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