1   package org.apache.maven.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 java.io.ByteArrayOutputStream;
23  import java.io.File;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.OutputStream;
27  
28  import junit.framework.TestCase;
29  
30  import org.apache.maven.wagon.authentication.AuthenticationException;
31  import org.apache.maven.wagon.authentication.AuthenticationInfo;
32  import org.apache.maven.wagon.authorization.AuthorizationException;
33  import org.apache.maven.wagon.events.SessionListener;
34  import org.apache.maven.wagon.events.TransferEvent;
35  import org.apache.maven.wagon.events.TransferListener;
36  import org.apache.maven.wagon.proxy.ProxyInfo;
37  import org.apache.maven.wagon.proxy.ProxyInfoProvider;
38  import org.apache.maven.wagon.repository.Repository;
39  import org.apache.maven.wagon.repository.RepositoryPermissions;
40  import org.apache.maven.wagon.resource.Resource;
41  import org.codehaus.plexus.util.FileUtils;
42  import org.codehaus.plexus.util.IOUtil;
43  import org.easymock.AbstractMatcher;
44  import org.easymock.MockControl;
45  
46  /**
47   * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
48   * @version $Id: AbstractWagonTest.java 630808 2008-02-25 11:01:41Z brett $
49   */
50  public class AbstractWagonTest
51      extends TestCase
52  {
53      private static class TestWagon
54          extends AbstractWagon
55      {
56          protected void closeConnection()
57              throws ConnectionException
58          {
59          }
60  
61          protected void openConnectionInternal()
62              throws ConnectionException, AuthenticationException
63          {
64          }
65  
66          public void get( String resourceName, File destination )
67              throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
68          {
69          }
70  
71          public boolean getIfNewer( String resourceName, File destination, long timestamp )
72              throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
73          {
74              return false;
75          }
76  
77          public void put( File source, String destination )
78              throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
79          {
80          }
81      };
82  
83      private String basedir;
84  
85      private WagonMock wagon = null;
86  
87      private File destination;
88  
89      private File source;
90  
91      private String artifact;
92  
93      private SessionListener sessionListener = null;
94  
95      private TransferListener transferListener = null;
96  
97      private MockControl transferListenerControl;
98  
99      private MockControl sessionListenerControl;
100 
101     protected void setUp()
102         throws Exception
103     {
104         super.setUp();
105 
106         basedir = System.getProperty( "basedir" );
107 
108         destination = new File( basedir, "target/folder/subfolder" );
109 
110         source = new File( basedir, "pom.xml" );
111 
112         wagon = new WagonMock();
113 
114         sessionListenerControl = MockControl.createControl( SessionListener.class );
115         sessionListener = (SessionListener) sessionListenerControl.getMock();
116 
117         wagon.addSessionListener( sessionListener );
118 
119         transferListenerControl = MockControl.createControl( TransferListener.class );
120         transferListener = (TransferListener) transferListenerControl.getMock();
121 
122         wagon.addTransferListener( transferListener );
123 
124     }
125 
126     public void testSessionListenerRegistration()
127     {
128         assertTrue( wagon.hasSessionListener( sessionListener ) );
129 
130         wagon.removeSessionListener( sessionListener );
131 
132         assertFalse( wagon.hasSessionListener( sessionListener ) );
133     }
134 
135     public void testTransferListenerRegistration()
136     {
137         assertTrue( wagon.hasTransferListener( transferListener ) );
138 
139         wagon.removeTransferListener( transferListener );
140 
141         assertFalse( wagon.hasTransferListener( transferListener ) );
142     }
143 
144     public void testNoProxyConfiguration()
145         throws ConnectionException, AuthenticationException
146     {
147         Repository repository = new Repository();
148         wagon.connect( repository );
149         assertNull( wagon.getProxyInfo() );
150         assertNull( wagon.getProxyInfo( "http", "www.example.com" ) );
151         assertNull( wagon.getProxyInfo( "dav", "www.example.com" ) );
152         assertNull( wagon.getProxyInfo( "scp", "www.example.com" ) );
153         assertNull( wagon.getProxyInfo( "ftp", "www.example.com" ) );
154         assertNull( wagon.getProxyInfo( "http", "localhost" ) );
155     }
156 
157     public void testNullProxyConfiguration()
158         throws ConnectionException, AuthenticationException
159     {
160         Repository repository = new Repository();
161         wagon.connect( repository, (ProxyInfo) null );
162         assertNull( wagon.getProxyInfo() );
163         assertNull( wagon.getProxyInfo( "http", "www.example.com" ) );
164         assertNull( wagon.getProxyInfo( "dav", "www.example.com" ) );
165         assertNull( wagon.getProxyInfo( "scp", "www.example.com" ) );
166         assertNull( wagon.getProxyInfo( "ftp", "www.example.com" ) );
167         assertNull( wagon.getProxyInfo( "http", "localhost" ) );
168 
169         wagon.connect( repository );
170         assertNull( wagon.getProxyInfo() );
171         assertNull( wagon.getProxyInfo( "http", "www.example.com" ) );
172         assertNull( wagon.getProxyInfo( "dav", "www.example.com" ) );
173         assertNull( wagon.getProxyInfo( "scp", "www.example.com" ) );
174         assertNull( wagon.getProxyInfo( "ftp", "www.example.com" ) );
175         assertNull( wagon.getProxyInfo( "http", "localhost" ) );
176 
177         wagon.connect( repository, new AuthenticationInfo() );
178         assertNull( wagon.getProxyInfo() );
179         assertNull( wagon.getProxyInfo( "http", "www.example.com" ) );
180         assertNull( wagon.getProxyInfo( "dav", "www.example.com" ) );
181         assertNull( wagon.getProxyInfo( "scp", "www.example.com" ) );
182         assertNull( wagon.getProxyInfo( "ftp", "www.example.com" ) );
183         assertNull( wagon.getProxyInfo( "http", "localhost" ) );
184     }
185 
186     public void testLegacyProxyConfiguration()
187         throws ConnectionException, AuthenticationException
188     {
189         ProxyInfo proxyInfo = new ProxyInfo();
190         proxyInfo.setType( "http" );
191 
192         Repository repository = new Repository();
193         wagon.connect( repository, proxyInfo );
194         assertEquals( proxyInfo, wagon.getProxyInfo() );
195         assertEquals( proxyInfo, wagon.getProxyInfo( "http", "www.example.com" ) );
196         assertNull( wagon.getProxyInfo( "dav", "www.example.com" ) );
197         assertNull( wagon.getProxyInfo( "scp", "www.example.com" ) );
198         assertNull( wagon.getProxyInfo( "ftp", "www.example.com" ) );
199     }
200 
201     public void testProxyConfiguration()
202         throws ConnectionException, AuthenticationException
203     {
204         final ProxyInfo httpProxyInfo = new ProxyInfo();
205         httpProxyInfo.setType( "http" );
206 
207         final ProxyInfo socksProxyInfo = new ProxyInfo();
208         socksProxyInfo.setType( "http" );
209 
210         ProxyInfoProvider proxyInfoProvider = new ProxyInfoProvider()
211         {
212             public ProxyInfo getProxyInfo( String protocol )
213             {
214                 if ( "http".equals( protocol ) || "dav".equals( protocol ) )
215                 {
216                     return httpProxyInfo;
217                 }
218                 else if ( "scp".equals( protocol ) )
219                 {
220                     return socksProxyInfo;
221                 }
222                 return null;
223             }
224         };
225 
226         Repository repository = new Repository();
227         wagon.connect( repository, proxyInfoProvider );
228         assertNull( wagon.getProxyInfo() );
229         assertEquals( httpProxyInfo, wagon.getProxyInfo( "http", "www.example.com" ) );
230         assertEquals( httpProxyInfo, wagon.getProxyInfo( "dav", "www.example.com" ) );
231         assertEquals( socksProxyInfo, wagon.getProxyInfo( "scp", "www.example.com" ) );
232         assertNull( wagon.getProxyInfo( "ftp", "www.example.com" ) );
233     }
234 
235     public void testSessionOpenEvents()
236         throws Exception
237     {
238         Repository repository = new Repository();
239 
240         sessionListenerControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
241         sessionListener.sessionOpening( null );
242         sessionListener.sessionOpened( null );
243         sessionListenerControl.replay();
244 
245         wagon.connect( repository );
246 
247         sessionListenerControl.verify();
248 
249         assertEquals( repository, wagon.getRepository() );
250     }
251 
252     public void testSessionConnectionRefusedEventConnectionException()
253         throws Exception
254     {
255         final WagonException exception = new ConnectionException( "" );
256 
257         try
258         {
259             runTestSessionConnectionRefusedEvent( exception );
260             fail();
261         }
262         catch ( ConnectionException e )
263         {
264             assertTrue( true );
265         }
266     }
267 
268     public void testSessionConnectionRefusedEventAuthenticationException()
269         throws Exception
270     {
271         final WagonException exception = new AuthenticationException( "" );
272 
273         try
274         {
275             runTestSessionConnectionRefusedEvent( exception );
276             fail();
277         }
278         catch ( AuthenticationException e )
279         {
280             assertTrue( true );
281         }
282     }
283 
284     private void runTestSessionConnectionRefusedEvent( final WagonException exception )
285         throws ConnectionException, AuthenticationException
286     {
287         Repository repository = new Repository();
288 
289         sessionListenerControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
290         sessionListener.sessionOpening( null );
291         sessionListener.sessionConnectionRefused( null );
292         sessionListenerControl.replay();
293 
294         Wagon wagon = new TestWagon()
295         {
296             protected void openConnectionInternal()
297                 throws ConnectionException, AuthenticationException
298             {
299                 if ( exception instanceof ConnectionException )
300                 {
301                     throw (ConnectionException) exception;
302                 }
303                 if ( exception instanceof AuthenticationException )
304                 {
305                     throw (AuthenticationException) exception;
306                 }
307             }
308         };
309         wagon.addSessionListener( sessionListener );
310 
311         try
312         {
313             wagon.connect( repository );
314             fail();
315         }
316         finally
317         {
318             sessionListenerControl.verify();
319 
320             assertEquals( repository, wagon.getRepository() );
321         }
322     }
323 
324     public void testSessionCloseEvents()
325         throws Exception
326     {
327         sessionListenerControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
328         sessionListener.sessionDisconnecting( null );
329         sessionListener.sessionDisconnected( null );
330         sessionListenerControl.replay();
331 
332         wagon.disconnect();
333 
334         sessionListenerControl.verify();
335     }
336 
337     public void testSessionCloseRefusedEventConnectionException()
338         throws Exception
339     {
340         Repository repository = new Repository();
341 
342         sessionListenerControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
343         sessionListener.sessionDisconnecting( null );
344         sessionListener.sessionError( null );
345         sessionListenerControl.replay();
346 
347         Wagon wagon = new TestWagon()
348         {
349             protected void closeConnection()
350                 throws ConnectionException
351             {
352                 throw new ConnectionException( "" );
353             }
354         };
355         wagon.addSessionListener( sessionListener );
356 
357         try
358         {
359             wagon.disconnect();
360             fail();
361         }
362         catch ( ConnectionException e )
363         {
364             assertTrue( true );
365         }
366         finally
367         {
368             sessionListenerControl.verify();
369         }
370     }
371 
372     public void testGetTransferEvents()
373         throws Exception
374     {
375         transferListener.debug( "fetch debug message" );
376         transferListenerControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
377         transferListener.transferInitiated( null );
378         transferListener.transferStarted( null );
379         transferListener.debug( null );
380         transferListenerControl.setVoidCallable( MockControl.ZERO_OR_MORE );
381         transferListener.transferProgress( null, null, 0 );
382         transferListenerControl.setVoidCallable( 5 );
383         transferListener.transferCompleted( null );
384         transferListenerControl.replay();
385 
386         wagon.fireTransferDebug( "fetch debug message" );
387 
388         Repository repository = new Repository();
389         wagon.connect( repository );
390 
391         wagon.get( artifact, destination );
392 
393         transferListenerControl.verify();
394     }
395 
396     public void testGetError()
397         throws Exception
398     {
399         transferListenerControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
400         transferListener.transferInitiated( null );
401         transferListener.transferStarted( null );
402         transferListener.debug( null );
403         transferListenerControl.setVoidCallable( MockControl.ZERO_OR_MORE );
404         transferListener.transferError( null );
405         transferListenerControl.replay();
406 
407         try
408         {
409             Repository repository = new Repository();
410 
411             WagonMock wagon = new WagonMock( true );
412 
413             wagon.addTransferListener( transferListener );
414 
415             wagon.connect( repository );
416 
417             wagon.get( artifact, destination );
418 
419             fail( "Transfer error was expected during deploy" );
420         }
421         catch ( TransferFailedException expected )
422         {
423             assertTrue( true );
424         }
425 
426         transferListenerControl.verify();
427     }
428 
429     public void testPutTransferEvents()
430         throws ConnectionException, AuthenticationException, ResourceDoesNotExistException, TransferFailedException,
431         AuthorizationException
432     {
433         transferListener.debug( "deploy debug message" );
434         transferListenerControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
435         transferListener.transferInitiated( null );
436         transferListener.transferStarted( null );
437         transferListener.transferProgress( null, null, 0 );
438         transferListener.transferCompleted( null );
439         transferListenerControl.replay();
440 
441         wagon.fireTransferDebug( "deploy debug message" );
442 
443         Repository repository = new Repository();
444 
445         wagon.connect( repository );
446 
447         wagon.put( source, artifact );
448 
449         transferListenerControl.verify();
450     }
451 
452     public void testStreamShutdown()
453     {
454         IOUtil.close( (InputStream) null );
455 
456         IOUtil.close( (OutputStream) null );
457 
458         InputStreamMock inputStream = new InputStreamMock();
459 
460         assertFalse( inputStream.isClosed() );
461 
462         IOUtil.close( inputStream );
463 
464         assertTrue( inputStream.isClosed() );
465 
466         OutputStreamMock outputStream = new OutputStreamMock();
467 
468         assertFalse( outputStream.isClosed() );
469 
470         IOUtil.close( outputStream );
471 
472         assertTrue( outputStream.isClosed() );
473     }
474 
475     public void testRepositoryPermissionsOverride()
476         throws ConnectionException, AuthenticationException
477     {
478         Repository repository = new Repository();
479 
480         RepositoryPermissions original = new RepositoryPermissions();
481         original.setFileMode( "664" );
482         repository.setPermissions( original );
483 
484         RepositoryPermissions override = new RepositoryPermissions();
485         override.setFileMode( "644" );
486         wagon.setPermissionsOverride( override );
487 
488         wagon.connect( repository );
489 
490         assertEquals( override, repository.getPermissions() );
491         assertEquals( "644", repository.getPermissions().getFileMode() );
492     }
493 
494     public void testRepositoryUserName()
495         throws ConnectionException, AuthenticationException
496     {
497         Repository repository = new Repository( "id", "http://bporter:password@www.example.com/path/to/resource" );
498 
499         AuthenticationInfo authenticationInfo = new AuthenticationInfo();
500         authenticationInfo.setUserName( "brett" );
501         authenticationInfo.setPassword( "pass" );
502         wagon.connect( repository, authenticationInfo );
503 
504         assertEquals( authenticationInfo, wagon.getAuthenticationInfo() );
505         assertEquals( "brett", authenticationInfo.getUserName() );
506         assertEquals( "pass", authenticationInfo.getPassword() );
507     }
508 
509     public void testRepositoryUserNameNotGivenInCredentials()
510         throws ConnectionException, AuthenticationException
511     {
512         Repository repository = new Repository( "id", "http://bporter:password@www.example.com/path/to/resource" );
513 
514         AuthenticationInfo authenticationInfo = new AuthenticationInfo();
515         wagon.connect( repository, authenticationInfo );
516 
517         assertEquals( authenticationInfo, wagon.getAuthenticationInfo() );
518         assertEquals( "bporter", authenticationInfo.getUserName() );
519         assertEquals( "password", authenticationInfo.getPassword() );
520     }
521 
522     public void testConnectNullRepository()
523         throws ConnectionException, AuthenticationException
524     {
525         try
526         {
527             wagon.connect( null );
528             fail();
529         }
530         catch ( IllegalStateException e )
531         {
532             assertTrue( true );
533         }
534     }
535 
536     public void testPostProcessListeners()
537         throws TransferFailedException, IOException
538     {
539         File tempFile = File.createTempFile( "wagon", "tmp" );
540         tempFile.deleteOnExit();
541         String content = "content";
542         FileUtils.fileWrite( tempFile.getAbsolutePath(), content );
543 
544         Resource resource = new Resource( "resource" );
545 
546         transferListener.transferInitiated( null );
547         transferListenerControl.setMatcher( MockControl.ALWAYS_MATCHER );
548         transferListener.transferStarted( null );
549         transferListenerControl.setMatcher( MockControl.ALWAYS_MATCHER );
550         TransferEvent event =
551             new TransferEvent( wagon, resource, TransferEvent.TRANSFER_PROGRESS, TransferEvent.REQUEST_PUT );
552         event.setLocalFile( tempFile );
553         transferListener.transferProgress( event, content.getBytes(), content.length() );
554         ProgressArgumentMatcher matcher = new ProgressArgumentMatcher();
555         transferListenerControl.setMatcher( matcher );
556         transferListener.transferCompleted( null );
557         transferListenerControl.setMatcher( MockControl.ALWAYS_MATCHER );
558         transferListenerControl.replay();
559 
560         wagon.postProcessListeners( resource, tempFile, TransferEvent.REQUEST_PUT );
561 
562         assertEquals( content.length(), matcher.getSize() );
563         assertEquals( new String( content.getBytes() ), new String( matcher.getBytes() ) );
564 
565         tempFile.delete();
566     }
567 
568     static final class ProgressArgumentMatcher
569         extends AbstractMatcher
570     {
571         private ByteArrayOutputStream baos = new ByteArrayOutputStream();
572 
573         private int size;
574         
575         private byte[] lastArray;
576 
577         protected boolean argumentMatches( Object expected, Object actual )
578         {
579             if ( actual instanceof byte[] )
580             {
581                 lastArray = (byte[]) actual;
582                 return true;
583             }
584             if ( actual instanceof Integer )
585             {
586                 int length = ( (Integer) actual ).intValue();
587                 baos.write( lastArray, 0, length );
588                 size += length;
589                 return true;
590             }
591             return super.argumentMatches( expected, actual );
592         }
593 
594         public int getSize()
595         {
596             return size;
597         }
598 
599         public byte[] getBytes()
600         {
601             return baos.toByteArray();
602         }
603     }
604 }