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