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