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