From 58463f598fc1149052c2e3672872ddf2b6228728 Mon Sep 17 00:00:00 2001 From: Brett Porter Date: Sun, 13 Aug 2006 02:22:06 +0000 Subject: [PATCH] [MRM-138] add more proxy tests git-svn-id: https://svn.apache.org/repos/asf/maven/repository-manager/trunk@431135 13f79535-47bb-0310-9956-ffa450edef68 --- .../configuration/ConfigurationStoreTest.java | 4 + maven-repository-proxy/pom.xml | 6 + .../proxy/DefaultProxyRequestHandler.java | 190 ++++++++------ .../proxy/ProxyRequestHandlerTest.java | 243 +++++++++++++++++- .../maven/repository/proxy/WagonDelegate.java | 157 +++++++++++ .../1.0/get-in-both-proxies-1.0.jar | 3 + .../1.0/get-in-both-proxies-1.0.jar | 3 + .../1.0/get-in-second-proxy-1.0.jar | 2 + .../proxy/ProxyRequestHandlerTest.xml | 25 ++ 9 files changed, 535 insertions(+), 98 deletions(-) create mode 100644 maven-repository-proxy/src/test/java/org/apache/maven/repository/proxy/WagonDelegate.java create mode 100644 maven-repository-proxy/src/test/repositories/proxied1/org/apache/maven/test/get-in-both-proxies/1.0/get-in-both-proxies-1.0.jar create mode 100644 maven-repository-proxy/src/test/repositories/proxied2/org/apache/maven/test/get-in-both-proxies/1.0/get-in-both-proxies-1.0.jar create mode 100644 maven-repository-proxy/src/test/repositories/proxied2/org/apache/maven/test/get-in-second-proxy/1.0/get-in-second-proxy-1.0.jar create mode 100644 maven-repository-proxy/src/test/resources/org/apache/maven/repository/proxy/ProxyRequestHandlerTest.xml diff --git a/maven-repository-configuration/src/test/java/org/apache/maven/repository/configuration/ConfigurationStoreTest.java b/maven-repository-configuration/src/test/java/org/apache/maven/repository/configuration/ConfigurationStoreTest.java index 0ab249758..34d350a68 100644 --- a/maven-repository-configuration/src/test/java/org/apache/maven/repository/configuration/ConfigurationStoreTest.java +++ b/maven-repository-configuration/src/test/java/org/apache/maven/repository/configuration/ConfigurationStoreTest.java @@ -26,6 +26,7 @@ import java.util.Properties; * Test the configuration store. * * @author Brett Porter + * @noinspection JavaDoc */ public class ConfigurationStoreTest extends PlexusTestCase @@ -130,6 +131,9 @@ public class ConfigurationStoreTest assertEquals( "check value", "index-path", configuration.getIndexPath() ); } + /** + * @noinspection JUnitTestMethodWithNoAssertions + */ public void testChangeListeners() throws Exception { diff --git a/maven-repository-proxy/pom.xml b/maven-repository-proxy/pom.xml index 5c0cd4515..1137c896e 100644 --- a/maven-repository-proxy/pom.xml +++ b/maven-repository-proxy/pom.xml @@ -42,6 +42,12 @@ org.apache.maven.wagon wagon-provider-api + + easymock + easymock + 1.2_Java1.3 + test + diff --git a/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/DefaultProxyRequestHandler.java b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/DefaultProxyRequestHandler.java index 3f4dc43db..5b000e413 100644 --- a/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/DefaultProxyRequestHandler.java +++ b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/DefaultProxyRequestHandler.java @@ -17,7 +17,6 @@ package org.apache.maven.repository.proxy; */ import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.manager.ChecksumFailedException; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; import org.apache.maven.repository.discovery.ArtifactDiscoverer; @@ -38,8 +37,8 @@ import java.io.File; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.util.Date; -import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -49,6 +48,7 @@ import java.util.Map; * @author Brett Porter * @plexus.component * @todo this currently duplicates a lot of the wagon manager, and doesn't do things like snapshot resolution, etc. + * The checksum handling is inconsistent with that of the wagon manager. * Should we have a more artifact based one? This will merge metadata so should behave correctly, and it is able to * correct some limitations of the wagon manager (eg, it can retrieve newer SNAPSHOT files without metadata) */ @@ -100,7 +100,7 @@ public class DefaultProxyRequestHandler public File getAlways( String path, List proxiedRepositories, ArtifactRepository managedRepository, ProxyInfo wagonProxy ) - throws ProxyException, ResourceDoesNotExistException + throws ResourceDoesNotExistException, ProxyException { File target = new File( managedRepository.getBasedir(), path ); @@ -114,68 +114,24 @@ public class DefaultProxyRequestHandler } else { - if ( path.endsWith( ".md5" ) || path.endsWith( ".sha1" ) ) + try { - // always read from the managed repository, no need to make remote request - } - else if ( path.endsWith( "maven-metadata.xml" ) ) - { - // TODO: this is not always! - if ( !target.exists() || isOutOfDate( repository.getRepository().getReleases(), target ) ) - { - getFileFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy, target ); - } - } - else - { - Artifact artifact = null; - try - { - artifact = defaultArtifactDiscoverer.buildArtifact( path ); - } - catch ( DiscovererException e ) - { - getLogger().debug( - "Failed to build artifact using default layout with message: " + e.getMessage() ); - } + get( path, target, repository, managedRepository, wagonProxy ); - if ( artifact == null ) + if ( !target.exists() ) { - try - { - artifact = legacyArtifactDiscoverer.buildArtifact( path ); - } - catch ( DiscovererException e ) - { - getLogger().debug( - "Failed to build artifact using legacy layout with message: " + e.getMessage() ); - } - } - - if ( artifact != null ) - { - getArtifactFromRepository( artifact, repository, managedRepository, wagonProxy, target ); + repository.addFailure( path ); } else { - // Some other unknown file in the repository, proxy as is - // TODO: this is not always! - if ( !target.exists() ) - { - getFileFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy, - target ); - } + // in case it previously failed and we've since found it + repository.clearFailure( path ); } } - - if ( !target.exists() ) + catch ( ProxyException e ) { repository.addFailure( path ); - } - else - { - // in case it previously failed and we've since found it - repository.clearFailure( path ); + throw e; } } } @@ -188,9 +144,65 @@ public class DefaultProxyRequestHandler return target; } + private void get( String path, File target, ProxiedArtifactRepository repository, + ArtifactRepository managedRepository, ProxyInfo wagonProxy ) + throws ProxyException + { + if ( path.endsWith( ".md5" ) || path.endsWith( ".sha1" ) ) + { + // always read from the managed repository, no need to make remote request + } + else if ( path.endsWith( "maven-metadata.xml" ) ) + { + // TODO: this is not always! + if ( !target.exists() || isOutOfDate( repository.getRepository().getReleases(), target ) ) + { + getFileFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy, target ); + } + } + else + { + Artifact artifact = null; + try + { + artifact = defaultArtifactDiscoverer.buildArtifact( path ); + } + catch ( DiscovererException e ) + { + getLogger().debug( "Failed to build artifact using default layout with message: " + e.getMessage() ); + } + + if ( artifact == null ) + { + try + { + artifact = legacyArtifactDiscoverer.buildArtifact( path ); + } + catch ( DiscovererException e ) + { + getLogger().debug( "Failed to build artifact using legacy layout with message: " + e.getMessage() ); + } + } + + if ( artifact != null ) + { + getArtifactFromRepository( artifact, repository, managedRepository, wagonProxy, target ); + } + else + { + // Some other unknown file in the repository, proxy as is + // TODO: this is not always! + if ( !target.exists() ) + { + getFileFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy, target ); + } + } + } + } + private void getFileFromRepository( String path, ProxiedArtifactRepository repository, String repositoryCachePath, ProxyInfo httpProxy, File target ) - throws ProxyException, ResourceDoesNotExistException + throws ProxyException { boolean connected = false; Map checksums = null; @@ -222,7 +234,7 @@ public class DefaultProxyRequestHandler { tries++; - getLogger().info( "Trying " + path + " from " + repository.getName() + "..." ); + getLogger().debug( "Trying " + path + " from " + repository.getName() + "..." ); if ( !target.exists() ) { @@ -233,21 +245,21 @@ public class DefaultProxyRequestHandler wagon.getIfNewer( path, temp, target.lastModified() ); } - success = doChecksumCheck( checksums, path, wagon, repositoryCachePath ); + success = checkChecksum( checksums, path, wagon, repositoryCachePath ); if ( tries > 1 && !success ) { - throw new ProxyException( "Checksum failures occurred while downloading " + path ); + //noinspection ThrowCaughtLocally + throw new TransferFailedException( "Checksum failures occurred while downloading " + path ); + } + + // temp won't exist if we called getIfNewer and it was older, but its still a successful return + if ( temp.exists() ) + { + moveTempToTarget( temp, target ); } } while ( !success ); - - disconnectWagon( wagon ); - - if ( temp.exists() ) - { - moveTempToTarget( temp, target ); - } } //try next repository } @@ -261,6 +273,11 @@ public class DefaultProxyRequestHandler String message = "Skipping repository " + repository.getName() + ": " + e.getMessage(); processRepositoryFailure( repository, message, e ); } + catch ( ResourceDoesNotExistException e ) + { + // hard failure setting doesn't affect "not found". + getLogger().debug( "Artifact not found in repository: " + repository.getName() + ": " + e.getMessage() ); + } finally { if ( wagon != null && checksums != null ) @@ -288,7 +305,7 @@ public class DefaultProxyRequestHandler */ private Map prepareChecksumListeners( Wagon wagon ) { - Map checksums = new HashMap(); + Map checksums = new LinkedHashMap(); try { ChecksumObserver checksum = new ChecksumObserver( "SHA-1" ); @@ -344,7 +361,7 @@ public class DefaultProxyRequestHandler return connected; } - private boolean doChecksumCheck( Map checksumMap, String path, Wagon wagon, String repositoryCachePath ) + private boolean checkChecksum( Map checksumMap, String path, Wagon wagon, String repositoryCachePath ) throws ProxyException { releaseChecksumListeners( wagon, checksumMap ); @@ -367,45 +384,49 @@ public class DefaultProxyRequestHandler remoteChecksum = remoteChecksum.substring( 0, remoteChecksum.indexOf( ' ' ) ); } - boolean checksumCheck = false; - if ( remoteChecksum.toUpperCase().equals( checksum.getActualChecksum().toUpperCase() ) ) + String actualChecksum = checksum.getActualChecksum().toUpperCase(); + remoteChecksum = remoteChecksum.toUpperCase(); + + boolean checksumCheck; + if ( remoteChecksum.equals( actualChecksum ) ) { moveTempToTarget( tempChecksumFile, checksumFile ); checksumCheck = true; } + else + { + getLogger().warn( + "The checksum '" + actualChecksum + "' did not match the remote value: " + remoteChecksum ); + checksumCheck = false; + } return checksumCheck; } - catch ( ChecksumFailedException e ) - { - return false; - } catch ( TransferFailedException e ) { - getLogger().debug( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(), - e ); + getLogger().warn( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(), + e ); // do nothing try the next checksum } catch ( ResourceDoesNotExistException e ) { - getLogger().debug( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(), - e ); + getLogger().debug( "The checksum did not exist: " + checksumPath, e ); // do nothing try the next checksum } catch ( AuthorizationException e ) { - getLogger().debug( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(), - e ); + getLogger().warn( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(), + e ); // do nothing try the next checksum } catch ( IOException e ) { - getLogger().debug( "An error occurred while reading the temporary checksum file.", e ); + getLogger().warn( "An error occurred while reading the temporary checksum file.", e ); return false; } } - getLogger().debug( "Skipping checksum validation for " + path + ": No remote checksums available." ); + getLogger().debug( "No remote checksums available." ); return true; } @@ -480,13 +501,14 @@ public class DefaultProxyRequestHandler } else { - getLogger().error( message, t ); + getLogger().warn( message ); + getLogger().debug( message, t ); } } private void getArtifactFromRepository( Artifact artifact, ProxiedArtifactRepository repository, ArtifactRepository managedRepository, ProxyInfo httpProxy, File remoteFile ) - throws ProxyException, ResourceDoesNotExistException + throws ProxyException { ArtifactRepository artifactRepository = repository.getRepository(); ArtifactRepositoryPolicy policy = diff --git a/maven-repository-proxy/src/test/java/org/apache/maven/repository/proxy/ProxyRequestHandlerTest.java b/maven-repository-proxy/src/test/java/org/apache/maven/repository/proxy/ProxyRequestHandlerTest.java index 9e7aa5388..c722686d0 100644 --- a/maven-repository-proxy/src/test/java/org/apache/maven/repository/proxy/ProxyRequestHandlerTest.java +++ b/maven-repository-proxy/src/test/java/org/apache/maven/repository/proxy/ProxyRequestHandlerTest.java @@ -20,21 +20,24 @@ import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.ArtifactRepositoryFactory; import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; import org.apache.maven.wagon.ResourceDoesNotExistException; +import org.apache.maven.wagon.TransferFailedException; +import org.apache.maven.wagon.Wagon; +import org.apache.maven.wagon.authorization.AuthorizationException; import org.codehaus.plexus.PlexusTestCase; import org.codehaus.plexus.util.FileUtils; +import org.easymock.MockControl; import java.io.File; import java.io.IOException; +import java.net.MalformedURLException; import java.util.ArrayList; import java.util.List; /** * @author Brett Porter * @todo! tests to do vvv - * @todo test when >1 repo has the artifact - * @todo test when >1 repo has the artifact but one fails - * @todo test hard failure on repo1 * @todo test when failure is cached + * @todo test when failure is cached and repo is hard fail * @todo test when failure should be cached but caching is disabled * @todo test snapshots - general * @todo test snapshots - newer version on repo2 is pulled down @@ -43,10 +46,18 @@ import java.util.List; * @todo test metadata - general * @todo test metadata - multiple repos are merged * @todo test metadata - update interval + * @todo test metadata - looking for an update and file has been removed remotely * @todo test when managed repo is m1 layout (proxy is m2), including metadata * @todo test when one proxied repo is m1 layout (managed is m2), including metadata * @todo test when one proxied repo is m1 layout (managed is m1), including metadata * @todo test get always + * @todo test get always when resource is present locally but not in any proxied repos (should fail) + * @todo test remote checksum only md5 + * @todo test remote checksum only sha1 + * @todo test remote checksum missing + * @todo test remote checksum present and correct + * @todo test remote checksum present and incorrect + * @todo test remote checksum transfer failed */ public class ProxyRequestHandlerTest extends PlexusTestCase @@ -61,6 +72,14 @@ public class ProxyRequestHandlerTest private ArtifactRepository proxiedRepository2; + private ArtifactRepositoryLayout defaultLayout; + + private ArtifactRepositoryFactory factory; + + private MockControl wagonMockControl; + + private Wagon wagonMock; + protected void setUp() throws Exception { @@ -72,24 +91,25 @@ public class ProxyRequestHandlerTest FileUtils.deleteDirectory( repoLocation ); copyDirectoryStructure( getTestFile( "src/test/repositories/managed" ), repoLocation ); - ArtifactRepositoryFactory factory = (ArtifactRepositoryFactory) lookup( ArtifactRepositoryFactory.ROLE ); - ArtifactRepositoryLayout defaultLayout = - (ArtifactRepositoryLayout) lookup( ArtifactRepositoryLayout.ROLE, "default" ); - defaultManagedRepository = factory.createArtifactRepository( "managed-repository", - repoLocation.toURI().toURL().toExternalForm(), - defaultLayout, null, null ); + defaultLayout = (ArtifactRepositoryLayout) lookup( ArtifactRepositoryLayout.ROLE, "default" ); + factory = (ArtifactRepositoryFactory) lookup( ArtifactRepositoryFactory.ROLE ); + + defaultManagedRepository = createRepository( "managed-repository", repoLocation ); File location = getTestFile( "src/test/repositories/proxied1" ); - proxiedRepository1 = factory.createArtifactRepository( "proxied1", location.toURI().toURL().toExternalForm(), - defaultLayout, null, null ); + proxiedRepository1 = createRepository( "proxied1", location ); location = getTestFile( "src/test/repositories/proxied2" ); - proxiedRepository2 = factory.createArtifactRepository( "proxied2", location.toURI().toURL().toExternalForm(), - defaultLayout, null, null ); + proxiedRepository2 = createRepository( "proxied2", location ); proxiedRepositories = new ArrayList( 2 ); proxiedRepositories.add( createProxiedRepository( proxiedRepository1 ) ); proxiedRepositories.add( createProxiedRepository( proxiedRepository2 ) ); + + wagonMockControl = MockControl.createNiceControl( Wagon.class ); + wagonMock = (Wagon) wagonMockControl.getMock(); + WagonDelegate delegate = (WagonDelegate) lookup( Wagon.ROLE, "test" ); + delegate.setDelegate( wagonMock ); } public void testGetDefaultLayoutNotPresent() @@ -134,12 +154,183 @@ public class ProxyRequestHandlerTest file.lastModified() ); } + public void testGetWhenInBothProxiedRepos() + throws ResourceDoesNotExistException, ProxyException, IOException + { + String path = "org/apache/maven/test/get-in-both-proxies/1.0/get-in-both-proxies-1.0.jar"; + File expectedFile = new File( defaultManagedRepository.getBasedir(), path ); + + assertFalse( expectedFile.exists() ); + + File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository ); + + assertEquals( "Check file matches", expectedFile, file ); + assertTrue( "Check file created", file.exists() ); + + File proxiedFile = new File( proxiedRepository1.getBasedir(), path ); + String expectedContents = FileUtils.fileRead( proxiedFile ); + assertEquals( "Check file contents", expectedContents, FileUtils.fileRead( file ) ); + + proxiedFile = new File( proxiedRepository2.getBasedir(), path ); + String unexpectedContents = FileUtils.fileRead( proxiedFile ); + assertFalse( "Check file contents", unexpectedContents.equals( FileUtils.fileRead( file ) ) ); + } + + public void testGetInSecondProxiedRepo() + throws ResourceDoesNotExistException, ProxyException, IOException + { + String path = "org/apache/maven/test/get-in-second-proxy/1.0/get-in-second-proxy-1.0.jar"; + File expectedFile = new File( defaultManagedRepository.getBasedir(), path ); + + assertFalse( expectedFile.exists() ); + + File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository ); + + assertEquals( "Check file matches", expectedFile, file ); + assertTrue( "Check file created", file.exists() ); + File proxiedFile = new File( proxiedRepository2.getBasedir(), path ); + String expectedContents = FileUtils.fileRead( proxiedFile ); + assertEquals( "Check file contents", expectedContents, FileUtils.fileRead( file ) ); + } + + public void testNotFoundInAnyProxies() + throws ResourceDoesNotExistException, ProxyException, IOException + { + String path = "org/apache/maven/test/does-not-exist/1.0/does-not-exist-1.0.jar"; + File expectedFile = new File( defaultManagedRepository.getBasedir(), path ); + + assertFalse( expectedFile.exists() ); + + try + { + File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository ); + fail( "File returned was: " + file + "; should have got a not found exception" ); + } + catch ( ResourceDoesNotExistException e ) + { + // expected, but check file was not created + assertFalse( expectedFile.exists() ); + } + } + + public void testGetInSecondProxiedRepoFirstFails() + throws ResourceDoesNotExistException, ProxyException, IOException, TransferFailedException, + AuthorizationException + { + String path = "org/apache/maven/test/get-in-second-proxy/1.0/get-in-second-proxy-1.0.jar"; + File expectedFile = new File( defaultManagedRepository.getBasedir(), path ).getAbsoluteFile(); + + assertFalse( expectedFile.exists() ); + + proxiedRepository1 = createRepository( "proxied1", "test://..." ); + proxiedRepositories.clear(); + ProxiedArtifactRepository proxiedArtifactRepository = createProxiedRepository( proxiedRepository1 ); + proxiedRepositories.add( proxiedArtifactRepository ); + proxiedRepositories.add( createProxiedRepository( proxiedRepository2 ) ); + + wagonMock.get( path, new File( expectedFile.getParentFile(), expectedFile.getName() + ".tmp" ) ); + wagonMockControl.setThrowable( new TransferFailedException( "transfer failed" ) ); + + wagonMockControl.replay(); + + File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository ); + + wagonMockControl.verify(); + + assertEquals( "Check file matches", expectedFile, file ); + assertTrue( "Check file created", file.exists() ); + File proxiedFile = new File( proxiedRepository2.getBasedir(), path ); + String expectedContents = FileUtils.fileRead( proxiedFile ); + assertEquals( "Check file contents", expectedContents, FileUtils.fileRead( file ) ); + + assertTrue( "Check failure", proxiedArtifactRepository.isCachedFailure( path ) ); + } + + public void testGetButAllRepositoriesFail() + throws ResourceDoesNotExistException, ProxyException, IOException, TransferFailedException, + AuthorizationException + { + String path = "org/apache/maven/test/get-in-second-proxy/1.0/get-in-second-proxy-1.0.jar"; + File expectedFile = new File( defaultManagedRepository.getBasedir(), path ).getAbsoluteFile(); + + assertFalse( expectedFile.exists() ); + + proxiedRepository1 = createRepository( "proxied1", "test://..." ); + proxiedRepository2 = createRepository( "proxied2", "test://..." ); + proxiedRepositories.clear(); + ProxiedArtifactRepository proxiedArtifactRepository1 = createProxiedRepository( proxiedRepository1 ); + proxiedRepositories.add( proxiedArtifactRepository1 ); + ProxiedArtifactRepository proxiedArtifactRepository2 = createProxiedRepository( proxiedRepository2 ); + proxiedRepositories.add( proxiedArtifactRepository2 ); + + wagonMock.get( path, new File( expectedFile.getParentFile(), expectedFile.getName() + ".tmp" ) ); + wagonMockControl.setThrowable( new TransferFailedException( "transfer failed" ) ); + + wagonMock.get( path, new File( expectedFile.getParentFile(), expectedFile.getName() + ".tmp" ) ); + wagonMockControl.setThrowable( new TransferFailedException( "transfer failed" ) ); + + wagonMockControl.replay(); + + try + { + File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository ); + fail( "Found file: " + file + "; but was expecting a failure" ); + } + catch ( ResourceDoesNotExistException e ) + { + // as expected + wagonMockControl.verify(); + assertTrue( "Check failure", proxiedArtifactRepository1.isCachedFailure( path ) ); + assertTrue( "Check failure", proxiedArtifactRepository2.isCachedFailure( path ) ); + + // TODO: do we really want failures to present as a not found? + // TODO: How much information on each failure should we pass back to the user vs. logging in the proxy? + } + } + + public void testGetInSecondProxiedRepoFirstHardFails() + throws ResourceDoesNotExistException, ProxyException, IOException, TransferFailedException, + AuthorizationException + { + String path = "org/apache/maven/test/get-in-second-proxy/1.0/get-in-second-proxy-1.0.jar"; + File expectedFile = new File( defaultManagedRepository.getBasedir(), path ).getAbsoluteFile(); + + assertFalse( expectedFile.exists() ); + + proxiedRepository1 = createRepository( "proxied1", "test://..." ); + proxiedRepositories.clear(); + ProxiedArtifactRepository proxiedArtifactRepository = createHardFailProxiedRepository( proxiedRepository1 ); + proxiedRepositories.add( proxiedArtifactRepository ); + proxiedRepositories.add( createProxiedRepository( proxiedRepository2 ) ); + + wagonMock.get( path, new File( expectedFile.getParentFile(), expectedFile.getName() + ".tmp" ) ); + TransferFailedException failedException = new TransferFailedException( "transfer failed" ); + wagonMockControl.setThrowable( failedException ); + + wagonMockControl.replay(); + + try + { + File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository ); + fail( "Found file: " + file + "; but was expecting a failure" ); + } + catch ( ProxyException e ) + { + // expect a failure + wagonMockControl.verify(); + + assertEquals( "Check cause", failedException, e.getCause() ); + assertTrue( "Check failure", proxiedArtifactRepository.isCachedFailure( path ) ); + } + } + /** * A faster recursive copy that omits .svn directories. * * @param sourceDirectory the source directory to copy * @param destDirectory the target location - * @throws java.io.IOException if there is a copying problemt + * @throws java.io.IOException if there is a copying problem + * @todo get back into plexus-utils, share with indexing module */ private static void copyDirectoryStructure( File sourceDirectory, File destDirectory ) throws IOException @@ -193,6 +384,30 @@ public class ProxyRequestHandlerTest { ProxiedArtifactRepository proxiedArtifactRepository = new ProxiedArtifactRepository( repository ); proxiedArtifactRepository.setName( repository.getId() ); + proxiedArtifactRepository.setCacheFailures( true ); return proxiedArtifactRepository; } + + private static ProxiedArtifactRepository createHardFailProxiedRepository( ArtifactRepository repository ) + { + ProxiedArtifactRepository proxiedArtifactRepository = createProxiedRepository( repository ); + proxiedArtifactRepository.setHardFail( true ); + return proxiedArtifactRepository; + } + + private ArtifactRepository createRepository( String id, File repoLocation ) + throws MalformedURLException + { + return createRepository( id, repoLocation.toURI().toURL().toExternalForm() ); + } + + private ArtifactRepository createRepository( String id, String url ) + { + return createRepository( id, url, defaultLayout ); + } + + private ArtifactRepository createRepository( String id, String url, ArtifactRepositoryLayout repositoryLayout ) + { + return factory.createArtifactRepository( id, url, repositoryLayout, null, null ); + } } diff --git a/maven-repository-proxy/src/test/java/org/apache/maven/repository/proxy/WagonDelegate.java b/maven-repository-proxy/src/test/java/org/apache/maven/repository/proxy/WagonDelegate.java new file mode 100644 index 000000000..904d6b869 --- /dev/null +++ b/maven-repository-proxy/src/test/java/org/apache/maven/repository/proxy/WagonDelegate.java @@ -0,0 +1,157 @@ +package org.apache.maven.repository.proxy; + +/* + * Copyright 2005-2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.maven.wagon.Wagon; +import org.apache.maven.wagon.TransferFailedException; +import org.apache.maven.wagon.ResourceDoesNotExistException; +import org.apache.maven.wagon.ConnectionException; +import org.apache.maven.wagon.events.SessionListener; +import org.apache.maven.wagon.events.TransferListener; +import org.apache.maven.wagon.proxy.ProxyInfo; +import org.apache.maven.wagon.authentication.AuthenticationException; +import org.apache.maven.wagon.authentication.AuthenticationInfo; +import org.apache.maven.wagon.repository.Repository; +import org.apache.maven.wagon.authorization.AuthorizationException; + +import java.io.File; + +/** + * A dummy wagon implementation + * + * @author Brett Porter + */ +public class WagonDelegate + implements Wagon +{ + private Wagon delegate; + + public void get( String resourceName, File destination ) + throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException + { + delegate.get( resourceName, destination ); + } + + public boolean getIfNewer( String resourceName, File destination, long timestamp ) + throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException + { + return delegate.getIfNewer( resourceName, destination, timestamp ); + } + + public void put( File source, String destination ) + throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException + { + delegate.put( source, destination ); + } + + public void putDirectory( File sourceDirectory, String destinationDirectory ) + throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException + { + delegate.putDirectory( sourceDirectory, destinationDirectory ); + } + + public boolean supportsDirectoryCopy() + { + return delegate.supportsDirectoryCopy(); + } + + public Repository getRepository() + { + return delegate.getRepository(); + } + + public void connect( Repository source ) + throws ConnectionException, AuthenticationException + { + delegate.connect( source ); + } + + public void connect( Repository source, ProxyInfo proxyInfo ) + throws ConnectionException, AuthenticationException + { + delegate.connect( source, proxyInfo ); + } + + public void connect( Repository source, AuthenticationInfo authenticationInfo ) + throws ConnectionException, AuthenticationException + { + delegate.connect( source, authenticationInfo ); + } + + public void connect( Repository source, AuthenticationInfo authenticationInfo, ProxyInfo proxyInfo ) + throws ConnectionException, AuthenticationException + { + delegate.connect( source, authenticationInfo, proxyInfo ); + } + + public void openConnection() + throws ConnectionException, AuthenticationException + { + delegate.openConnection(); + } + + public void disconnect() + throws ConnectionException + { + delegate.disconnect(); + } + + public void addSessionListener( SessionListener listener ) + { + delegate.addSessionListener( listener ); + } + + public void removeSessionListener( SessionListener listener ) + { + delegate.removeSessionListener( listener ); + } + + public boolean hasSessionListener( SessionListener listener ) + { + return delegate.hasSessionListener( listener ); + } + + public void addTransferListener( TransferListener listener ) + { + delegate.addTransferListener( listener ); + } + + public void removeTransferListener( TransferListener listener ) + { + delegate.removeTransferListener( listener ); + } + + public boolean hasTransferListener( TransferListener listener ) + { + return delegate.hasTransferListener( listener ); + } + + public boolean isInteractive() + { + return delegate.isInteractive(); + } + + public void setInteractive( boolean interactive ) + { + delegate.setInteractive( interactive ); + } + + public void setDelegate( Wagon delegate ) + { + this.delegate = delegate; + } +} diff --git a/maven-repository-proxy/src/test/repositories/proxied1/org/apache/maven/test/get-in-both-proxies/1.0/get-in-both-proxies-1.0.jar b/maven-repository-proxy/src/test/repositories/proxied1/org/apache/maven/test/get-in-both-proxies/1.0/get-in-both-proxies-1.0.jar new file mode 100644 index 000000000..3cc35fa29 --- /dev/null +++ b/maven-repository-proxy/src/test/repositories/proxied1/org/apache/maven/test/get-in-both-proxies/1.0/get-in-both-proxies-1.0.jar @@ -0,0 +1,3 @@ +get-in-both-proxies-1.0.jar +(proxied 1) + diff --git a/maven-repository-proxy/src/test/repositories/proxied2/org/apache/maven/test/get-in-both-proxies/1.0/get-in-both-proxies-1.0.jar b/maven-repository-proxy/src/test/repositories/proxied2/org/apache/maven/test/get-in-both-proxies/1.0/get-in-both-proxies-1.0.jar new file mode 100644 index 000000000..e46d60ac3 --- /dev/null +++ b/maven-repository-proxy/src/test/repositories/proxied2/org/apache/maven/test/get-in-both-proxies/1.0/get-in-both-proxies-1.0.jar @@ -0,0 +1,3 @@ +get-in-both-proxies-1.0.jar +(proxied 2) + diff --git a/maven-repository-proxy/src/test/repositories/proxied2/org/apache/maven/test/get-in-second-proxy/1.0/get-in-second-proxy-1.0.jar b/maven-repository-proxy/src/test/repositories/proxied2/org/apache/maven/test/get-in-second-proxy/1.0/get-in-second-proxy-1.0.jar new file mode 100644 index 000000000..3460f656d --- /dev/null +++ b/maven-repository-proxy/src/test/repositories/proxied2/org/apache/maven/test/get-in-second-proxy/1.0/get-in-second-proxy-1.0.jar @@ -0,0 +1,2 @@ +get-in-second-proxy-1.0.jar + diff --git a/maven-repository-proxy/src/test/resources/org/apache/maven/repository/proxy/ProxyRequestHandlerTest.xml b/maven-repository-proxy/src/test/resources/org/apache/maven/repository/proxy/ProxyRequestHandlerTest.xml new file mode 100644 index 000000000..d7fa2be2f --- /dev/null +++ b/maven-repository-proxy/src/test/resources/org/apache/maven/repository/proxy/ProxyRequestHandlerTest.xml @@ -0,0 +1,25 @@ + + + + + + org.apache.maven.wagon.Wagon + test + org.apache.maven.repository.proxy.WagonDelegate + + +