001package org.apache.maven.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 org.apache.maven.wagon.authentication.AuthenticationException; 023import org.apache.maven.wagon.authentication.AuthenticationInfo; 024import org.apache.maven.wagon.authorization.AuthorizationException; 025import org.apache.maven.wagon.events.TransferEvent; 026import org.apache.maven.wagon.events.TransferListener; 027import org.apache.maven.wagon.observers.ChecksumObserver; 028import org.apache.maven.wagon.observers.Debug; 029import org.apache.maven.wagon.repository.Repository; 030import org.apache.maven.wagon.repository.RepositoryPermissions; 031import org.apache.maven.wagon.resource.Resource; 032import org.codehaus.plexus.PlexusTestCase; 033import org.codehaus.plexus.util.FileUtils; 034import org.easymock.IAnswer; 035import org.junit.Assume; 036 037// CHECKSTYLE_OFF: AvoidStarImport 038import static org.easymock.EasyMock.*; 039//CHECKSTYLE_ON: AvoidStarImport 040 041import org.slf4j.Logger; 042import org.slf4j.LoggerFactory; 043 044import java.io.File; 045import java.io.IOException; 046import java.nio.charset.StandardCharsets; 047import java.security.NoSuchAlgorithmException; 048import java.text.SimpleDateFormat; 049import java.util.ArrayList; 050import java.util.Collections; 051import java.util.List; 052 053/** 054 * @author <a href="mailto:jason@maven.org">Jason van Zyl</a> 055 */ 056public abstract class WagonTestCase 057 extends PlexusTestCase 058{ 059 protected static Logger logger = LoggerFactory.getLogger( WagonTestCase.class ); 060 061 062 static final class ProgressAnswer implements IAnswer 063 { 064 private int size; 065 066 public Object answer() throws Throwable 067 { 068 int length = (Integer) getCurrentArguments()[2]; 069 size += length; 070 return null; 071 } 072 073 public int getSize() 074 { 075 return size; 076 } 077 } 078 079 protected static final String TEST_CONTENT = "test-resource.txt\n"; 080 081 protected static final String TEST_CKSUM = cksum( TEST_CONTENT ); 082 083 protected static final String POM = "pom.xml"; 084 085 protected Repository localRepository; 086 087 protected Repository testRepository; 088 089 protected String localRepositoryPath; 090 091 protected File sourceFile; 092 093 protected File destFile; 094 095 protected String resource; 096 097 protected boolean testSkipped; 098 099 protected File artifactSourceFile; 100 101 protected File artifactDestFile; 102 103 protected ChecksumObserver checksumObserver; 104 105 protected TransferListener mockTransferListener; 106 107 // ---------------------------------------------------------------------- 108 // Constructors 109 // ---------------------------------------------------------------------- 110 111 protected void setUp() 112 throws Exception 113 { 114 checksumObserver = new ChecksumObserver(); 115 116 mockTransferListener = createMock( TransferListener.class ); 117 118 super.setUp(); 119 } 120 121 // ---------------------------------------------------------------------- 122 // Methods that should be provided by subclasses for proper testing 123 // ---------------------------------------------------------------------- 124 125 /** 126 * URL of the repository. For a complete test it should point to a non existing folder so we also check for the 127 * creation of new folders in the remote site. <p/> return the URL of the repository as specified by Wagon syntax 128 */ 129 protected abstract String getTestRepositoryUrl() 130 throws IOException; 131 132 /** 133 * Protocol id of the Wagon to use, eg. <code>scp</code>, <code>ftp</code> 134 * 135 * @return the protocol id 136 */ 137 protected abstract String getProtocol(); 138 139 // ---------------------------------------------------------------------- 140 // 1. Create a local file repository which mimic a users local file 141 // Repository. 142 // 143 // 2. Create a test repository for the type of wagon we are testing. So, 144 // for example, for testing the file wagon we might have a test 145 // repository url of file://${basedir}/target/file-repository. 146 // ---------------------------------------------------------------------- 147 148 protected void setupRepositories() 149 throws Exception 150 { 151 resource = "test-resource"; 152 153 // ---------------------------------------------------------------------- 154 // Create the test repository for the wagon we are testing. 155 // ---------------------------------------------------------------------- 156 157 testRepository = new Repository(); 158 159 testRepository.setUrl( getTestRepositoryUrl() ); 160 161 testRepository.setPermissions( getPermissions() ); 162 163 // ---------------------------------------------------------------------- 164 // Create a test local repository. 165 // ---------------------------------------------------------------------- 166 167 File file = FileTestUtils.createDir( "local-repository" ); 168 localRepositoryPath = file.getPath(); 169 170 localRepository = createFileRepository( file.toPath().toUri().toASCIIString() ); 171 172 message( "Local repository: " + localRepository ); 173 174 File f = new File( localRepositoryPath ); 175 176 if ( !f.exists() ) 177 { 178 f.mkdirs(); 179 } 180 } 181 182 protected void customizeContext() 183 throws Exception 184 { 185 getContainer().addContextValue( "test.repository", localRepositoryPath ); 186 } 187 188 protected void setupWagonTestingFixtures() 189 throws Exception 190 { 191 } 192 193 protected void tearDownWagonTestingFixtures() 194 throws Exception 195 { 196 } 197 198 // ---------------------------------------------------------------------- 199 // 200 // ---------------------------------------------------------------------- 201 202 protected AuthenticationInfo getAuthInfo() 203 { 204 return new AuthenticationInfo(); 205 } 206 207 protected RepositoryPermissions getPermissions() 208 { 209 return new RepositoryPermissions(); 210 } 211 212 protected Wagon getWagon() 213 throws Exception 214 { 215 Wagon wagon = (Wagon) lookup( Wagon.ROLE, getProtocol() ); 216 217 Debug debug = new Debug(); 218 219 wagon.addSessionListener( debug ); 220 221 wagon.addTransferListener( debug ); 222 223 return wagon; 224 } 225 226 /** 227 * @param cmd the executable to run, not null. 228 * @return <code>true</code> 229 */ 230 public static boolean isSystemCmd( String cmd ) 231 { 232 try 233 { 234 Runtime.getRuntime().exec( cmd ); 235 236 return true; 237 } 238 catch ( IOException e ) 239 { 240 return false; 241 } 242 } 243 244 protected void message( String message ) 245 { 246 logger.info( message ); 247 } 248 249 // ---------------------------------------------------------------------- 250 // 251 // ---------------------------------------------------------------------- 252 253 public void testWagon() 254 throws Exception 255 { 256 setupWagonTestingFixtures(); 257 258 setupRepositories(); 259 260 fileRoundTripTesting(); 261 262 tearDownWagonTestingFixtures(); 263 } 264 265 public void testWagonGetIfNewerIsNewer() 266 throws Exception 267 { 268 if ( supportsGetIfNewer() ) 269 { 270 setupWagonTestingFixtures(); 271 setupRepositories(); 272 int expectedSize = putFile(); 273 // CHECKSTYLE_OFF: MagicNumber 274 getIfNewer( getExpectedLastModifiedOnGet( testRepository, new Resource( resource ) ) + 30000, false, 275 expectedSize ); 276 // CHECKSTYLE_ON: MagicNumber 277 } 278 } 279 280 @Override 281 protected void runTest() 282 throws Throwable 283 { 284 if ( !testSkipped ) 285 { 286 super.runTest(); 287 } 288 } 289 290 protected boolean supportsGetIfNewer() 291 { 292 return true; 293 } 294 295 296 public void testWagonGetIfNewerIsSame() 297 throws Exception 298 { 299 if ( supportsGetIfNewer() ) 300 { 301 setupWagonTestingFixtures(); 302 setupRepositories(); 303 int expectedSize = putFile(); 304 getIfNewer( getExpectedLastModifiedOnGet( testRepository, new Resource( resource ) ), false, expectedSize ); 305 } 306 } 307 308 public void testWagonGetIfNewerIsOlder() 309 throws Exception 310 { 311 if ( supportsGetIfNewer() ) 312 { 313 setupWagonTestingFixtures(); 314 setupRepositories(); 315 int expectedSize = putFile(); 316 getIfNewer( new SimpleDateFormat( "yyyy-MM-dd" ).parse( "2006-01-01" ).getTime(), true, expectedSize ); 317 } 318 } 319 320 private void getIfNewer( long timestamp, boolean expectedResult, int expectedSize ) 321 throws Exception 322 { 323 Wagon wagon = getWagon(); 324 325 ProgressAnswer progressAnswer = setupGetIfNewerTest( wagon, expectedResult, expectedSize ); 326 327 connectWagon( wagon ); 328 329 boolean result = wagon.getIfNewer( this.resource, destFile, timestamp ); 330 assertEquals( expectedResult, result ); 331 332 disconnectWagon( wagon ); 333 334 assertGetIfNewerTest( progressAnswer, expectedResult, expectedSize ); 335 336 tearDownWagonTestingFixtures(); 337 } 338 339 protected ProgressAnswer setupGetIfNewerTest( Wagon wagon, boolean expectedResult, int expectedSize ) 340 throws NoSuchAlgorithmException, IOException 341 { 342 checksumObserver = new ChecksumObserver(); 343 344 destFile = FileTestUtils.createUniqueFile( getName(), getName() ); 345 destFile.delete(); 346 assertFalse( destFile.exists() ); 347 destFile.deleteOnExit(); 348 349 ProgressAnswer progressAnswer = null; 350 if ( expectedResult ) 351 { 352 progressAnswer = replaceMockForGet( wagon, expectedSize ); 353 } 354 else 355 { 356 replaceMockForSkippedGetIfNewer( wagon, expectedSize ); 357 } 358 return progressAnswer; 359 } 360 361 protected void assertGetIfNewerTest( ProgressAnswer progressAnswer, boolean expectedResult, 362 int expectedSize ) 363 throws IOException 364 { 365 if ( expectedResult ) 366 { 367 verifyMock( progressAnswer, expectedSize ); 368 369 assertNotNull( "check checksum is not null", checksumObserver.getActualChecksum() ); 370 371 assertEquals( "compare checksums", TEST_CKSUM, 372 checksumObserver.getActualChecksum() ); 373 374 // Now compare the contents of the artifact that was placed in 375 // the repository with the contents of the artifact that was 376 // retrieved from the repository. 377 378 String sourceContent = FileUtils.fileRead( sourceFile ); 379 String destContent = FileUtils.fileRead( destFile ); 380 assertEquals( sourceContent, destContent ); 381 } 382 else 383 { 384 verify( mockTransferListener ); 385 386 reset( mockTransferListener ); 387 388 assertNull( "check checksum is null", checksumObserver.getActualChecksum() ); 389 390 assertFalse( destFile.exists() ); 391 } 392 } 393 394 395 private void replaceMockForSkippedGetIfNewer( Wagon wagon, int expectedSize ) 396 { 397 Resource resource = new Resource( this.resource ); 398 mockTransferListener.transferInitiated( 399 createTransferEvent( wagon, resource, TransferEvent.TRANSFER_INITIATED, TransferEvent.REQUEST_GET, 400 destFile ) ); 401 resource = new Resource( this.resource ); 402 resource.setContentLength( getExpectedContentLengthOnGet( expectedSize ) ); 403 resource.setLastModified( getExpectedLastModifiedOnGet( testRepository, resource ) ); 404 // TODO: transfer skipped event? 405 // mockTransferListener.transferSkipped( createTransferEvent( wagon, resource, TransferEvent.TRANSFER_STARTED, 406 // TransferEvent.REQUEST_GET, destFile ) ); 407 408 mockTransferListener.debug( anyString() ); 409 expectLastCall().anyTimes(); 410 411 replay( mockTransferListener ); 412 } 413 414 public void testWagonPutDirectory() 415 throws Exception 416 { 417 setupWagonTestingFixtures(); 418 419 setupRepositories(); 420 421 Wagon wagon = getWagon(); 422 423 if ( wagon.supportsDirectoryCopy() ) 424 { 425 sourceFile = new File( FileTestUtils.getTestOutputDir(), "directory-copy" ); 426 427 FileUtils.deleteDirectory( sourceFile ); 428 429 writeTestFile( "test-resource-1.txt" ); 430 writeTestFile( "a/test-resource-2.txt" ); 431 writeTestFile( "a/b/test-resource-3.txt" ); 432 writeTestFile( "c/test-resource-4.txt" ); 433 writeTestFile( "d/e/f/test-resource-5.txt" ); 434 435 wagon.connect( testRepository, getAuthInfo() ); 436 437 wagon.putDirectory( sourceFile, "directory-copy" ); 438 439 destFile = FileTestUtils.createUniqueFile( getName(), getName() ); 440 441 destFile.deleteOnExit(); 442 443 wagon.get( "directory-copy/test-resource-1.txt", destFile ); 444 wagon.get( "directory-copy/a/test-resource-2.txt", destFile ); 445 wagon.get( "directory-copy/a/b/test-resource-3.txt", destFile ); 446 wagon.get( "directory-copy/c/test-resource-4.txt", destFile ); 447 wagon.get( "directory-copy/d/e/f/test-resource-5.txt", destFile ); 448 449 wagon.disconnect(); 450 } 451 452 tearDownWagonTestingFixtures(); 453 } 454 455 /** 456 * Test for putting a directory with a destination that multiple directories deep, all of which haven't been 457 * created. 458 * 459 * @throws Exception 460 * @since 1.0-beta-2 461 */ 462 public void testWagonPutDirectoryDeepDestination() 463 throws Exception 464 { 465 setupWagonTestingFixtures(); 466 467 setupRepositories(); 468 469 Wagon wagon = getWagon(); 470 471 if ( wagon.supportsDirectoryCopy() ) 472 { 473 sourceFile = new File( FileTestUtils.getTestOutputDir(), "deep0/deep1/deep2" ); 474 475 FileUtils.deleteDirectory( sourceFile ); 476 477 writeTestFile( "test-resource-1.txt" ); 478 writeTestFile( "a/test-resource-2.txt" ); 479 writeTestFile( "a/b/test-resource-3.txt" ); 480 writeTestFile( "c/test-resource-4.txt" ); 481 writeTestFile( "d/e/f/test-resource-5.txt" ); 482 483 wagon.connect( testRepository, getAuthInfo() ); 484 485 wagon.putDirectory( sourceFile, "deep0/deep1/deep2" ); 486 487 destFile = FileTestUtils.createUniqueFile( getName(), getName() ); 488 489 destFile.deleteOnExit(); 490 491 wagon.get( "deep0/deep1/deep2/test-resource-1.txt", destFile ); 492 wagon.get( "deep0/deep1/deep2/a/test-resource-2.txt", destFile ); 493 wagon.get( "deep0/deep1/deep2/a/b/test-resource-3.txt", destFile ); 494 wagon.get( "deep0/deep1/deep2/c/test-resource-4.txt", destFile ); 495 wagon.get( "deep0/deep1/deep2/d/e/f/test-resource-5.txt", destFile ); 496 497 wagon.disconnect(); 498 } 499 500 tearDownWagonTestingFixtures(); 501 } 502 503 /** 504 * Test that when putting a directory that already exists new files get also copied 505 * 506 * @throws Exception 507 * @since 1.0-beta-1 508 */ 509 public void testWagonPutDirectoryWhenDirectoryAlreadyExists() 510 throws Exception 511 { 512 513 final String dirName = "directory-copy-existing"; 514 515 final String resourceToCreate = "test-resource-1.txt"; 516 517 final String[] resources = { "a/test-resource-2.txt", "a/b/test-resource-3.txt", "c/test-resource-4.txt" }; 518 519 setupWagonTestingFixtures(); 520 521 setupRepositories(); 522 523 Wagon wagon = getWagon(); 524 525 if ( wagon.supportsDirectoryCopy() ) 526 { 527 sourceFile = new File( FileTestUtils.getTestOutputDir(), dirName ); 528 529 FileUtils.deleteDirectory( sourceFile ); 530 531 createDirectory( wagon, resourceToCreate, dirName ); 532 533 for ( String resource : resources ) 534 { 535 writeTestFile( resource ); 536 } 537 538 wagon.connect( testRepository, getAuthInfo() ); 539 540 wagon.putDirectory( sourceFile, dirName ); 541 542 List<String> resourceNames = new ArrayList<String>( resources.length + 1 ); 543 544 resourceNames.add( dirName + "/" + resourceToCreate ); 545 for ( String resource : resources ) 546 { 547 resourceNames.add( dirName + "/" + resource ); 548 } 549 550 assertResourcesAreInRemoteSide( wagon, resourceNames ); 551 552 wagon.disconnect(); 553 } 554 555 tearDownWagonTestingFixtures(); 556 } 557 558 /** 559 * Test that when putting a directory that already exists new files get also copied and destination is "." 560 * 561 * @throws Exception 562 * @since 1.0-beta-1 563 */ 564 public void testWagonPutDirectoryForDot() 565 throws Exception 566 { 567 final String resourceToCreate = "test-resource-1.txt"; 568 569 final String[] resources = { "a/test-resource-2.txt", "a/b/test-resource-3.txt", "c/test-resource-4.txt" }; 570 571 setupWagonTestingFixtures(); 572 573 setupRepositories(); 574 575 Wagon wagon = getWagon(); 576 577 if ( wagon.supportsDirectoryCopy() ) 578 { 579 sourceFile = new File( FileTestUtils.getTestOutputDir(), "dot-repo" ); 580 581 FileUtils.deleteDirectory( sourceFile ); 582 583 createDirectory( wagon, resourceToCreate, "." ); 584 585 for ( String resource : resources ) 586 { 587 writeTestFile( resource ); 588 } 589 590 wagon.connect( testRepository, getAuthInfo() ); 591 592 wagon.putDirectory( sourceFile, "." ); 593 594 List<String> resourceNames = new ArrayList<String>( resources.length + 1 ); 595 596 resourceNames.add( resourceToCreate ); 597 Collections.addAll( resourceNames, resources ); 598 599 assertResourcesAreInRemoteSide( wagon, resourceNames ); 600 601 wagon.disconnect(); 602 } 603 604 tearDownWagonTestingFixtures(); 605 } 606 607 /** 608 * Create a directory with a resource and check that the other ones don't exist 609 * 610 * @param wagon 611 * @param resourceToCreate name of the resource to be created 612 * @param dirName directory name to create 613 * @throws Exception 614 */ 615 protected void createDirectory( Wagon wagon, String resourceToCreate, String dirName ) 616 throws Exception 617 { 618 writeTestFile( resourceToCreate ); 619 } 620 621 protected void assertResourcesAreInRemoteSide( Wagon wagon, List<String> resourceNames ) 622 throws IOException, TransferFailedException, ResourceDoesNotExistException, AuthorizationException 623 { 624 for ( String resourceName : resourceNames ) 625 { 626 File destFile = FileTestUtils.createUniqueFile( getName(), resourceName ); 627 628 destFile.deleteOnExit(); 629 630 wagon.get( resourceName, destFile ); 631 } 632 } 633 634 /** 635 * Assert that a resource does not exist in the remote wagon system 636 * 637 * @param wagon wagon to get the resource from 638 * @param resourceName name of the resource 639 * @throws IOException if a temp file can't be created 640 * @throws AuthorizationException 641 * @throws TransferFailedException 642 * @since 1.0-beta-1 643 */ 644 protected void assertNotExists( Wagon wagon, String resourceName ) 645 throws IOException, TransferFailedException, AuthorizationException 646 { 647 File tmpFile = File.createTempFile( "wagon", null ); 648 try 649 { 650 wagon.get( resourceName, tmpFile ); 651 fail( "Resource exists: " + resourceName ); 652 } 653 catch ( ResourceDoesNotExistException e ) 654 { 655 // ok 656 } 657 finally 658 { 659 tmpFile.delete(); 660 } 661 } 662 663 private void writeTestFile( String child ) 664 throws IOException 665 { 666 File dir = new File( sourceFile, child ); 667 dir.getParentFile().mkdirs(); 668 FileUtils.fileWrite( dir.getAbsolutePath(), child ); 669 } 670 671 public void testFailedGet() 672 throws Exception 673 { 674 setupWagonTestingFixtures(); 675 676 setupRepositories(); 677 678 message( "Getting test artifact from test repository " + testRepository ); 679 680 Wagon wagon = getWagon(); 681 682 wagon.addTransferListener( checksumObserver ); 683 684 wagon.connect( testRepository, getAuthInfo() ); 685 686 destFile = FileTestUtils.createUniqueFile( getName(), getName() ); 687 688 destFile.deleteOnExit(); 689 690 try 691 { 692 wagon.get( "fubar.txt", destFile ); 693 fail( "File was found when it shouldn't have been" ); 694 } 695 catch ( ResourceDoesNotExistException e ) 696 { 697 // expected 698 assertTrue( true ); 699 } 700 finally 701 { 702 wagon.removeTransferListener( checksumObserver ); 703 704 wagon.disconnect(); 705 706 tearDownWagonTestingFixtures(); 707 } 708 } 709 710 public void testFailedGetIfNewer() 711 throws Exception 712 { 713 if ( supportsGetIfNewer() ) 714 { 715 setupWagonTestingFixtures(); 716 setupRepositories(); 717 message( "Getting test artifact from test repository " + testRepository ); 718 Wagon wagon = getWagon(); 719 wagon.addTransferListener( checksumObserver ); 720 wagon.connect( testRepository, getAuthInfo() ); 721 destFile = FileTestUtils.createUniqueFile( getName(), getName() ); 722 destFile.deleteOnExit(); 723 try 724 { 725 wagon.getIfNewer( "fubar.txt", destFile, 0 ); 726 fail( "File was found when it shouldn't have been" ); 727 } 728 catch ( ResourceDoesNotExistException e ) 729 { 730 // expected 731 assertTrue( true ); 732 } 733 finally 734 { 735 wagon.removeTransferListener( checksumObserver ); 736 737 wagon.disconnect(); 738 739 tearDownWagonTestingFixtures(); 740 } 741 } 742 } 743 744 /** 745 * Test {@link Wagon#getFileList(String)}. 746 * 747 * @throws Exception 748 * @since 1.0-beta-2 749 */ 750 public void testWagonGetFileList() 751 throws Exception 752 { 753 setupWagonTestingFixtures(); 754 755 setupRepositories(); 756 757 String dirName = "file-list"; 758 759 String filenames[] = 760 new String[]{ "test-resource.txt", "test-resource.pom", "test-resource b.txt", "more-resources.dat", 761 ".index.txt" }; 762 763 for ( String filename : filenames ) 764 { 765 putFile( dirName + "/" + filename, dirName + "/" + filename, filename + "\n" ); 766 } 767 768 Wagon wagon = getWagon(); 769 770 wagon.connect( testRepository, getAuthInfo() ); 771 772 try 773 { 774 List<String> list = wagon.getFileList( dirName ); 775 assertNotNull( "file list should not be null.", list ); 776 assertTrue( "file list should contain more items (actually contains '" + list + "').", 777 list.size() >= filenames.length ); 778 779 for ( String filename : filenames ) 780 { 781 assertTrue( "Filename '" + filename + "' should be in list.", list.contains( filename ) ); 782 } 783 784 // WAGON-250 785 list = wagon.getFileList( "" ); 786 assertNotNull( "file list should not be null.", list ); 787 assertTrue( "file list should contain items (actually contains '" + list + "').", !list.isEmpty() ); 788 assertTrue( list.contains( "file-list/" ) ); 789 assertFalse( list.contains( "file-list" ) ); 790 assertFalse( list.contains( "." ) ); 791 assertFalse( list.contains( ".." ) ); 792 assertFalse( list.contains( "./" ) ); 793 assertFalse( list.contains( "../" ) ); 794 } 795 catch ( UnsupportedOperationException e ) 796 { 797 // Some providers don't support this 798 Assume.assumeFalse( false ); 799 } 800 finally 801 { 802 wagon.disconnect(); 803 804 tearDownWagonTestingFixtures(); 805 } 806 } 807 808 /** 809 * Test {@link Wagon#getFileList(String)} when the directory does not exist. 810 * 811 * @throws Exception 812 * @since 1.0-beta-2 813 */ 814 public void testWagonGetFileListWhenDirectoryDoesNotExist() 815 throws Exception 816 { 817 setupWagonTestingFixtures(); 818 819 setupRepositories(); 820 821 String dirName = "file-list-unexisting"; 822 823 Wagon wagon = getWagon(); 824 825 wagon.connect( testRepository, getAuthInfo() ); 826 827 try 828 { 829 wagon.getFileList( dirName ); 830 fail( "getFileList on unexisting directory must throw ResourceDoesNotExistException" ); 831 } 832 catch ( ResourceDoesNotExistException e ) 833 { 834 // expected 835 } 836 catch ( UnsupportedOperationException e ) 837 { 838 // Some providers don't support this 839 Assume.assumeFalse( false ); 840 } 841 finally 842 { 843 wagon.disconnect(); 844 845 tearDownWagonTestingFixtures(); 846 } 847 } 848 849 /** 850 * Test for an existing resource. 851 * 852 * @throws Exception 853 * @since 1.0-beta-2 854 */ 855 public void testWagonResourceExists() 856 throws Exception 857 { 858 setupWagonTestingFixtures(); 859 860 setupRepositories(); 861 862 Wagon wagon = getWagon(); 863 864 putFile(); 865 866 wagon.connect( testRepository, getAuthInfo() ); 867 868 assertTrue( sourceFile.getName() + " does not exist", wagon.resourceExists( sourceFile.getName() ) ); 869 870 wagon.disconnect(); 871 872 tearDownWagonTestingFixtures(); 873 } 874 875 /** 876 * Test for an invalid resource. 877 * 878 * @throws Exception 879 * @since 1.0-beta-2 880 */ 881 public void testWagonResourceNotExists() 882 throws Exception 883 { 884 setupWagonTestingFixtures(); 885 886 setupRepositories(); 887 888 Wagon wagon = getWagon(); 889 890 wagon.connect( testRepository, getAuthInfo() ); 891 892 assertFalse( wagon.resourceExists( "a/bad/resource/name/that/should/not/exist.txt" ) ); 893 894 wagon.disconnect(); 895 896 tearDownWagonTestingFixtures(); 897 } 898 899 // ---------------------------------------------------------------------- 900 // File <--> File round trip testing 901 // ---------------------------------------------------------------------- 902 // We are testing taking a file, our sourcefile, and placing it into the 903 // test repository that we have setup. 904 // ---------------------------------------------------------------------- 905 906 protected void putFile( String resourceName, String testFileName, String content ) 907 throws Exception 908 { 909 sourceFile = new File( FileTestUtils.getTestOutputDir(), testFileName ); 910 sourceFile.getParentFile().mkdirs(); 911 FileUtils.fileWrite( sourceFile.getAbsolutePath(), content ); 912 913 Wagon wagon = getWagon(); 914 915 ProgressAnswer progressAnswer = replayMockForPut( resourceName, content, wagon ); 916 917 message( "Putting test artifact: " + resourceName + " into test repository " + testRepository ); 918 919 connectWagon( wagon ); 920 921 wagon.put( sourceFile, resourceName ); 922 923 disconnectWagon( wagon ); 924 925 verifyMock( progressAnswer, content.length() ); 926 } 927 928 protected ProgressAnswer replayMockForPut( String resourceName, String content, Wagon wagon ) 929 { 930 Resource resource = new Resource( resourceName ); 931 mockTransferListener.transferInitiated( 932 createTransferEvent( wagon, resource, TransferEvent.TRANSFER_INITIATED, TransferEvent.REQUEST_PUT, 933 sourceFile ) ); 934 resource = new Resource( resourceName ); 935 resource.setContentLength( content.length() ); 936 resource.setLastModified( sourceFile.lastModified() ); 937 mockTransferListener.transferStarted( 938 createTransferEvent( wagon, resource, TransferEvent.TRANSFER_STARTED, TransferEvent.REQUEST_PUT, 939 sourceFile ) ); 940 mockTransferListener.transferProgress( 941 eq( createTransferEvent( wagon, resource, TransferEvent.TRANSFER_PROGRESS, TransferEvent.REQUEST_PUT, 942 sourceFile ) ), anyObject( byte[].class ), anyInt() ); 943 ProgressAnswer progressAnswer = new ProgressAnswer(); 944 expectLastCall().andStubAnswer( progressAnswer ); 945 946 mockTransferListener.debug( anyString() ); 947 expectLastCall().anyTimes(); 948 949 mockTransferListener.transferCompleted( 950 createTransferEvent( wagon, resource, TransferEvent.TRANSFER_COMPLETED, TransferEvent.REQUEST_PUT, 951 sourceFile ) ); 952 953 replay( mockTransferListener ); 954 return progressAnswer; 955 } 956 957 protected TransferEvent createTransferEvent( Wagon wagon, Resource resource, int eventType, int requestType, 958 File file ) 959 { 960 TransferEvent transferEvent = new TransferEvent( wagon, resource, eventType, requestType ); 961 transferEvent.setLocalFile( file ); 962 return transferEvent; 963 } 964 965 protected int putFile() 966 throws Exception 967 { 968 String content = TEST_CONTENT; 969 putFile( resource, "test-resource", content ); 970 return content.length(); 971 } 972 973 protected void getFile( int expectedSize ) 974 throws Exception 975 { 976 destFile = FileTestUtils.createUniqueFile( getName(), getName() ); 977 destFile.deleteOnExit(); 978 979 Wagon wagon = getWagon(); 980 981 ProgressAnswer progressAnswer = replaceMockForGet( wagon, expectedSize ); 982 983 message( "Getting test artifact from test repository " + testRepository ); 984 985 connectWagon( wagon ); 986 987 wagon.get( this.resource, destFile ); 988 989 disconnectWagon( wagon ); 990 991 verifyMock( progressAnswer, expectedSize ); 992 } 993 994 995 protected void verifyMock( ProgressAnswer progressAnswer, int length ) 996 { 997 verify( mockTransferListener ); 998 999 assertEquals( length, progressAnswer.getSize() ); 1000 1001 reset( mockTransferListener ); 1002 } 1003 1004 protected void disconnectWagon( Wagon wagon ) 1005 throws ConnectionException 1006 { 1007 wagon.removeTransferListener( mockTransferListener ); 1008 1009 wagon.removeTransferListener( checksumObserver ); 1010 1011 wagon.disconnect(); 1012 } 1013 1014 protected void connectWagon( Wagon wagon ) 1015 throws ConnectionException, AuthenticationException 1016 { 1017 wagon.addTransferListener( checksumObserver ); 1018 1019 wagon.addTransferListener( mockTransferListener ); 1020 1021 wagon.connect( testRepository, getAuthInfo() ); 1022 } 1023 1024 /** 1025 * 1026 * some test (mock on transfertprogress call) relies on the fact that InputStream #read(byte[] b, int off, int len) 1027 * read all bytes. But javadoc says: "" 1028 */ 1029 protected boolean assertOnTransferProgress() 1030 { 1031 return false; 1032 } 1033 1034 protected ProgressAnswer replaceMockForGet( Wagon wagon, int expectedSize ) 1035 { 1036 Resource resource = new Resource( this.resource ); 1037 mockTransferListener.transferInitiated( 1038 createTransferEvent( wagon, resource, TransferEvent.TRANSFER_INITIATED, TransferEvent.REQUEST_GET, 1039 destFile ) ); 1040 resource = new Resource( this.resource ); 1041 resource.setContentLength( getExpectedContentLengthOnGet( expectedSize ) ); 1042 resource.setLastModified( getExpectedLastModifiedOnGet( testRepository, resource ) ); 1043 TransferEvent te = 1044 createTransferEvent( wagon, resource, TransferEvent.TRANSFER_STARTED, TransferEvent.REQUEST_GET, null ); 1045 mockTransferListener.transferStarted( te ); 1046 mockTransferListener.transferProgress( 1047 eq( new TransferEvent( wagon, resource, TransferEvent.TRANSFER_PROGRESS, TransferEvent.REQUEST_GET ) ), 1048 anyObject( byte[].class ), anyInt() ); 1049 1050 ProgressAnswer progressAnswer = new ProgressAnswer(); 1051 1052 if ( assertOnTransferProgress() ) 1053 { 1054 expectLastCall().andAnswer( progressAnswer ); 1055 } 1056 else 1057 { 1058 expectLastCall().andAnswer( progressAnswer ); 1059 expectLastCall().anyTimes(); 1060 } 1061 mockTransferListener.debug( anyString() ); 1062 expectLastCall().anyTimes(); 1063 1064 mockTransferListener.transferCompleted( 1065 createTransferEvent( wagon, resource, TransferEvent.TRANSFER_COMPLETED, TransferEvent.REQUEST_GET, 1066 destFile ) ); 1067 1068 replay( mockTransferListener ); 1069 return progressAnswer; 1070 } 1071 1072 protected int getExpectedContentLengthOnGet( int expectedSize ) 1073 { 1074 return expectedSize; 1075 } 1076 1077 protected long getExpectedLastModifiedOnGet( Repository repository, Resource resource ) 1078 { 1079 // default implementation - prone to failing if the time between test file creation and completion of putFile() 1080 // cross the "second" boundary, causing the "remote" and local files to have different times. 1081 1082 return sourceFile.lastModified(); 1083 } 1084 1085 protected void fileRoundTripTesting() 1086 throws Exception 1087 { 1088 message( "File round trip testing ..." ); 1089 1090 int expectedSize = putFile(); 1091 1092 assertNotNull( "check checksum is not null", checksumObserver.getActualChecksum() ); 1093 1094 assertEquals( "compare checksums", TEST_CKSUM, checksumObserver.getActualChecksum() ); 1095 1096 checksumObserver = new ChecksumObserver(); 1097 1098 getFile( expectedSize ); 1099 1100 assertNotNull( "check checksum is not null", checksumObserver.getActualChecksum() ); 1101 1102 assertEquals( "compare checksums", TEST_CKSUM, checksumObserver.getActualChecksum() ); 1103 1104 // Now compare the conents of the artifact that was placed in 1105 // the repository with the contents of the artifact that was 1106 // retrieved from the repository. 1107 1108 String sourceContent = FileUtils.fileRead( sourceFile ); 1109 1110 String destContent = FileUtils.fileRead( destFile ); 1111 1112 assertEquals( sourceContent, destContent ); 1113 } 1114 1115 // ---------------------------------------------------------------------- 1116 // 1117 // ---------------------------------------------------------------------- 1118 1119 protected Repository createFileRepository( String url ) 1120 { 1121 File path = new File( url.substring( 7 ) ); 1122 1123 path.mkdirs(); 1124 1125 Repository repository = new Repository(); 1126 1127 repository.setUrl( url ); 1128 1129 return repository; 1130 } 1131 1132 protected static String cksum( String content ) 1133 { 1134 String checkSum; 1135 try 1136 { 1137 ChecksumObserver obs = new ChecksumObserver(); 1138 byte[] buf = content.getBytes( StandardCharsets.ISO_8859_1 ); 1139 obs.transferProgress( null, buf, buf.length ); 1140 obs.transferCompleted( null ); 1141 checkSum = obs.getActualChecksum(); 1142 } 1143 catch ( Exception e ) 1144 { 1145 checkSum = null; 1146 } 1147 return checkSum; 1148 } 1149 1150}