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.util.Map; 029import java.util.UUID; 030 031import org.apache.maven.wagon.ResourceDoesNotExistException; 032import org.apache.maven.wagon.TransferFailedException; 033import org.apache.maven.wagon.Wagon; 034import org.eclipse.aether.ConfigurationProperties; 035import org.eclipse.aether.DefaultRepositorySystemSession; 036import org.eclipse.aether.internal.test.util.TestFileUtils; 037import org.eclipse.aether.internal.test.util.TestLoggerFactory; 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 throws Exception 102 { 103 if ( "mem".equalsIgnoreCase( roleHint ) ) 104 { 105 return newWagon(); 106 } 107 throw new IllegalArgumentException( "Unknown wagon role: " + roleHint ); 108 } 109 110 public void release( Wagon wagon ) 111 { 112 } 113 }, new WagonConfigurator() 114 { 115 public void configure( Wagon wagon, Object configuration ) 116 throws Exception 117 { 118 ( (Configurable) wagon ).setConfiguration( configuration ); 119 } 120 }, new TestLoggerFactory() ); 121 id = UUID.randomUUID().toString().replace( "-", "" ); 122 fs = MemWagonUtils.getFilesystem( id ); 123 fs.put( "file.txt", "test" ); 124 fs.put( "empty.txt", "" ); 125 fs.put( "some space.txt", "space" ); 126 newTransporter( "mem://" + id ); 127 } 128 129 @After 130 public void tearDown() 131 { 132 if ( transporter != null ) 133 { 134 transporter.close(); 135 transporter = null; 136 } 137 factory = null; 138 session = null; 139 } 140 141 @Test 142 public void testClassify() 143 { 144 assertEquals( Transporter.ERROR_OTHER, transporter.classify( new TransferFailedException( "test" ) ) ); 145 assertEquals( Transporter.ERROR_NOT_FOUND, transporter.classify( new ResourceDoesNotExistException( "test" ) ) ); 146 } 147 148 @Test 149 public void testPeek() 150 throws Exception 151 { 152 transporter.peek( new PeekTask( URI.create( "file.txt" ) ) ); 153 } 154 155 @Test 156 public void testPeek_NotFound() 157 throws Exception 158 { 159 try 160 { 161 transporter.peek( new PeekTask( URI.create( "missing.txt" ) ) ); 162 fail( "Expected error" ); 163 } 164 catch ( ResourceDoesNotExistException e ) 165 { 166 assertEquals( Transporter.ERROR_NOT_FOUND, transporter.classify( e ) ); 167 } 168 } 169 170 @Test 171 public void testPeek_Closed() 172 throws Exception 173 { 174 transporter.close(); 175 try 176 { 177 transporter.peek( new PeekTask( URI.create( "missing.txt" ) ) ); 178 fail( "Expected error" ); 179 } 180 catch ( IllegalStateException e ) 181 { 182 assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) ); 183 } 184 } 185 186 @Test 187 public void testGet_ToMemory() 188 throws Exception 189 { 190 RecordingTransportListener listener = new RecordingTransportListener(); 191 GetTask task = new GetTask( URI.create( "file.txt" ) ).setListener( listener ); 192 transporter.get( task ); 193 assertEquals( "test", task.getDataString() ); 194 assertEquals( 0, listener.dataOffset ); 195 assertEquals( 4, listener.dataLength ); 196 assertEquals( 1, listener.startedCount ); 197 assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 ); 198 assertEquals( task.getDataString(), listener.baos.toString( "UTF-8" ) ); 199 } 200 201 @Test 202 public void testGet_ToFile() 203 throws Exception 204 { 205 File file = TestFileUtils.createTempFile( "failure" ); 206 RecordingTransportListener listener = new RecordingTransportListener(); 207 GetTask task = new GetTask( URI.create( "file.txt" ) ).setDataFile( file ).setListener( listener ); 208 transporter.get( task ); 209 assertEquals( "test", TestFileUtils.readString( file ) ); 210 assertEquals( 0, listener.dataOffset ); 211 assertEquals( 4, listener.dataLength ); 212 assertEquals( 1, listener.startedCount ); 213 assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 ); 214 assertEquals( "test", listener.baos.toString( "UTF-8" ) ); 215 } 216 217 @Test 218 public void testGet_EmptyResource() 219 throws Exception 220 { 221 File file = TestFileUtils.createTempFile( "failure" ); 222 assertTrue( file.delete() && !file.exists() ); 223 RecordingTransportListener listener = new RecordingTransportListener(); 224 GetTask task = new GetTask( URI.create( "empty.txt" ) ).setDataFile( file ).setListener( listener ); 225 transporter.get( task ); 226 assertEquals( "", TestFileUtils.readString( file ) ); 227 assertEquals( 0, listener.dataOffset ); 228 assertEquals( 0, listener.dataLength ); 229 assertEquals( 1, listener.startedCount ); 230 assertEquals( 0, listener.progressedCount ); 231 assertEquals( "", listener.baos.toString( "UTF-8" ) ); 232 } 233 234 @Test 235 public void testGet_EncodedResourcePath() 236 throws Exception 237 { 238 GetTask task = new GetTask( URI.create( "some%20space.txt" ) ); 239 transporter.get( task ); 240 assertEquals( "space", task.getDataString() ); 241 } 242 243 @Test 244 public void testGet_FileHandleLeak() 245 throws Exception 246 { 247 for ( int i = 0; i < 100; i++ ) 248 { 249 File file = TestFileUtils.createTempFile( "failure" ); 250 transporter.get( new GetTask( URI.create( "file.txt" ) ).setDataFile( file ) ); 251 assertTrue( i + ", " + file.getAbsolutePath(), file.delete() ); 252 } 253 } 254 255 @Test 256 public void testGet_NotFound() 257 throws Exception 258 { 259 try 260 { 261 transporter.get( new GetTask( URI.create( "missing.txt" ) ) ); 262 fail( "Expected error" ); 263 } 264 catch ( ResourceDoesNotExistException e ) 265 { 266 assertEquals( Transporter.ERROR_NOT_FOUND, transporter.classify( e ) ); 267 } 268 } 269 270 @Test 271 public void testGet_Closed() 272 throws Exception 273 { 274 transporter.close(); 275 try 276 { 277 transporter.get( new GetTask( URI.create( "file.txt" ) ) ); 278 fail( "Expected error" ); 279 } 280 catch ( IllegalStateException e ) 281 { 282 assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) ); 283 } 284 } 285 286 @Test 287 public void testGet_StartCancelled() 288 throws Exception 289 { 290 RecordingTransportListener listener = new RecordingTransportListener(); 291 listener.cancelStart = true; 292 GetTask task = new GetTask( URI.create( "file.txt" ) ).setListener( listener ); 293 transporter.get( task ); 294 assertEquals( 1, listener.startedCount ); 295 } 296 297 @Test 298 public void testGet_ProgressCancelled() 299 throws Exception 300 { 301 RecordingTransportListener listener = new RecordingTransportListener(); 302 listener.cancelProgress = true; 303 GetTask task = new GetTask( URI.create( "file.txt" ) ).setListener( listener ); 304 try 305 { 306 transporter.get( task ); 307 fail( "Expected error" ); 308 } 309 catch ( TransferCancelledException e ) 310 { 311 assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) ); 312 } 313 assertEquals( 0, listener.dataOffset ); 314 assertEquals( 4, listener.dataLength ); 315 assertEquals( 1, listener.startedCount ); 316 assertEquals( 1, listener.progressedCount ); 317 } 318 319 @Test 320 public void testPut_FromMemory() 321 throws Exception 322 { 323 RecordingTransportListener listener = new RecordingTransportListener(); 324 PutTask task = new PutTask( URI.create( "file.txt" ) ).setListener( listener ).setDataString( "upload" ); 325 transporter.put( task ); 326 assertEquals( 0, listener.dataOffset ); 327 assertEquals( 6, listener.dataLength ); 328 assertEquals( 1, listener.startedCount ); 329 assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 ); 330 assertEquals( "upload", fs.get( "file.txt" ) ); 331 } 332 333 @Test 334 public void testPut_FromFile() 335 throws Exception 336 { 337 File file = TestFileUtils.createTempFile( "upload" ); 338 RecordingTransportListener listener = new RecordingTransportListener(); 339 PutTask task = new PutTask( URI.create( "file.txt" ) ).setListener( listener ).setDataFile( file ); 340 transporter.put( task ); 341 assertEquals( 0, listener.dataOffset ); 342 assertEquals( 6, listener.dataLength ); 343 assertEquals( 1, listener.startedCount ); 344 assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 ); 345 assertEquals( "upload", fs.get( "file.txt" ) ); 346 } 347 348 @Test 349 public void testPut_EmptyResource() 350 throws Exception 351 { 352 RecordingTransportListener listener = new RecordingTransportListener(); 353 PutTask task = new PutTask( URI.create( "file.txt" ) ).setListener( listener ); 354 transporter.put( task ); 355 assertEquals( 0, listener.dataOffset ); 356 assertEquals( 0, listener.dataLength ); 357 assertEquals( 1, listener.startedCount ); 358 assertEquals( 0, listener.progressedCount ); 359 assertEquals( "", fs.get( "file.txt" ) ); 360 } 361 362 @Test 363 public void testPut_NonExistentParentDir() 364 throws Exception 365 { 366 RecordingTransportListener listener = new RecordingTransportListener(); 367 PutTask task = 368 new PutTask( URI.create( "dir/sub/dir/file.txt" ) ).setListener( listener ).setDataString( "upload" ); 369 transporter.put( task ); 370 assertEquals( 0, listener.dataOffset ); 371 assertEquals( 6, listener.dataLength ); 372 assertEquals( 1, listener.startedCount ); 373 assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 ); 374 assertEquals( "upload", fs.get( "dir/sub/dir/file.txt" ) ); 375 } 376 377 @Test 378 public void testPut_EncodedResourcePath() 379 throws Exception 380 { 381 RecordingTransportListener listener = new RecordingTransportListener(); 382 PutTask task = new PutTask( URI.create( "some%20space.txt" ) ).setListener( listener ).setDataString( "OK" ); 383 transporter.put( task ); 384 assertEquals( 0, listener.dataOffset ); 385 assertEquals( 2, listener.dataLength ); 386 assertEquals( 1, listener.startedCount ); 387 assertTrue( "Count: " + listener.progressedCount, listener.progressedCount > 0 ); 388 assertEquals( "OK", fs.get( "some space.txt" ) ); 389 } 390 391 @Test 392 public void testPut_FileHandleLeak() 393 throws Exception 394 { 395 for ( int i = 0; i < 100; i++ ) 396 { 397 File src = TestFileUtils.createTempFile( "upload" ); 398 transporter.put( new PutTask( URI.create( "file.txt" ) ).setDataFile( src ) ); 399 assertTrue( i + ", " + src.getAbsolutePath(), src.delete() ); 400 } 401 } 402 403 @Test 404 public void testPut_Closed() 405 throws Exception 406 { 407 transporter.close(); 408 try 409 { 410 transporter.put( new PutTask( URI.create( "missing.txt" ) ) ); 411 fail( "Expected error" ); 412 } 413 catch ( IllegalStateException e ) 414 { 415 assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) ); 416 } 417 } 418 419 @Test 420 public void testPut_StartCancelled() 421 throws Exception 422 { 423 RecordingTransportListener listener = new RecordingTransportListener(); 424 listener.cancelStart = true; 425 PutTask task = new PutTask( URI.create( "file.txt" ) ).setListener( listener ).setDataString( "upload" ); 426 transporter.put( task ); 427 assertEquals( 1, listener.startedCount ); 428 } 429 430 @Test 431 public void testPut_ProgressCancelled() 432 throws Exception 433 { 434 RecordingTransportListener listener = new RecordingTransportListener(); 435 listener.cancelProgress = true; 436 PutTask task = new PutTask( URI.create( "file.txt" ) ).setListener( listener ).setDataString( "upload" ); 437 try 438 { 439 transporter.put( task ); 440 fail( "Expected error" ); 441 } 442 catch ( TransferCancelledException e ) 443 { 444 assertEquals( Transporter.ERROR_OTHER, transporter.classify( e ) ); 445 } 446 assertEquals( 0, listener.dataOffset ); 447 assertEquals( 6, listener.dataLength ); 448 assertEquals( 1, listener.startedCount ); 449 assertEquals( 1, listener.progressedCount ); 450 } 451 452 @Test( expected = NoTransporterException.class ) 453 public void testInit_BadProtocol() 454 throws Exception 455 { 456 newTransporter( "bad:/void" ); 457 } 458 459 @Test 460 public void testInit_CaseInsensitiveProtocol() 461 throws Exception 462 { 463 newTransporter( "mem:/void" ); 464 newTransporter( "MEM:/void" ); 465 newTransporter( "mEm:/void" ); 466 } 467 468 @Test 469 public void testInit_Configuration() 470 throws Exception 471 { 472 session.setConfigProperty( "aether.connector.wagon.config.test", "passed" ); 473 newTransporter( "mem://" + id + "?config=passed" ); 474 transporter.peek( new PeekTask( URI.create( "file.txt" ) ) ); 475 } 476 477 @Test 478 public void testInit_UserAgent() 479 throws Exception 480 { 481 session.setConfigProperty( ConfigurationProperties.USER_AGENT, "Test/1.0" ); 482 newTransporter( "mem://" + id + "?userAgent=Test/1.0" ); 483 transporter.peek( new PeekTask( URI.create( "file.txt" ) ) ); 484 } 485 486 @Test 487 public void testInit_Timeout() 488 throws Exception 489 { 490 session.setConfigProperty( ConfigurationProperties.REQUEST_TIMEOUT, "12345678" ); 491 newTransporter( "mem://" + id + "?requestTimeout=12345678" ); 492 transporter.peek( new PeekTask( URI.create( "file.txt" ) ) ); 493 } 494 495 @Test 496 public void testInit_ServerAuth() 497 throws Exception 498 { 499 String url = 500 "mem://" + id + "?serverUsername=testuser&serverPassword=testpass" 501 + "&serverPrivateKey=testkey&serverPassphrase=testphrase"; 502 Authentication auth = 503 new AuthenticationBuilder().addUsername( "testuser" ).addPassword( "testpass" ).addPrivateKey( "testkey", 504 "testphrase" ).build(); 505 RemoteRepository repo = 506 new RemoteRepository.Builder( "test", "default", url ).setAuthentication( auth ).build(); 507 newTransporter( repo ); 508 transporter.peek( new PeekTask( URI.create( "file.txt" ) ) ); 509 } 510 511 @Test 512 public void testInit_Proxy() 513 throws Exception 514 { 515 String url = "mem://" + id + "?proxyHost=testhost&proxyPort=8888"; 516 RemoteRepository repo = 517 new RemoteRepository.Builder( "test", "default", url ).setProxy( new Proxy( "http", "testhost", 8888 ) ).build(); 518 newTransporter( repo ); 519 transporter.peek( new PeekTask( URI.create( "file.txt" ) ) ); 520 } 521 522 @Test 523 public void testInit_ProxyAuth() 524 throws Exception 525 { 526 String url = "mem://" + id + "?proxyUsername=testuser&proxyPassword=testpass"; 527 Authentication auth = new AuthenticationBuilder().addUsername( "testuser" ).addPassword( "testpass" ).build(); 528 RemoteRepository repo = 529 new RemoteRepository.Builder( "test", "default", url ).setProxy( new Proxy( "http", "testhost", 8888, auth ) ).build(); 530 newTransporter( repo ); 531 transporter.peek( new PeekTask( URI.create( "file.txt" ) ) ); 532 } 533 534}