001package org.eclipse.aether.transport.wagon; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import static org.junit.Assert.assertEquals; 023import static org.junit.Assert.assertTrue; 024import static org.junit.Assert.fail; 025 026import java.io.File; 027import java.net.URI; 028import java.nio.charset.StandardCharsets; 029import java.util.Map; 030import java.util.UUID; 031 032import org.apache.maven.wagon.ResourceDoesNotExistException; 033import org.apache.maven.wagon.TransferFailedException; 034import org.apache.maven.wagon.Wagon; 035import org.eclipse.aether.ConfigurationProperties; 036import org.eclipse.aether.DefaultRepositorySystemSession; 037import org.eclipse.aether.internal.test.util.TestFileUtils; 038import org.eclipse.aether.internal.test.util.TestUtils; 039import org.eclipse.aether.repository.Authentication; 040import org.eclipse.aether.repository.Proxy; 041import org.eclipse.aether.repository.RemoteRepository; 042import org.eclipse.aether.spi.connector.transport.GetTask; 043import org.eclipse.aether.spi.connector.transport.PeekTask; 044import org.eclipse.aether.spi.connector.transport.PutTask; 045import org.eclipse.aether.spi.connector.transport.Transporter; 046import org.eclipse.aether.spi.connector.transport.TransporterFactory; 047import org.eclipse.aether.transfer.NoTransporterException; 048import org.eclipse.aether.transfer.TransferCancelledException; 049import org.eclipse.aether.util.repository.AuthenticationBuilder; 050import org.junit.After; 051import org.junit.Before; 052import org.junit.Test; 053 054/** 055 */ 056public abstract class AbstractWagonTransporterTest 057{ 058 059 private DefaultRepositorySystemSession session; 060 061 private TransporterFactory factory; 062 063 private Transporter transporter; 064 065 private String id; 066 067 private Map<String, String> fs; 068 069 protected abstract Wagon newWagon(); 070 071 private RemoteRepository newRepo( String url ) 072 { 073 return new RemoteRepository.Builder( "test", "default", url ).build(); 074 } 075 076 private void newTransporter( String url ) 077 throws Exception 078 { 079 newTransporter( newRepo( url ) ); 080 } 081 082 private void newTransporter( RemoteRepository repo ) 083 throws Exception 084 { 085 if ( transporter != null ) 086 { 087 transporter.close(); 088 transporter = null; 089 } 090 transporter = factory.newInstance( session, repo ); 091 } 092 093 @Before 094 public void setUp() 095 throws Exception 096 { 097 session = TestUtils.newSession(); 098 factory = new WagonTransporterFactory( new WagonProvider() 099 { 100 public Wagon lookup( String roleHint ) 101 { 102 if ( "mem".equalsIgnoreCase( roleHint ) ) 103 { 104 return newWagon(); 105 } 106 throw new IllegalArgumentException( "unknown wagon role: " + roleHint ); 107 } 108 109 public void release( Wagon wagon ) 110 { 111 } 112 }, new WagonConfigurator() 113 { 114 public void configure( Wagon wagon, Object configuration ) 115 { 116 ( (Configurable) wagon ).setConfiguration( configuration ); 117 } 118 } ); 119 id = UUID.randomUUID().toString().replace( "-", "" ); 120 fs = MemWagonUtils.getFilesystem( id ); 121 fs.put( "file.txt", "test" ); 122 fs.put( "empty.txt", "" ); 123 fs.put( "some space.txt", "space" ); 124 newTransporter( "mem://" + id ); 125 } 126 127 @After 128 public void tearDown() 129 { 130 if ( transporter != null ) 131 { 132 transporter.close(); 133 transporter = null; 134 } 135 factory = null; 136 session = null; 137 } 138 139 @Test 140 public void testClassify() 141 { 142 assertEquals( Transporter.ERROR_OTHER, transporter.classify( new TransferFailedException( "test" ) ) ); 143 assertEquals( Transporter.ERROR_NOT_FOUND, transporter.classify( new ResourceDoesNotExistException( "test" ) ) ); 144 } 145 146 @Test 147 public void testPeek() 148 throws Exception 149 { 150 transporter.peek( new PeekTask( URI.create( "file.txt" ) ) ); 151 } 152 153 @Test 154 public void testPeek_NotFound() 155 throws Exception 156 { 157 try 158 { 159 transporter.peek( new PeekTask( URI.create( "missing.txt" ) ) ); 160 fail( "Expected error" ); 161 } 162 catch ( ResourceDoesNotExistException e ) 163 { 164 assertEquals( Transporter.ERROR_NOT_FOUND, transporter.classify( e ) ); 165 } 166 } 167 168 @Test 169 public void testPeek_Closed() 170 throws Exception 171 { 172 transporter.close(); 173 try 174 { 175 transporter.peek( new PeekTask( URI.create( "missing.txt" ) ) ); 176 fail( "Expected error" ); 177 } 178 catch ( IllegalStateException e ) 179 { 180 assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) ); 181 } 182 } 183 184 @Test 185 public void testGet_ToMemory() 186 throws Exception 187 { 188 RecordingTransportListener listener = new RecordingTransportListener(); 189 GetTask task = new GetTask( URI.create( "file.txt" ) ).setListener( listener ); 190 transporter.get( task ); 191 assertEquals( "test", task.getDataString() ); 192 assertEquals( 0L, listener.dataOffset ); 193 assertEquals( 4L, listener.dataLength ); 194 assertEquals( 1, listener.startedCount ); 195 assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 ); 196 assertEquals( task.getDataString(), new String( listener.baos.toByteArray(), StandardCharsets.UTF_8 ) ); 197 } 198 199 @Test 200 public void testGet_ToFile() 201 throws Exception 202 { 203 File file = TestFileUtils.createTempFile( "failure" ); 204 RecordingTransportListener listener = new RecordingTransportListener(); 205 GetTask task = new GetTask( URI.create( "file.txt" ) ).setDataFile( file ).setListener( listener ); 206 transporter.get( task ); 207 assertEquals( "test", TestFileUtils.readString( file ) ); 208 assertEquals( 0L, listener.dataOffset ); 209 assertEquals( 4L, listener.dataLength ); 210 assertEquals( 1, listener.startedCount ); 211 assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 ); 212 assertEquals( "test", new String( listener.baos.toByteArray(), StandardCharsets.UTF_8 ) ); 213 } 214 215 @Test 216 public void testGet_EmptyResource() 217 throws Exception 218 { 219 File file = TestFileUtils.createTempFile( "failure" ); 220 assertTrue( file.delete() && !file.exists() ); 221 RecordingTransportListener listener = new RecordingTransportListener(); 222 GetTask task = new GetTask( URI.create( "empty.txt" ) ).setDataFile( file ).setListener( listener ); 223 transporter.get( task ); 224 assertEquals( "", TestFileUtils.readString( file ) ); 225 assertEquals( 0L, listener.dataOffset ); 226 assertEquals( 0L, listener.dataLength ); 227 assertEquals( 1, listener.startedCount ); 228 assertEquals( 0, listener.progressedCount ); 229 assertEquals( "", new String( listener.baos.toByteArray(), StandardCharsets.UTF_8 ) ); 230 } 231 232 @Test 233 public void testGet_EncodedResourcePath() 234 throws Exception 235 { 236 GetTask task = new GetTask( URI.create( "some%20space.txt" ) ); 237 transporter.get( task ); 238 assertEquals( "space", task.getDataString() ); 239 } 240 241 @Test 242 public void testGet_FileHandleLeak() 243 throws Exception 244 { 245 for ( int i = 0; i < 100; i++ ) 246 { 247 File file = TestFileUtils.createTempFile( "failure" ); 248 transporter.get( new GetTask( URI.create( "file.txt" ) ).setDataFile( file ) ); 249 assertTrue( i + ", " + file.getAbsolutePath(), file.delete() ); 250 } 251 } 252 253 @Test 254 public void testGet_NotFound() 255 throws Exception 256 { 257 try 258 { 259 transporter.get( new GetTask( URI.create( "missing.txt" ) ) ); 260 fail( "Expected error" ); 261 } 262 catch ( ResourceDoesNotExistException e ) 263 { 264 assertEquals( Transporter.ERROR_NOT_FOUND, transporter.classify( e ) ); 265 } 266 } 267 268 @Test 269 public void testGet_Closed() 270 throws Exception 271 { 272 transporter.close(); 273 try 274 { 275 transporter.get( new GetTask( URI.create( "file.txt" ) ) ); 276 fail( "Expected error" ); 277 } 278 catch ( IllegalStateException e ) 279 { 280 assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) ); 281 } 282 } 283 284 @Test 285 public void testGet_StartCancelled() 286 throws Exception 287 { 288 RecordingTransportListener listener = new RecordingTransportListener(); 289 listener.cancelStart = true; 290 GetTask task = new GetTask( URI.create( "file.txt" ) ).setListener( listener ); 291 transporter.get( task ); 292 assertEquals( 1, listener.startedCount ); 293 } 294 295 @Test 296 public void testGet_ProgressCancelled() 297 throws Exception 298 { 299 RecordingTransportListener listener = new RecordingTransportListener(); 300 listener.cancelProgress = true; 301 GetTask task = new GetTask( URI.create( "file.txt" ) ).setListener( listener ); 302 try 303 { 304 transporter.get( task ); 305 fail( "Expected error" ); 306 } 307 catch ( TransferCancelledException e ) 308 { 309 assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) ); 310 } 311 assertEquals( 0L, listener.dataOffset ); 312 assertEquals( 4L, listener.dataLength ); 313 assertEquals( 1, listener.startedCount ); 314 assertEquals( 1, listener.progressedCount ); 315 } 316 317 @Test 318 public void testPut_FromMemory() 319 throws Exception 320 { 321 RecordingTransportListener listener = new RecordingTransportListener(); 322 PutTask task = new PutTask( URI.create( "file.txt" ) ).setListener( listener ).setDataString( "upload" ); 323 transporter.put( task ); 324 assertEquals( 0L, listener.dataOffset ); 325 assertEquals( 6L, listener.dataLength ); 326 assertEquals( 1, listener.startedCount ); 327 assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 ); 328 assertEquals( "upload", fs.get( "file.txt" ) ); 329 } 330 331 @Test 332 public void testPut_FromFile() 333 throws Exception 334 { 335 File file = TestFileUtils.createTempFile( "upload" ); 336 RecordingTransportListener listener = new RecordingTransportListener(); 337 PutTask task = new PutTask( URI.create( "file.txt" ) ).setListener( listener ).setDataFile( file ); 338 transporter.put( task ); 339 assertEquals( 0L, listener.dataOffset ); 340 assertEquals( 6L, listener.dataLength ); 341 assertEquals( 1, listener.startedCount ); 342 assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 ); 343 assertEquals( "upload", fs.get( "file.txt" ) ); 344 } 345 346 @Test 347 public void testPut_EmptyResource() 348 throws Exception 349 { 350 RecordingTransportListener listener = new RecordingTransportListener(); 351 PutTask task = new PutTask( URI.create( "file.txt" ) ).setListener( listener ); 352 transporter.put( task ); 353 assertEquals( 0L, listener.dataOffset ); 354 assertEquals( 0L, listener.dataLength ); 355 assertEquals( 1, listener.startedCount ); 356 assertEquals( 0, listener.progressedCount ); 357 assertEquals( "", fs.get( "file.txt" ) ); 358 } 359 360 @Test 361 public void testPut_NonExistentParentDir() 362 throws Exception 363 { 364 RecordingTransportListener listener = new RecordingTransportListener(); 365 PutTask task = 366 new PutTask( URI.create( "dir/sub/dir/file.txt" ) ).setListener( listener ).setDataString( "upload" ); 367 transporter.put( task ); 368 assertEquals( 0L, listener.dataOffset ); 369 assertEquals( 6L, listener.dataLength ); 370 assertEquals( 1, listener.startedCount ); 371 assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 ); 372 assertEquals( "upload", fs.get( "dir/sub/dir/file.txt" ) ); 373 } 374 375 @Test 376 public void testPut_EncodedResourcePath() 377 throws Exception 378 { 379 RecordingTransportListener listener = new RecordingTransportListener(); 380 PutTask task = new PutTask( URI.create( "some%20space.txt" ) ).setListener( listener ).setDataString( "OK" ); 381 transporter.put( task ); 382 assertEquals( 0L, listener.dataOffset ); 383 assertEquals( 2L, listener.dataLength ); 384 assertEquals( 1, listener.startedCount ); 385 assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 ); 386 assertEquals( "OK", fs.get( "some space.txt" ) ); 387 } 388 389 @Test 390 public void testPut_FileHandleLeak() 391 throws Exception 392 { 393 for ( int i = 0; i < 100; i++ ) 394 { 395 File src = TestFileUtils.createTempFile( "upload" ); 396 transporter.put( new PutTask( URI.create( "file.txt" ) ).setDataFile( src ) ); 397 assertTrue( i + ", " + src.getAbsolutePath(), src.delete() ); 398 } 399 } 400 401 @Test 402 public void testPut_Closed() 403 throws Exception 404 { 405 transporter.close(); 406 try 407 { 408 transporter.put( new PutTask( URI.create( "missing.txt" ) ) ); 409 fail( "Expected error" ); 410 } 411 catch ( IllegalStateException e ) 412 { 413 assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) ); 414 } 415 } 416 417 @Test 418 public void testPut_StartCancelled() 419 throws Exception 420 { 421 RecordingTransportListener listener = new RecordingTransportListener(); 422 listener.cancelStart = true; 423 PutTask task = new PutTask( URI.create( "file.txt" ) ).setListener( listener ).setDataString( "upload" ); 424 transporter.put( task ); 425 assertEquals( 1, listener.startedCount ); 426 } 427 428 @Test 429 public void testPut_ProgressCancelled() 430 throws Exception 431 { 432 RecordingTransportListener listener = new RecordingTransportListener(); 433 listener.cancelProgress = true; 434 PutTask task = new PutTask( URI.create( "file.txt" ) ).setListener( listener ).setDataString( "upload" ); 435 try 436 { 437 transporter.put( task ); 438 fail( "Expected error" ); 439 } 440 catch ( TransferCancelledException e ) 441 { 442 assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) ); 443 } 444 assertEquals( 0L, listener.dataOffset ); 445 assertEquals( 6L, listener.dataLength ); 446 assertEquals( 1, listener.startedCount ); 447 assertEquals( 1, listener.progressedCount ); 448 } 449 450 @Test( expected = NoTransporterException.class ) 451 public void testInit_BadProtocol() 452 throws Exception 453 { 454 newTransporter( "bad:/void" ); 455 } 456 457 @Test 458 public void testInit_CaseInsensitiveProtocol() 459 throws Exception 460 { 461 newTransporter( "mem:/void" ); 462 newTransporter( "MEM:/void" ); 463 newTransporter( "mEm:/void" ); 464 } 465 466 @Test 467 public void testInit_Configuration() 468 throws Exception 469 { 470 session.setConfigProperty( "aether.connector.wagon.config.test", "passed" ); 471 newTransporter( "mem://" + id + "?config=passed" ); 472 transporter.peek( new PeekTask( URI.create( "file.txt" ) ) ); 473 } 474 475 @Test 476 public void testInit_UserAgent() 477 throws Exception 478 { 479 session.setConfigProperty( ConfigurationProperties.USER_AGENT, "Test/1.0" ); 480 newTransporter( "mem://" + id + "?userAgent=Test/1.0" ); 481 transporter.peek( new PeekTask( URI.create( "file.txt" ) ) ); 482 } 483 484 @Test 485 public void testInit_Timeout() 486 throws Exception 487 { 488 session.setConfigProperty( ConfigurationProperties.REQUEST_TIMEOUT, "12345678" ); 489 newTransporter( "mem://" + id + "?requestTimeout=12345678" ); 490 transporter.peek( new PeekTask( URI.create( "file.txt" ) ) ); 491 } 492 493 @Test 494 public void testInit_ServerAuth() 495 throws Exception 496 { 497 String url = 498 "mem://" + id + "?serverUsername=testuser&serverPassword=testpass" 499 + "&serverPrivateKey=testkey&serverPassphrase=testphrase"; 500 Authentication auth = 501 new AuthenticationBuilder().addUsername( "testuser" ).addPassword( "testpass" ).addPrivateKey( "testkey", 502 "testphrase" ).build(); 503 RemoteRepository repo = 504 new RemoteRepository.Builder( "test", "default", url ).setAuthentication( auth ).build(); 505 newTransporter( repo ); 506 transporter.peek( new PeekTask( URI.create( "file.txt" ) ) ); 507 } 508 509 @Test 510 public void testInit_Proxy() 511 throws Exception 512 { 513 String url = "mem://" + id + "?proxyHost=testhost&proxyPort=8888"; 514 RemoteRepository repo = 515 new RemoteRepository.Builder( "test", "default", url ).setProxy( new Proxy( "http", "testhost", 8888 ) ).build(); 516 newTransporter( repo ); 517 transporter.peek( new PeekTask( URI.create( "file.txt" ) ) ); 518 } 519 520 @Test 521 public void testInit_ProxyAuth() 522 throws Exception 523 { 524 String url = "mem://" + id + "?proxyUsername=testuser&proxyPassword=testpass"; 525 Authentication auth = new AuthenticationBuilder().addUsername( "testuser" ).addPassword( "testpass" ).build(); 526 RemoteRepository repo = 527 new RemoteRepository.Builder( "test", "default", url ).setProxy( new Proxy( "http", "testhost", 8888, auth ) ).build(); 528 newTransporter( repo ); 529 transporter.peek( new PeekTask( URI.create( "file.txt" ) ) ); 530 } 531 532}