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