View Javadoc
1   package org.eclipse.aether.transport.wagon;
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 static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertTrue;
24  import static org.junit.Assert.fail;
25  
26  import java.io.File;
27  import java.net.URI;
28  import java.nio.charset.StandardCharsets;
29  import java.util.Map;
30  import java.util.UUID;
31  
32  import org.apache.maven.wagon.ResourceDoesNotExistException;
33  import org.apache.maven.wagon.TransferFailedException;
34  import org.apache.maven.wagon.Wagon;
35  import org.eclipse.aether.ConfigurationProperties;
36  import org.eclipse.aether.DefaultRepositorySystemSession;
37  import org.eclipse.aether.internal.test.util.TestFileUtils;
38  import org.eclipse.aether.internal.test.util.TestUtils;
39  import org.eclipse.aether.repository.Authentication;
40  import org.eclipse.aether.repository.Proxy;
41  import org.eclipse.aether.repository.RemoteRepository;
42  import org.eclipse.aether.spi.connector.transport.GetTask;
43  import org.eclipse.aether.spi.connector.transport.PeekTask;
44  import org.eclipse.aether.spi.connector.transport.PutTask;
45  import org.eclipse.aether.spi.connector.transport.Transporter;
46  import org.eclipse.aether.spi.connector.transport.TransporterFactory;
47  import org.eclipse.aether.transfer.NoTransporterException;
48  import org.eclipse.aether.transfer.TransferCancelledException;
49  import org.eclipse.aether.util.repository.AuthenticationBuilder;
50  import org.junit.After;
51  import org.junit.Before;
52  import org.junit.Test;
53  
54  /**
55   */
56  public abstract class AbstractWagonTransporterTest
57  {
58  
59      private DefaultRepositorySystemSession session;
60  
61      private TransporterFactory factory;
62  
63      private Transporter transporter;
64  
65      private String id;
66  
67      private Map<String, String> fs;
68  
69      protected abstract Wagon newWagon();
70  
71      private RemoteRepository newRepo( String url )
72      {
73          return new RemoteRepository.Builder( "test", "default", url ).build();
74      }
75  
76      private void newTransporter( String url )
77          throws Exception
78      {
79          newTransporter( newRepo( url ) );
80      }
81  
82      private void newTransporter( RemoteRepository repo )
83          throws Exception
84      {
85          if ( transporter != null )
86          {
87              transporter.close();
88              transporter = null;
89          }
90          transporter = factory.newInstance( session, repo );
91      }
92  
93      @Before
94      public void setUp()
95          throws Exception
96      {
97          session = TestUtils.newSession();
98          factory = new WagonTransporterFactory( new WagonProvider()
99          {
100             public Wagon lookup( String roleHint )
101             {
102                 if ( "mem".equalsIgnoreCase( roleHint ) )
103                 {
104                     return newWagon();
105                 }
106                 throw new IllegalArgumentException( "unknown wagon role: " + roleHint );
107             }
108 
109             public void release( Wagon wagon )
110             {
111             }
112         }, new WagonConfigurator()
113         {
114             public void configure( Wagon wagon, Object configuration )
115             {
116                 ( (Configurable) wagon ).setConfiguration( configuration );
117             }
118         } );
119         id = UUID.randomUUID().toString().replace( "-", "" );
120         fs = MemWagonUtils.getFilesystem( id );
121         fs.put( "file.txt", "test" );
122         fs.put( "empty.txt", "" );
123         fs.put( "some space.txt", "space" );
124         newTransporter( "mem://" + id );
125     }
126 
127     @After
128     public void tearDown()
129     {
130         if ( transporter != null )
131         {
132             transporter.close();
133             transporter = null;
134         }
135         factory = null;
136         session = null;
137     }
138 
139     @Test
140     public void testClassify()
141     {
142         assertEquals( Transporter.ERROR_OTHER, transporter.classify( new TransferFailedException( "test" ) ) );
143         assertEquals( Transporter.ERROR_NOT_FOUND, transporter.classify( new ResourceDoesNotExistException( "test" ) ) );
144     }
145 
146     @Test
147     public void testPeek()
148         throws Exception
149     {
150         transporter.peek( new PeekTask( URI.create( "file.txt" ) ) );
151     }
152 
153     @Test
154     public void testPeek_NotFound()
155         throws Exception
156     {
157         try
158         {
159             transporter.peek( new PeekTask( URI.create( "missing.txt" ) ) );
160             fail( "Expected error" );
161         }
162         catch ( ResourceDoesNotExistException e )
163         {
164             assertEquals( Transporter.ERROR_NOT_FOUND, transporter.classify( e ) );
165         }
166     }
167 
168     @Test
169     public void testPeek_Closed()
170         throws Exception
171     {
172         transporter.close();
173         try
174         {
175             transporter.peek( new PeekTask( URI.create( "missing.txt" ) ) );
176             fail( "Expected error" );
177         }
178         catch ( IllegalStateException e )
179         {
180             assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) );
181         }
182     }
183 
184     @Test
185     public void testGet_ToMemory()
186         throws Exception
187     {
188         RecordingTransportListener listener = new RecordingTransportListener();
189         GetTask task = new GetTask( URI.create( "file.txt" ) ).setListener( listener );
190         transporter.get( task );
191         assertEquals( "test", task.getDataString() );
192         assertEquals( 0L, listener.dataOffset );
193         assertEquals( 4L, listener.dataLength );
194         assertEquals( 1, listener.startedCount );
195         assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 );
196         assertEquals( task.getDataString(), new String( listener.baos.toByteArray(), StandardCharsets.UTF_8 ) );
197     }
198 
199     @Test
200     public void testGet_ToFile()
201         throws Exception
202     {
203         File file = TestFileUtils.createTempFile( "failure" );
204         RecordingTransportListener listener = new RecordingTransportListener();
205         GetTask task = new GetTask( URI.create( "file.txt" ) ).setDataFile( file ).setListener( listener );
206         transporter.get( task );
207         assertEquals( "test", TestFileUtils.readString( file ) );
208         assertEquals( 0L, listener.dataOffset );
209         assertEquals( 4L, listener.dataLength );
210         assertEquals( 1, listener.startedCount );
211         assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 );
212         assertEquals( "test", new String( listener.baos.toByteArray(), StandardCharsets.UTF_8 ) );
213     }
214 
215     @Test
216     public void testGet_EmptyResource()
217         throws Exception
218     {
219         File file = TestFileUtils.createTempFile( "failure" );
220         assertTrue( file.delete() && !file.exists() );
221         RecordingTransportListener listener = new RecordingTransportListener();
222         GetTask task = new GetTask( URI.create( "empty.txt" ) ).setDataFile( file ).setListener( listener );
223         transporter.get( task );
224         assertEquals( "", TestFileUtils.readString( file ) );
225         assertEquals( 0L, listener.dataOffset );
226         assertEquals( 0L, listener.dataLength );
227         assertEquals( 1, listener.startedCount );
228         assertEquals( 0, listener.progressedCount );
229         assertEquals( "", new String( listener.baos.toByteArray(), StandardCharsets.UTF_8 ) );
230     }
231 
232     @Test
233     public void testGet_EncodedResourcePath()
234         throws Exception
235     {
236         GetTask task = new GetTask( URI.create( "some%20space.txt" ) );
237         transporter.get( task );
238         assertEquals( "space", task.getDataString() );
239     }
240 
241     @Test
242     public void testGet_FileHandleLeak()
243         throws Exception
244     {
245         for ( int i = 0; i < 100; i++ )
246         {
247             File file = TestFileUtils.createTempFile( "failure" );
248             transporter.get( new GetTask( URI.create( "file.txt" ) ).setDataFile( file ) );
249             assertTrue( i + ", " + file.getAbsolutePath(), file.delete() );
250         }
251     }
252 
253     @Test
254     public void testGet_NotFound()
255         throws Exception
256     {
257         try
258         {
259             transporter.get( new GetTask( URI.create( "missing.txt" ) ) );
260             fail( "Expected error" );
261         }
262         catch ( ResourceDoesNotExistException e )
263         {
264             assertEquals( Transporter.ERROR_NOT_FOUND, transporter.classify( e ) );
265         }
266     }
267 
268     @Test
269     public void testGet_Closed()
270         throws Exception
271     {
272         transporter.close();
273         try
274         {
275             transporter.get( new GetTask( URI.create( "file.txt" ) ) );
276             fail( "Expected error" );
277         }
278         catch ( IllegalStateException e )
279         {
280             assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) );
281         }
282     }
283 
284     @Test
285     public void testGet_StartCancelled()
286         throws Exception
287     {
288         RecordingTransportListener listener = new RecordingTransportListener();
289         listener.cancelStart = true;
290         GetTask task = new GetTask( URI.create( "file.txt" ) ).setListener( listener );
291         transporter.get( task );
292         assertEquals( 1, listener.startedCount );
293     }
294 
295     @Test
296     public void testGet_ProgressCancelled()
297         throws Exception
298     {
299         RecordingTransportListener listener = new RecordingTransportListener();
300         listener.cancelProgress = true;
301         GetTask task = new GetTask( URI.create( "file.txt" ) ).setListener( listener );
302         try
303         {
304             transporter.get( task );
305             fail( "Expected error" );
306         }
307         catch ( TransferCancelledException e )
308         {
309             assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) );
310         }
311         assertEquals( 0L, listener.dataOffset );
312         assertEquals( 4L, listener.dataLength );
313         assertEquals( 1, listener.startedCount );
314         assertEquals( 1, listener.progressedCount );
315     }
316 
317     @Test
318     public void testPut_FromMemory()
319         throws Exception
320     {
321         RecordingTransportListener listener = new RecordingTransportListener();
322         PutTask task = new PutTask( URI.create( "file.txt" ) ).setListener( listener ).setDataString( "upload" );
323         transporter.put( task );
324         assertEquals( 0L, listener.dataOffset );
325         assertEquals( 6L, listener.dataLength );
326         assertEquals( 1, listener.startedCount );
327         assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 );
328         assertEquals( "upload", fs.get( "file.txt" ) );
329     }
330 
331     @Test
332     public void testPut_FromFile()
333         throws Exception
334     {
335         File file = TestFileUtils.createTempFile( "upload" );
336         RecordingTransportListener listener = new RecordingTransportListener();
337         PutTask task = new PutTask( URI.create( "file.txt" ) ).setListener( listener ).setDataFile( file );
338         transporter.put( task );
339         assertEquals( 0L, listener.dataOffset );
340         assertEquals( 6L, listener.dataLength );
341         assertEquals( 1, listener.startedCount );
342         assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 );
343         assertEquals( "upload", fs.get( "file.txt" ) );
344     }
345 
346     @Test
347     public void testPut_EmptyResource()
348         throws Exception
349     {
350         RecordingTransportListener listener = new RecordingTransportListener();
351         PutTask task = new PutTask( URI.create( "file.txt" ) ).setListener( listener );
352         transporter.put( task );
353         assertEquals( 0L, listener.dataOffset );
354         assertEquals( 0L, listener.dataLength );
355         assertEquals( 1, listener.startedCount );
356         assertEquals( 0, listener.progressedCount );
357         assertEquals( "", fs.get( "file.txt" ) );
358     }
359 
360     @Test
361     public void testPut_NonExistentParentDir()
362         throws Exception
363     {
364         RecordingTransportListener listener = new RecordingTransportListener();
365         PutTask task =
366             new PutTask( URI.create( "dir/sub/dir/file.txt" ) ).setListener( listener ).setDataString( "upload" );
367         transporter.put( task );
368         assertEquals( 0L, listener.dataOffset );
369         assertEquals( 6L, listener.dataLength );
370         assertEquals( 1, listener.startedCount );
371         assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 );
372         assertEquals( "upload", fs.get( "dir/sub/dir/file.txt" ) );
373     }
374 
375     @Test
376     public void testPut_EncodedResourcePath()
377         throws Exception
378     {
379         RecordingTransportListener listener = new RecordingTransportListener();
380         PutTask task = new PutTask( URI.create( "some%20space.txt" ) ).setListener( listener ).setDataString( "OK" );
381         transporter.put( task );
382         assertEquals( 0L, listener.dataOffset );
383         assertEquals( 2L, listener.dataLength );
384         assertEquals( 1, listener.startedCount );
385         assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 );
386         assertEquals( "OK", fs.get( "some space.txt" ) );
387     }
388 
389     @Test
390     public void testPut_FileHandleLeak()
391         throws Exception
392     {
393         for ( int i = 0; i < 100; i++ )
394         {
395             File src = TestFileUtils.createTempFile( "upload" );
396             transporter.put( new PutTask( URI.create( "file.txt" ) ).setDataFile( src ) );
397             assertTrue( i + ", " + src.getAbsolutePath(), src.delete() );
398         }
399     }
400 
401     @Test
402     public void testPut_Closed()
403         throws Exception
404     {
405         transporter.close();
406         try
407         {
408             transporter.put( new PutTask( URI.create( "missing.txt" ) ) );
409             fail( "Expected error" );
410         }
411         catch ( IllegalStateException e )
412         {
413             assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) );
414         }
415     }
416 
417     @Test
418     public void testPut_StartCancelled()
419         throws Exception
420     {
421         RecordingTransportListener listener = new RecordingTransportListener();
422         listener.cancelStart = true;
423         PutTask task = new PutTask( URI.create( "file.txt" ) ).setListener( listener ).setDataString( "upload" );
424         transporter.put( task );
425         assertEquals( 1, listener.startedCount );
426     }
427 
428     @Test
429     public void testPut_ProgressCancelled()
430         throws Exception
431     {
432         RecordingTransportListener listener = new RecordingTransportListener();
433         listener.cancelProgress = true;
434         PutTask task = new PutTask( URI.create( "file.txt" ) ).setListener( listener ).setDataString( "upload" );
435         try
436         {
437             transporter.put( task );
438             fail( "Expected error" );
439         }
440         catch ( TransferCancelledException e )
441         {
442             assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) );
443         }
444         assertEquals( 0L, listener.dataOffset );
445         assertEquals( 6L, listener.dataLength );
446         assertEquals( 1, listener.startedCount );
447         assertEquals( 1, listener.progressedCount );
448     }
449 
450     @Test( expected = NoTransporterException.class )
451     public void testInit_BadProtocol()
452         throws Exception
453     {
454         newTransporter( "bad:/void" );
455     }
456 
457     @Test
458     public void testInit_CaseInsensitiveProtocol()
459         throws Exception
460     {
461         newTransporter( "mem:/void" );
462         newTransporter( "MEM:/void" );
463         newTransporter( "mEm:/void" );
464     }
465 
466     @Test
467     public void testInit_Configuration()
468         throws Exception
469     {
470         session.setConfigProperty( "aether.connector.wagon.config.test", "passed" );
471         newTransporter( "mem://" + id + "?config=passed" );
472         transporter.peek( new PeekTask( URI.create( "file.txt" ) ) );
473     }
474 
475     @Test
476     public void testInit_UserAgent()
477         throws Exception
478     {
479         session.setConfigProperty( ConfigurationProperties.USER_AGENT, "Test/1.0" );
480         newTransporter( "mem://" + id + "?userAgent=Test/1.0" );
481         transporter.peek( new PeekTask( URI.create( "file.txt" ) ) );
482     }
483 
484     @Test
485     public void testInit_Timeout()
486         throws Exception
487     {
488         session.setConfigProperty( ConfigurationProperties.REQUEST_TIMEOUT, "12345678" );
489         newTransporter( "mem://" + id + "?requestTimeout=12345678" );
490         transporter.peek( new PeekTask( URI.create( "file.txt" ) ) );
491     }
492 
493     @Test
494     public void testInit_ServerAuth()
495         throws Exception
496     {
497         String url =
498             "mem://" + id + "?serverUsername=testuser&serverPassword=testpass"
499                 + "&serverPrivateKey=testkey&serverPassphrase=testphrase";
500         Authentication auth =
501             new AuthenticationBuilder().addUsername( "testuser" ).addPassword( "testpass" ).addPrivateKey( "testkey",
502                                                                                                            "testphrase" ).build();
503         RemoteRepository repo =
504             new RemoteRepository.Builder( "test", "default", url ).setAuthentication( auth ).build();
505         newTransporter( repo );
506         transporter.peek( new PeekTask( URI.create( "file.txt" ) ) );
507     }
508 
509     @Test
510     public void testInit_Proxy()
511         throws Exception
512     {
513         String url = "mem://" + id + "?proxyHost=testhost&proxyPort=8888";
514         RemoteRepository repo =
515             new RemoteRepository.Builder( "test", "default", url ).setProxy( new Proxy( "http", "testhost", 8888 ) ).build();
516         newTransporter( repo );
517         transporter.peek( new PeekTask( URI.create( "file.txt" ) ) );
518     }
519 
520     @Test
521     public void testInit_ProxyAuth()
522         throws Exception
523     {
524         String url = "mem://" + id + "?proxyUsername=testuser&proxyPassword=testpass";
525         Authentication auth = new AuthenticationBuilder().addUsername( "testuser" ).addPassword( "testpass" ).build();
526         RemoteRepository repo =
527             new RemoteRepository.Builder( "test", "default", url ).setProxy( new Proxy( "http", "testhost", 8888, auth ) ).build();
528         newTransporter( repo );
529         transporter.peek( new PeekTask( URI.create( "file.txt" ) ) );
530     }
531 
532 }