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