View Javadoc
1   package org.apache.maven.wagon.tck.http;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.wagon.ConnectionException;
23  import org.apache.maven.wagon.ResourceDoesNotExistException;
24  import org.apache.maven.wagon.StreamWagon;
25  import org.apache.maven.wagon.TransferFailedException;
26  import org.apache.maven.wagon.authentication.AuthenticationException;
27  import org.apache.maven.wagon.authentication.AuthenticationInfo;
28  import org.apache.maven.wagon.authorization.AuthorizationException;
29  import org.apache.maven.wagon.proxy.ProxyInfo;
30  import org.apache.maven.wagon.tck.http.fixture.ErrorCodeServlet;
31  import org.apache.maven.wagon.tck.http.fixture.LatencyServlet;
32  import org.apache.maven.wagon.tck.http.fixture.ProxyConnectionVerifierFilter;
33  import org.apache.maven.wagon.tck.http.fixture.RedirectionServlet;
34  import org.apache.maven.wagon.tck.http.fixture.ServerFixture;
35  import org.apache.maven.wagon.tck.http.fixture.ServletExceptionServlet;
36  import org.apache.maven.wagon.tck.http.util.ValueHolder;
37  import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
38  import org.junit.Ignore;
39  import org.junit.Test;
40  
41  import javax.servlet.Servlet;
42  import javax.servlet.http.HttpServletResponse;
43  import java.io.File;
44  import java.io.IOException;
45  
46  import static junit.framework.Assert.assertTrue;
47  import static junit.framework.Assert.fail;
48  import static org.apache.maven.wagon.tck.http.Assertions.NO_RESPONSE_STATUS_CODE;
49  import static org.apache.maven.wagon.tck.http.Assertions.assertFileContentsFromResource;
50  import static org.apache.maven.wagon.tck.http.Assertions.assertWagonExceptionMessage;
51  
52  /**
53   * 
54   */
55  public class GetWagonTests
56      extends HttpWagonTests
57  {
58      private static final int TWO_SECONDS = 2000;
59      private static final int ONE_MINUTE = 60000;
60  
61      @Test
62      public void basic()
63          throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
64          TransferFailedException, ResourceDoesNotExistException, AuthorizationException
65      {
66          testSuccessfulGet( "base.txt" );
67      }
68  
69      @Test
70      @Ignore( "FIX ME!" )
71      public void proxied()
72          throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
73          TransferFailedException, ResourceDoesNotExistException, AuthorizationException
74      {
75          getServerFixture().addFilter( "*", new ProxyConnectionVerifierFilter() );
76  
77          ProxyInfo info = newProxyInfo();
78          if ( !initTest( null, info ) )
79          {
80              return;
81          }
82  
83          File target = newTempFile();
84          getWagon().get( "base.txt", target );
85  
86          assertFileContentsFromResource( ServerFixture.SERVER_ROOT_RESOURCE_PATH, "base.txt", target,
87                                          "Downloaded file doesn't match original." );
88      }
89  
90      @Test
91      public void highLatencyHighTimeout()
92          throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
93          TransferFailedException, ResourceDoesNotExistException, AuthorizationException
94      {
95          getServerFixture().addServlet( "/slow/*", new LatencyServlet( TWO_SECONDS ) );
96          testSuccessfulGet( "slow/large.txt", "large.txt" );
97      }
98  
99      @Test
100     public void highLatencyLowTimeout()
101         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
102         TransferFailedException, ResourceDoesNotExistException, AuthorizationException
103     {
104         Servlet servlet = new LatencyServlet( TWO_SECONDS );
105         getServerFixture().addServlet( "/slow/*", servlet );
106         testSuccessfulGet( "slow/large.txt", "large.txt" );
107     }
108 
109     @Test
110     public void inifiniteLatencyTimeout()
111         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
112         TransferFailedException, ResourceDoesNotExistException, AuthorizationException
113     {
114         if ( !isSupported() )
115         {
116             return;
117         }
118 
119         final ValueHolder<TransferFailedException> holder = new ValueHolder<>( null );
120 
121         Runnable r = new Runnable()
122         {
123             public void run()
124             {
125                 Servlet servlet = new LatencyServlet( -1 );
126                 addNotificationTarget( servlet );
127 
128                 getServerFixture().addServlet( "/infinite/*", servlet );
129                 try
130                 {
131                     if ( !initTest( null, null ) )
132                     {
133                         return;
134                     }
135 
136                     if ( getWagon() instanceof StreamWagon )
137                     {
138                         logger.info( "Connection timeout is: " + getWagon().getTimeout() );
139                     }
140 
141                     File target = newTempFile();
142                     getWagon().get( "infinite/", target );
143 
144                     fail( "Should have failed to transfer due to transaction timeout." );
145                 }
146                 catch ( ConnectionException | AuthenticationException | ResourceDoesNotExistException
147                         | AuthorizationException | ComponentConfigurationException | IOException e )
148                 {
149                     throw new IllegalStateException( e );
150                 }
151                 catch ( TransferFailedException e )
152                 {
153                     // expected
154                     holder.setValue( e );
155                 }
156             }
157         };
158 
159         Thread t = new Thread( r );
160         t.start();
161 
162         try
163         {
164             logger.info( "Waiting 60 seconds for wagon timeout." );
165             t.join( ONE_MINUTE );
166         }
167         catch ( InterruptedException e )
168         {
169             e.printStackTrace();
170         }
171 
172         logger.info( "Interrupting thread." );
173         t.interrupt();
174 
175         assertTrue( "TransferFailedException should have been thrown.", holder.getValue() != null );
176         assertWagonExceptionMessage( holder.getValue(), NO_RESPONSE_STATUS_CODE, getBaseUrl() + "infinite/",
177                 "", null );
178     }
179 
180     @Test
181     public void nonExistentHost()
182         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
183         ResourceDoesNotExistException, AuthorizationException
184     {
185         // we use a invalid localhost URL since some Internet Service Providers lately
186         // use funny 'search-DNS' which don't handle explicitly marked testing DNS properly.
187         // According to RFC-2606 .test, .invalid TLDs etc should work, but in practice it doesn't :(
188         if ( !initTest( "http://localhost:65520", null, null ) )
189         {
190             return;
191         }
192 
193         File target = newTempFile();
194         try
195         {
196             getWagon().get( "base.txt", target );
197             fail( "Expected error related to host lookup failure." );
198         }
199         catch ( TransferFailedException e )
200         {
201             // expected
202             assertWagonExceptionMessage( e, NO_RESPONSE_STATUS_CODE,  "http://localhost:65520/base.txt",
203                     null, null );
204         }
205     }
206 
207     @Test
208     public void oneLevelPermanentMove()
209         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
210         TransferFailedException, ResourceDoesNotExistException, AuthorizationException
211     {
212         getServerFixture().addServlet( "/moved.txt",
213                                        new RedirectionServlet( HttpServletResponse.SC_MOVED_PERMANENTLY,
214                                                                "/base.txt" ) );
215 
216         testSuccessfulGet( "moved.txt" );
217     }
218 
219     @Test
220     public void oneLevelTemporaryMove()
221         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
222         TransferFailedException, ResourceDoesNotExistException, AuthorizationException
223     {
224         getServerFixture().addServlet( "/moved.txt",
225                                        new RedirectionServlet( HttpServletResponse.SC_MOVED_TEMPORARILY,
226                                                                "/base.txt" ) );
227 
228         testSuccessfulGet( "moved.txt" );
229     }
230 
231     @Test
232     public void sixLevelPermanentMove()
233         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
234         TransferFailedException, ResourceDoesNotExistException, AuthorizationException
235     {
236         String myPath = "moved.txt";
237         String targetPath = "/base.txt";
238 
239         getServerFixture().addServlet( "/" + myPath + "/*",
240                                        new RedirectionServlet( HttpServletResponse.SC_MOVED_PERMANENTLY, myPath,
241                                                                targetPath, 6 ) );
242 
243         testSuccessfulGet( myPath );
244     }
245 
246     @Test
247     public void sixLevelTemporaryMove()
248         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
249         TransferFailedException, ResourceDoesNotExistException, AuthorizationException
250     {
251         String myPath = "moved.txt";
252         String targetPath = "/base.txt";
253 
254         getServerFixture().addServlet( "/" + myPath + "/*",
255                                        new RedirectionServlet( HttpServletResponse.SC_MOVED_TEMPORARILY, myPath,
256                                                                targetPath, 6 ) );
257 
258         testSuccessfulGet( myPath );
259     }
260 
261     @Test
262     public void infinitePermanentMove()
263         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
264         TransferFailedException, ResourceDoesNotExistException, AuthorizationException
265     {
266         String myPath = "moved.txt";
267         String targetPath = "/base.txt";
268 
269         getServerFixture().addServlet(
270                                        "/" + myPath,
271                                        new RedirectionServlet( HttpServletResponse.SC_MOVED_PERMANENTLY, myPath,
272                                                                targetPath, -1 ) );
273 
274         try
275         {
276             testSuccessfulGet( myPath );
277             fail( "Expected failure as a result of too many redirects." );
278         }
279         catch ( TransferFailedException e )
280         {
281             // expected
282         }
283     }
284 
285     @Test
286     public void infiniteTemporaryMove()
287         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
288         ResourceDoesNotExistException, AuthorizationException
289     {
290         String myPath = "moved.txt";
291         String targetPath = "/base.txt";
292 
293         getServerFixture().addServlet(
294                                        "/" + myPath,
295                                        new RedirectionServlet( HttpServletResponse.SC_MOVED_TEMPORARILY, myPath,
296                                                                targetPath, -1 ) );
297 
298         try
299         {
300             testSuccessfulGet( myPath );
301             fail( "Expected failure as a result of too many redirects." );
302         }
303         catch ( TransferFailedException e )
304         {
305             // expected
306         }
307     }
308 
309     /**
310      * NOTE: This test depends on a {@link WagonTestCaseConfigurator} configuration to limit redirects to 20. In the
311      * case of the Sun HTTP implementation, this is the default limit.
312      */
313     @Test
314     @SuppressWarnings( "checkstyle:methodname" )
315     public void permanentMove_TooManyRedirects_limit20()
316         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
317         TransferFailedException, ResourceDoesNotExistException, AuthorizationException
318     {
319         String myPath = "moved.txt";
320         String targetPath = "/base.txt";
321 
322         getServerFixture().addServlet(
323                                        "/" + myPath,
324                                        new RedirectionServlet( HttpServletResponse.SC_MOVED_PERMANENTLY, myPath,
325                                                                targetPath, -1 ) );
326 
327         try
328         {
329             testSuccessfulGet( myPath );
330             fail( "Expected failure as a result of too many redirects." );
331         }
332         catch ( TransferFailedException e )
333         {
334             // expected
335         }
336     }
337 
338     /**
339      * NOTE: This test depends on a {@link WagonTestCaseConfigurator} configuration to limit redirects to 20. In the
340      * case of the Sun HTTP implementation, this is the default limit.
341      */
342     @Test
343     @SuppressWarnings( "checkstyle:methodname" )
344     public void temporaryMove_TooManyRedirects_limit20()
345         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
346         ResourceDoesNotExistException, AuthorizationException
347     {
348         String myPath = "moved.txt";
349         String targetPath = "/base.txt";
350 
351         getServerFixture().addServlet(
352                                        "/" + myPath,
353                                        new RedirectionServlet( HttpServletResponse.SC_MOVED_TEMPORARILY, myPath,
354                                                                targetPath, -1 ) );
355 
356         try
357         {
358             testSuccessfulGet( myPath );
359             fail( "Expected failure as a result of too many redirects." );
360         }
361         catch ( TransferFailedException e )
362         {
363             // expected
364         }
365     }
366 
367     @Test
368     public void missing()
369         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
370         TransferFailedException, AuthorizationException
371     {
372         if ( !initTest( null, null ) )
373         {
374             return;
375         }
376 
377         File target = newTempFile();
378         try
379         {
380             getWagon().get( "404.txt", target );
381             fail( "should have received a 404, meaning the resource doesn't exist." );
382         }
383         catch ( ResourceDoesNotExistException e )
384         {
385             // expected
386         }
387     }
388 
389     @Test
390     public void error()
391         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
392         AuthorizationException, ResourceDoesNotExistException
393     {
394         testErrorHandling( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
395     }
396 
397     @Test
398     public void proxyTimeout()
399         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
400         AuthorizationException, ResourceDoesNotExistException
401     {
402         testErrorHandling( HttpServletResponse.SC_GATEWAY_TIMEOUT );
403     }
404 
405     @Test
406     public void forbidden()
407         throws ConnectionException, ComponentConfigurationException, IOException, ResourceDoesNotExistException,
408         TransferFailedException
409     {
410         AuthenticationInfo info = new AuthenticationInfo();
411         info.setUserName( "user" );
412         info.setPassword( "password" );
413 
414         getServerFixture().addUser( info.getUserName(), "password" );
415 
416         getServerFixture().addServlet( "/403.txt",
417                                        new ErrorCodeServlet( HttpServletResponse.SC_FORBIDDEN, "Expected 403" ) );
418 
419         testAuthFailure( "403.txt", info );
420     }
421 
422     @Test
423     public void successfulAuthentication()
424         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
425         TransferFailedException, ResourceDoesNotExistException, AuthorizationException
426     {
427         AuthenticationInfo info = new AuthenticationInfo();
428         info.setUserName( "user" );
429         info.setPassword( "password" );
430 
431         getServerFixture().addUser( info.getUserName(), info.getPassword() );
432 
433         if ( !initTest( info, null ) )
434         {
435             return;
436         }
437 
438         File target = newTempFile();
439         getWagon().get( "protected/base.txt", target );
440 
441         assertFileContentsFromResource( ServerFixture.SERVER_ROOT_RESOURCE_PATH, "base.txt", target,
442                                         "Downloaded file doesn't match original." );
443     }
444 
445     @Test
446     public void unsuccessfulAuthentication()
447         throws ConnectionException, ComponentConfigurationException, IOException, TransferFailedException,
448         ResourceDoesNotExistException
449     {
450         AuthenticationInfo info = new AuthenticationInfo();
451         info.setUserName( "user" );
452         info.setPassword( "password" );
453 
454         getServerFixture().addUser( info.getUserName(), "anotherPassword" );
455 
456         testAuthFailure( "protected/base.txt", info );
457     }
458 
459     protected void testAuthFailure( final String path, final AuthenticationInfo info )
460         throws ConnectionException, ComponentConfigurationException, IOException, TransferFailedException,
461         ResourceDoesNotExistException
462     {
463         boolean authFailure = false;
464         try
465         {
466             if ( !initTest( info, null ) )
467             {
468                 return;
469             }
470         }
471         catch ( AuthenticationException e )
472         {
473             // expected
474             authFailure = true;
475         }
476 
477         File target = newTempFile();
478         try
479         {
480             getWagon().get( path, target );
481         }
482         catch ( AuthorizationException e )
483         {
484             // expected
485             authFailure = true;
486         }
487 
488         assertTrue( "Authentication/Authorization should have failed.", authFailure );
489     }
490 
491     protected void testSuccessfulGet( final String path )
492         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
493         TransferFailedException, ResourceDoesNotExistException, AuthorizationException
494     {
495         testSuccessfulGet( path, "base.txt" );
496     }
497 
498     protected void testSuccessfulGet( final String path, final String checkPath )
499         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
500         TransferFailedException, ResourceDoesNotExistException, AuthorizationException
501     {
502         if ( !initTest( null, null ) )
503         {
504             return;
505         }
506 
507         if ( getWagon() instanceof StreamWagon )
508         {
509             logger.info( "Connection timeout is: " + getWagon().getTimeout() );
510         }
511 
512         File target = newTempFile();
513         getWagon().get( path, target );
514 
515         assertFileContentsFromResource( ServerFixture.SERVER_ROOT_RESOURCE_PATH, checkPath, target,
516                                         "Downloaded file doesn't match original." );
517     }
518 
519     protected void testErrorHandling( final int code )
520         throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException,
521         AuthorizationException, ResourceDoesNotExistException
522     {
523         if ( code == HttpServletResponse.SC_INTERNAL_SERVER_ERROR )
524         {
525             getServerFixture().addServlet( "/" + code + ".txt", new ServletExceptionServlet( "Expected " + code ) );
526         }
527         else
528         {
529             getServerFixture().addServlet( "/" + code + ".txt", new ErrorCodeServlet( code, "Expected " + code ) );
530         }
531 
532         if ( !initTest( null, null ) )
533         {
534             return;
535         }
536 
537         File target = newTempFile();
538         try
539         {
540             getWagon().get( code + ".txt", target );
541             fail( "should have received a " + code + " error code, meaning the resource doesn't exist." );
542         }
543         catch ( TransferFailedException e )
544         {
545             // expected
546         }
547     }
548 }