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