View Javadoc

1   package org.apache.maven.wagon.providers.webdav;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
5    * agreements. See the NOTICE file distributed with this work for additional information regarding
6    * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance with the License. You may obtain a
8    * copy of the License at
9    * 
10   * http://www.apache.org/licenses/LICENSE-2.0
11   * 
12   * Unless required by applicable law or agreed to in writing, software distributed under the License
13   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14   * or implied. See the License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  
18  import it.could.webdav.DAVServlet;
19  import org.apache.commons.httpclient.HttpException;
20  import org.apache.commons.httpclient.HttpMethod;
21  import org.apache.maven.wagon.ResourceDoesNotExistException;
22  import org.apache.maven.wagon.StreamingWagon;
23  import org.apache.maven.wagon.TransferFailedException;
24  import org.apache.maven.wagon.Wagon;
25  import org.apache.maven.wagon.http.HttpWagonTestCase;
26  import org.apache.maven.wagon.repository.Repository;
27  import org.apache.maven.wagon.resource.Resource;
28  import org.mortbay.jetty.Server;
29  import org.mortbay.jetty.servlet.Context;
30  import org.mortbay.jetty.servlet.ServletHolder;
31  
32  import java.io.File;
33  import java.io.IOException;
34  import java.net.SocketTimeoutException;
35  import java.util.List;
36  import java.util.Properties;
37  
38  /*
39   * WebDAV Wagon Test
40   * 
41   * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
42   * 
43   * @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
44   */
45  public class WebDavWagonTest
46      extends HttpWagonTestCase
47  {
48      protected String getTestRepositoryUrl()
49          throws IOException
50      {
51          return getProtocol() + "://localhost:" + getTestRepositoryPort() + "/newfolder/folder2/";
52      }
53  
54      protected String getProtocol()
55      {
56          return "dav";
57      }
58  
59      protected void createContext( Server server, File repositoryDirectory )
60          throws IOException
61      {
62          Context dav = new Context( server, "/", Context.SESSIONS );
63          ServletHolder davServletHolder = new ServletHolder( new DAVServlet() );
64          davServletHolder.setInitParameter( "rootPath", repositoryDirectory.getAbsolutePath() );
65          davServletHolder.setInitParameter( "xmlOnly", "false" );
66          dav.addServlet( davServletHolder, "/*" );
67      }
68  
69      protected long getExpectedLastModifiedOnGet( Repository repository, Resource resource )
70      {
71          File file = new File( getDavRepository(), resource.getName() );
72          return ( file.lastModified() / 1000 ) * 1000;
73      }
74  
75  
76      private File getDavRepository()
77      {
78          return getTestFile( "target/test-output/http-repository/newfolder/folder2" );
79      }
80  
81      private void assertURL( String userUrl, String expectedUrl )
82      {
83          Repository repo = new Repository( "test-geturl", userUrl );
84          String actualUrl = ( new WebDavWagon() ).getURL( repo );
85          assertEquals( "WebDavWagon.getURL(" + userUrl + ")", expectedUrl, actualUrl );
86      }
87  
88      /**
89       * Tests the maven 2.0.x way to define a webdav URL without SSL.
90       */
91      public void testGetURLDavHttp()
92      {
93          assertURL( "dav:http://localhost:" + getTestRepositoryPort() + "/dav/",
94                     "http://localhost:" + getTestRepositoryPort() + "/dav/" );
95      }
96  
97      /**
98       * Tests the maven 2.0.x way to define a webdav URL with SSL.
99       */
100     public void testGetURLDavHttps()
101     {
102         assertURL( "dav:https://localhost:" + getTestRepositoryPort() + "/dav/",
103                    "https://localhost:" + getTestRepositoryPort() + "/dav/" );
104     }
105 
106     /**
107      * Tests the URI spec way of defining a webdav URL without SSL.
108      */
109     public void testGetURLDavUri()
110     {
111         assertURL( "dav://localhost:" + getTestRepositoryPort() + "/dav/",
112                    "http://localhost:" + getTestRepositoryPort() + "/dav/" );
113     }
114 
115     /**
116      * Tests the URI spec way of defining a webdav URL with SSL.
117      */
118     public void testGetURLDavUriWithSsl()
119     {
120         assertURL( "davs://localhost:" + getTestRepositoryPort() + "/dav/",
121                    "https://localhost:" + getTestRepositoryPort() + "/dav/" );
122     }
123 
124     /**
125      * Tests the URI spec way of defining a webdav URL without SSL.
126      */
127     public void testGetURLDavPlusHttp()
128     {
129         assertURL( "dav+https://localhost:" + getTestRepositoryPort() + "/dav/",
130                    "https://localhost:" + getTestRepositoryPort() + "/dav/" );
131     }
132 
133     /**
134      * Tests the URI spec way of defining a webdav URL with SSL.
135      */
136     public void testGetURLDavPlusHttps()
137     {
138         assertURL( "dav+https://localhost:" + getTestRepositoryPort() + "/dav/",
139                    "https://localhost:" + getTestRepositoryPort() + "/dav/" );
140     }
141 
142     public void testMkdirs()
143         throws Exception
144     {
145         setupRepositories();
146 
147         setupWagonTestingFixtures();
148 
149         WebDavWagon wagon = (WebDavWagon) getWagon();
150         wagon.connect( testRepository, getAuthInfo() );
151 
152         try
153         {
154             File dir = getRepositoryDirectory();
155 
156             // check basedir also doesn't exist and will need to be created
157             dir = new File( dir, testRepository.getBasedir() );
158             assertFalse( dir.exists() );
159 
160             // test leading /
161             assertFalse( new File( dir, "foo" ).exists() );
162             wagon.mkdirs( "/foo" );
163             assertTrue( new File( dir, "foo" ).exists() );
164 
165             // test trailing /
166             assertFalse( new File( dir, "bar" ).exists() );
167             wagon.mkdirs( "bar/" );
168             assertTrue( new File( dir, "bar" ).exists() );
169 
170             // test when already exists
171             wagon.mkdirs( "bar" );
172 
173             // test several parts
174             assertFalse( new File( dir, "1/2/3/4" ).exists() );
175             wagon.mkdirs( "1/2/3/4" );
176             assertTrue( new File( dir, "1/2/3/4" ).exists() );
177 
178             // test additional part and trailing /
179             assertFalse( new File( dir, "1/2/3/4/5" ).exists() );
180             wagon.mkdirs( "1/2/3/4/5/" );
181             assertTrue( new File( dir, "1/2/3/4" ).exists() );
182         }
183         finally
184         {
185             wagon.disconnect();
186 
187             tearDownWagonTestingFixtures();
188         }
189     }
190 
191     public void testMkdirsWithNoBasedir()
192         throws Exception
193     {
194         // WAGON-244
195         setupRepositories();
196 
197         setupWagonTestingFixtures();
198 
199         // reconstruct with no basedir
200         testRepository.setUrl(
201             testRepository.getProtocol() + "://" + testRepository.getHost() + ":" + testRepository.getPort() );
202 
203         WebDavWagon wagon = (WebDavWagon) getWagon();
204         wagon.connect( testRepository, getAuthInfo() );
205 
206         try
207         {
208             File dir = getRepositoryDirectory();
209 
210             // check basedir also doesn't exist and will need to be created
211             dir = new File( dir, testRepository.getBasedir() );
212             assertTrue( dir.exists() );
213 
214             // test leading /
215             assertFalse( new File( dir, "foo" ).exists() );
216             wagon.mkdirs( "/foo" );
217             assertTrue( new File( dir, "foo" ).exists() );
218         }
219         finally
220         {
221             wagon.disconnect();
222 
223             tearDownWagonTestingFixtures();
224         }
225     }
226 
227     protected void setHttpHeaders( StreamingWagon wagon, Properties properties )
228     {
229         ( (WebDavWagon) wagon ).setHttpHeaders( properties );
230     }
231 
232     /**
233      * Make sure wagon webdav can detect remote directory
234      *
235      * @throws Exception
236      */
237     public void testWagonWebDavGetFileList()
238         throws Exception
239     {
240         setupRepositories();
241 
242         setupWagonTestingFixtures();
243 
244         String dirName = "file-list";
245 
246         String filenames[] =
247             new String[]{ "test-resource.txt", "test-resource.pom", "test-resource b.txt", "more-resources.dat" };
248 
249         for ( int i = 0; i < filenames.length; i++ )
250         {
251             putFile( dirName + "/" + filenames[i], dirName + "/" + filenames[i], filenames[i] + "\n" );
252         }
253 
254         String dirnames[] = new String[]{ "test-dir1", "test-dir2" };
255 
256         for ( int i = 0; i < dirnames.length; i++ )
257         {
258             new File( getDavRepository(), dirName + "/" + dirnames[i] ).mkdirs();
259         }
260 
261         Wagon wagon = getWagon();
262 
263         wagon.connect( testRepository, getAuthInfo() );
264 
265         List<String> list = wagon.getFileList( dirName );
266 
267         assertNotNull( "file list should not be null.", list );
268         assertEquals( "file list should contain 6 items", 6, list.size() );
269 
270         for ( int i = 0; i < filenames.length; i++ )
271         {
272             assertTrue( "Filename '" + filenames[i] + "' should be in list.", list.contains( filenames[i] ) );
273         }
274 
275         for ( int i = 0; i < dirnames.length; i++ )
276         {
277             assertTrue( "Directory '" + dirnames[i] + "' should be in list.", list.contains( dirnames[i] + "/" ) );
278         }
279 
280         ///////////////////////////////////////////////////////////////////////////
281         list = wagon.getFileList( "" );
282         assertNotNull( "file list should not be null.", list );
283         assertEquals( "file list should contain 1 items", 1, list.size() );
284 
285         ///////////////////////////////////////////////////////////////////////////
286         list = wagon.getFileList( dirName + "/test-dir1" );
287         assertNotNull( "file list should not be null.", list );
288         assertEquals( "file list should contain 0 items", 0, list.size() );
289 
290         /////////////////////////////////////////////////////////////////////////////
291         try
292         {
293             list = wagon.getFileList( dirName + "/test-dir-bogus" );
294             fail( "Exception expected" );
295         }
296         catch ( ResourceDoesNotExistException e )
297         {
298 
299         }
300 
301         wagon.disconnect();
302 
303         tearDownWagonTestingFixtures();
304     }
305 
306     @Override
307     protected boolean supportPreemptiveAuthentication()
308     {
309         return true;
310     }
311 
312     protected void testPreemptiveAuthentication( TestSecurityHandler sh )
313     {
314 
315         if ( supportPreemptiveAuthentication() )
316         {
317             assertEquals( "not 2 security handler use " + sh.securityHandlerRequestReponses, 2,
318                           sh.securityHandlerRequestReponses.size() );
319             assertEquals( 200, sh.securityHandlerRequestReponses.get( 0 ).responseCode );
320         }
321         else
322         {
323             assertEquals( "not 4 security handler use " + sh.securityHandlerRequestReponses, 4,
324                           sh.securityHandlerRequestReponses.size() );
325             assertEquals( 401, sh.securityHandlerRequestReponses.get( 0 ).responseCode );
326             assertEquals( 200, sh.securityHandlerRequestReponses.get( 1 ).responseCode );
327             assertEquals( 401, sh.securityHandlerRequestReponses.get( 2 ).responseCode );
328             assertEquals( 200, sh.securityHandlerRequestReponses.get( 3 ).responseCode );
329 
330         }
331     }
332 
333     public void testWagonFailsOnPutFailureByDefault()
334         throws Exception
335     {
336         setupRepositories();
337 
338         setupWagonTestingFixtures();
339 
340         File testFile = getTempFile();
341 
342         System.clearProperty( WebDavWagon.CONTINUE_ON_FAILURE_PROPERTY );
343 
344         WebDavWagon wagon = new TimeoutSimulatingWagon();
345         wagon.connect( testRepository, getAuthInfo() );
346 
347         try
348         {
349             String filename = TimeoutSimulatingWagon.TIMEOUT_TRIGGER + ".txt";
350 
351             try
352             {
353                 wagon.put( testFile, filename );
354                 fail( "Exception expected" );
355             }
356             catch ( TransferFailedException e )
357             {
358 
359             }
360         }
361         finally
362         {
363             wagon.disconnect();
364 
365             tearDownWagonTestingFixtures();
366         }
367     }
368 
369     private File getTempFile()
370         throws IOException
371     {
372         File inputFile = File.createTempFile( "test-resource", ".txt" );
373         inputFile.deleteOnExit();
374         return inputFile;
375     }
376 
377     private static class TimeoutSimulatingWagon
378         extends WebDavWagon
379     {
380         private static final String TIMEOUT_TRIGGER = "timeout";
381 
382         protected int execute( HttpMethod httpMethod )
383             throws HttpException, IOException
384         {
385             if ( httpMethod.getPath().contains( TIMEOUT_TRIGGER ) )
386             {
387                 throw new SocketTimeoutException( "Timeout triggered by request for '" + httpMethod.getPath() + "'" );
388             }
389             else
390             {
391                 return super.execute( httpMethod );
392             }
393         }
394     }
395 
396     public void testWagonContinuesOnPutFailureIfPropertySet()
397         throws Exception
398     {
399         setupRepositories();
400 
401         setupWagonTestingFixtures();
402 
403         File testFile = getTempFile();
404 
405         String continueOnFailureProperty = WebDavWagon.CONTINUE_ON_FAILURE_PROPERTY;
406         System.setProperty( continueOnFailureProperty, "true" );
407 
408         WebDavWagon wagon = new TimeoutSimulatingWagon();
409         wagon.connect( testRepository, getAuthInfo() );
410 
411         try
412         {
413             String filename = TimeoutSimulatingWagon.TIMEOUT_TRIGGER + ".txt";
414 
415             wagon.put( testFile, filename );
416         }
417         finally
418         {
419             wagon.disconnect();
420 
421             System.clearProperty( continueOnFailureProperty );
422 
423             tearDownWagonTestingFixtures();
424         }
425     }
426 
427     protected boolean supportProxyPreemptiveAuthentication()
428     {
429         return true;
430     }
431 
432 }