From b02cdf39a14af419375fe8f6f6bddd6d8aafec14 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 13 Apr 2007 15:48:27 +0000 Subject: [PATCH] * Adding CachedFailuresPolicy. * Adding UrlFailureCache component. * Adding unit tests for cache-failures and checksum policies. git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/branches/archiva-jpox-database-refactor@528532 13f79535-47bb-0310-9956-ffa450edef68 --- archiva-base/archiva-policies/pom.xml | 27 ++ .../policies/CachedFailuresPolicy.java | 96 ++++++ .../archiva/policies/ChecksumPolicy.java | 270 ++++++++------- .../archiva/policies/DownloadPolicy.java | 3 + .../archiva/policies/ReleasesPolicy.java | 2 +- .../archiva/policies/SnapshotsPolicy.java | 4 +- .../urlcache/DefaultUrlFailureCache.java | 58 ++++ .../policies/urlcache/UrlFailureCache.java | 48 +++ .../resources/META-INF/plexus/components.xml | 24 ++ .../policies/CachedFailuresPolicyTest.java | 102 ++++++ .../archiva/policies/ChecksumPolicyTest.java | 314 ++++++++++++++++++ .../src/test/resources/checksums/artifact.jar | Bin 0 -> 2422 bytes .../resources/checksums/artifact.jar.md5-bad | 1 + .../resources/checksums/artifact.jar.md5-good | 1 + .../resources/checksums/artifact.jar.sha1-bad | 1 + .../checksums/artifact.jar.sha1-good | 1 + .../src/test/resources/log4j.xml | 47 +++ 17 files changed, 883 insertions(+), 116 deletions(-) create mode 100644 archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/CachedFailuresPolicy.java create mode 100644 archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/urlcache/DefaultUrlFailureCache.java create mode 100644 archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/urlcache/UrlFailureCache.java create mode 100644 archiva-base/archiva-policies/src/main/resources/META-INF/plexus/components.xml create mode 100644 archiva-base/archiva-policies/src/test/java/org/apache/maven/archiva/policies/CachedFailuresPolicyTest.java create mode 100644 archiva-base/archiva-policies/src/test/java/org/apache/maven/archiva/policies/ChecksumPolicyTest.java create mode 100644 archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar create mode 100644 archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.md5-bad create mode 100644 archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.md5-good create mode 100644 archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.sha1-bad create mode 100644 archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.sha1-good create mode 100644 archiva-base/archiva-policies/src/test/resources/log4j.xml diff --git a/archiva-base/archiva-policies/pom.xml b/archiva-base/archiva-policies/pom.xml index 068148950..a08bd09db 100644 --- a/archiva-base/archiva-policies/pom.xml +++ b/archiva-base/archiva-policies/pom.xml @@ -41,6 +41,11 @@ org.codehaus.plexus plexus-digest + + org.codehaus.plexus.cache + plexus-cache-ehcache + 1.0-alpha-2-SNAPSHOT + easymock easymock @@ -60,4 +65,26 @@ test + + + + org.codehaus.plexus + plexus-maven-plugin + + + merge + + merge-descriptors + + + + ${basedir}/src/main/resources/META-INF/plexus/components.xml + ${project.build.directory}/generated-resources/plexus/META-INF/plexus/components.xml + + + + + + + diff --git a/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/CachedFailuresPolicy.java b/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/CachedFailuresPolicy.java new file mode 100644 index 000000000..5bd7e78a8 --- /dev/null +++ b/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/CachedFailuresPolicy.java @@ -0,0 +1,96 @@ +package org.apache.maven.archiva.policies; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.commons.lang.StringUtils; +import org.apache.maven.archiva.policies.urlcache.UrlFailureCache; +import org.codehaus.plexus.logging.AbstractLogEnabled; + +import java.io.File; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; + +/** + * {@link PreDownloadPolicy} to check if the requested url has failed before. + * + * @author Joakim Erdfelt + * @version $Id$ + * + * @plexus.component role="org.apache.maven.archiva.policies.PreDownloadPolicy" + * role-hint="cache-failures" + */ +public class CachedFailuresPolicy + extends AbstractLogEnabled + implements PreDownloadPolicy +{ + /** + * The CACHED policy indicates that if the URL provided exists in the + * cached failures pool, then the policy fails, and the download isn't even + * attempted. + */ + public static final String CACHED = "cached"; + + /** + * @plexus.requirement role-hint="default" + */ + private UrlFailureCache urlFailureCache; + + private Set validPolicyCodes = new HashSet(); + + public CachedFailuresPolicy() + { + validPolicyCodes.add( IGNORED ); + validPolicyCodes.add( CACHED ); + } + + public boolean applyPolicy( String policySetting, Properties request, File localFile ) + { + if ( !validPolicyCodes.contains( policySetting ) ) + { + // No valid code? false it is then. + getLogger().error( "Unknown checksum policyCode [" + policySetting + "]" ); + return false; + } + + if ( IGNORED.equals( policySetting ) ) + { + // Ignore. + return true; + } + + String url = request.getProperty( "url" ); + + if ( StringUtils.isNotBlank( url ) ) + { + if ( urlFailureCache.hasFailedBefore( url ) ) + { + return false; + } + } + + return true; + } + + public String getDefaultPolicySetting() + { + return IGNORED; + } +} diff --git a/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/ChecksumPolicy.java b/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/ChecksumPolicy.java index f297aa700..864ba1358 100644 --- a/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/ChecksumPolicy.java +++ b/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/ChecksumPolicy.java @@ -1,5 +1,24 @@ package org.apache.maven.archiva.policies; +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.codehaus.plexus.digest.ChecksumFile; import org.codehaus.plexus.digest.Digester; import org.codehaus.plexus.digest.DigesterException; @@ -12,6 +31,15 @@ import java.util.HashSet; import java.util.Properties; import java.util.Set; +/** + * ChecksumPolicy + * + * @author Joakim Erdfelt + * @version $Id$ + * + * @plexus.component role="org.apache.maven.archiva.policies.PostDownloadPolicy" + * role-hint="checksum" + */ public class ChecksumPolicy extends AbstractLogEnabled implements PostDownloadPolicy @@ -30,13 +58,6 @@ public class ChecksumPolicy */ public static final String FIX = "fix"; - /** - * The IGNORE policy indicates that the checksum is never tested - * and even bad downloads and checksum files are left in place - * on the local repository. - */ - public static final String IGNORED = "ignored"; - /** * @plexus.requirement role-hint="sha1" */ @@ -88,147 +109,170 @@ public class ChecksumPolicy if ( FAIL.equals( policySetting ) ) { + boolean checksPass = true; + + // Both files missing is a failure. if ( !sha1File.exists() && !md5File.exists() ) { - getLogger().error( "File " + localFile.getAbsolutePath() + " has no checksum files (sha1 or md5)." ); - localFile.delete(); - return false; + getLogger().error( "File " + localFile.getPath() + " has no checksum files (sha1 or md5)." ); + checksPass = false; } - // Test for sha1 first, then md5 - if ( sha1File.exists() ) { - try + // Bad sha1 checksum is a failure. + if ( !validateChecksum( sha1File, "sha1" ) ) { - return checksumFile.isValidChecksum( sha1File ); - } - catch ( FileNotFoundException e ) - { - getLogger().warn( "Unable to find sha1 file: " + sha1File.getAbsolutePath(), e ); - return false; - } - catch ( DigesterException e ) - { - getLogger().warn( "Unable to process sha1 file: " + sha1File.getAbsolutePath(), e ); - return false; - } - catch ( IOException e ) - { - getLogger().warn( "Unable to process sha1 file: " + sha1File.getAbsolutePath(), e ); - return false; + getLogger().warn( "SHA1 is incorrect for " + localFile.getPath() ); + checksPass = false; } } if ( md5File.exists() ) { - try - { - return checksumFile.isValidChecksum( md5File ); - } - catch ( FileNotFoundException e ) + // Bad md5 checksum is a failure. + if ( !validateChecksum( md5File, "md5" ) ) { - getLogger().warn( "Unable to find md5 file: " + md5File.getAbsolutePath(), e ); - return false; + getLogger().warn( "MD5 is incorrect for " + localFile.getPath() ); + checksPass = false; } - catch ( DigesterException e ) + } + + if ( !checksPass ) + { + // On failure. delete files. + if ( sha1File.exists() ) { - getLogger().warn( "Unable to process md5 file: " + md5File.getAbsolutePath(), e ); - return false; + sha1File.delete(); } - catch ( IOException e ) + + if ( md5File.exists() ) { - getLogger().warn( "Unable to process md5 file: " + md5File.getAbsolutePath(), e ); - return false; + md5File.delete(); } + + localFile.delete(); } + + return checksPass; } if ( FIX.equals( policySetting ) ) { - if ( !sha1File.exists() ) + boolean checksPass = true; + + if ( !fixChecksum( localFile, sha1File, digestSha1 ) ) { - try - { - checksumFile.createChecksum( localFile, digestSha1 ); - } - catch ( DigesterException e ) - { - getLogger().warn( "Unable to create sha1 file: " + e.getMessage(), e ); - return false; - } - catch ( IOException e ) - { - getLogger().warn( "Unable to create sha1 file: " + e.getMessage(), e ); - return false; - } + checksPass = false; } - else + + if ( !fixChecksum( localFile, md5File, digestMd5 ) ) { - try - { - checksumFile.isValidChecksum( sha1File ); - } - catch ( FileNotFoundException e ) - { - getLogger().warn( "Unable to find sha1 file: " + sha1File.getAbsolutePath(), e ); - return false; - } - catch ( DigesterException e ) - { - getLogger().warn( "Unable to process sha1 file: " + sha1File.getAbsolutePath(), e ); - return false; - } - catch ( IOException e ) - { - getLogger().warn( "Unable to process sha1 file: " + sha1File.getAbsolutePath(), e ); - return false; - } + checksPass = false; } - if ( !md5File.exists() ) + return checksPass; + } + + getLogger().error( "Unhandled policyCode [" + policySetting + "]" ); + return false; + } + + private boolean createChecksum( File localFile, Digester digester ) + { + try + { + checksumFile.createChecksum( localFile, digester ); + return true; + } + catch ( DigesterException e ) + { + getLogger().warn( "Unable to create " + digester.getFilenameExtension() + " file: " + e.getMessage(), e ); + return false; + } + catch ( IOException e ) + { + getLogger().warn( "Unable to create " + digester.getFilenameExtension() + " file: " + e.getMessage(), e ); + return false; + } + } + + private boolean fixChecksum( File localFile, File hashFile, Digester digester ) + { + String ext = digester.getFilenameExtension(); + + if ( !hashFile.getPath().endsWith( ext ) ) + { + throw new IllegalArgumentException( "Cannot fix " + hashFile.getPath() + " using " + ext + " digester." ); + } + + // If hashfile doesn't exist, create it. + if ( !hashFile.exists() ) + { + return createChecksum( localFile, digester ); + } + + // Validate checksum, if bad, recreate it. + try + { + if ( checksumFile.isValidChecksum( hashFile ) ) { - try - { - checksumFile.createChecksum( localFile, digestMd5 ); - } - catch ( DigesterException e ) - { - getLogger().warn( "Unable to create md5 file: " + e.getMessage(), e ); - return false; - } - catch ( IOException e ) - { - getLogger().warn( "Unable to create md5 file: " + e.getMessage(), e ); - return false; - } + getLogger().debug( "Valid checksum: " + hashFile.getPath() ); + return true; } else { - try - { - return checksumFile.isValidChecksum( md5File ); - } - catch ( FileNotFoundException e ) - { - getLogger().warn( "Unable to find md5 file: " + md5File.getAbsolutePath(), e ); - return false; - } - catch ( DigesterException e ) - { - getLogger().warn( "Unable to process md5 file: " + md5File.getAbsolutePath(), e ); - return false; - } - catch ( IOException e ) - { - getLogger().warn( "Unable to process md5 file: " + md5File.getAbsolutePath(), e ); - return false; - } + getLogger().debug( "Not valid checksum: " + hashFile.getPath() ); + return createChecksum( localFile, digester ); } } + catch ( FileNotFoundException e ) + { + getLogger().warn( "Unable to find " + ext + " file: " + hashFile.getAbsolutePath(), e ); + return false; + } + catch ( DigesterException e ) + { + getLogger().warn( "Unable to process " + ext + " file: " + hashFile.getAbsolutePath(), e ); + return false; + } + catch ( IOException e ) + { + getLogger().warn( "Unable to process " + ext + " file: " + hashFile.getAbsolutePath(), e ); + return false; + } + } - getLogger().error( "Unhandled policyCode [" + policySetting + "]" ); - return false; + private boolean validateChecksum( File hashFile, String type ) + { + try + { + boolean validity = checksumFile.isValidChecksum( hashFile ); + if ( validity ) + { + getLogger().debug( "Valid checksum: " + hashFile.getPath() ); + } + else + { + getLogger().debug( "Not valid checksum: " + hashFile.getPath() ); + } + return validity; + } + catch ( FileNotFoundException e ) + { + getLogger().warn( "Unable to find " + type + " file: " + hashFile.getAbsolutePath(), e ); + return false; + } + catch ( DigesterException e ) + { + getLogger().warn( "Unable to process " + type + " file: " + hashFile.getAbsolutePath(), e ); + return false; + } + catch ( IOException e ) + { + getLogger().warn( "Unable to process " + type + " file: " + hashFile.getAbsolutePath(), e ); + return false; + } } public String getDefaultPolicySetting() diff --git a/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/DownloadPolicy.java b/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/DownloadPolicy.java index 36f283705..e556c4b28 100644 --- a/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/DownloadPolicy.java +++ b/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/DownloadPolicy.java @@ -35,6 +35,9 @@ public interface DownloadPolicy */ public static final String IGNORED = "ignored"; + public static final boolean PASS = true; + public static final boolean FAIL = false; + /** * Get the default policy setting. * diff --git a/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/ReleasesPolicy.java b/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/ReleasesPolicy.java index 9c9bc2daa..4d08d1a68 100644 --- a/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/ReleasesPolicy.java +++ b/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/ReleasesPolicy.java @@ -26,7 +26,7 @@ package org.apache.maven.archiva.policies; * @author Joakim Erdfelt * @version $Id$ * - * @plexus.component role="org.apache.maven.archiva.policies.download.PreDownloadPolicy" + * @plexus.component role="org.apache.maven.archiva.policies.PreDownloadPolicy" * role-hint="releases" */ public class ReleasesPolicy diff --git a/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/SnapshotsPolicy.java b/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/SnapshotsPolicy.java index d786275ed..d78847a80 100644 --- a/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/SnapshotsPolicy.java +++ b/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/SnapshotsPolicy.java @@ -26,8 +26,8 @@ package org.apache.maven.archiva.policies; * @author Joakim Erdfelt * @version $Id$ * - * @plexus.component role="org.apache.maven.archiva.policies.download.PreDownloadPolicy" - * role-hint="releases" + * @plexus.component role="org.apache.maven.archiva.policies.PreDownloadPolicy" + * role-hint="snapshots" */ public class SnapshotsPolicy extends AbstractUpdatePolicy diff --git a/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/urlcache/DefaultUrlFailureCache.java b/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/urlcache/DefaultUrlFailureCache.java new file mode 100644 index 000000000..0c251aee4 --- /dev/null +++ b/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/urlcache/DefaultUrlFailureCache.java @@ -0,0 +1,58 @@ +package org.apache.maven.archiva.policies.urlcache; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.codehaus.plexus.cache.Cache; + +import java.util.Date; + +/** + * DefaultUrlFailureCache + * + * @author Joakim Erdfelt + * @version $Id$ + * + * @plexus.component role="org.apache.maven.archiva.policies.urlcache.UrlFailureCache" + * role-hint="default" + */ +public class DefaultUrlFailureCache + implements UrlFailureCache +{ + /** + * @plexus.requirement role-hint="url-failures-cache" + */ + private Cache urlCache; + + public void cacheFailure( String url ) + { + urlCache.register( url, new Date() ); + } + + public boolean hasFailedBefore( String url ) + { + if ( urlCache.hasKey( url ) ) + { + urlCache.register( url, new Date() ); + return true; + } + + return false; + } +} diff --git a/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/urlcache/UrlFailureCache.java b/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/urlcache/UrlFailureCache.java new file mode 100644 index 000000000..fc08e6c33 --- /dev/null +++ b/archiva-base/archiva-policies/src/main/java/org/apache/maven/archiva/policies/urlcache/UrlFailureCache.java @@ -0,0 +1,48 @@ +package org.apache.maven.archiva.policies.urlcache; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + + +/** + * Cache for requested URLs that cannot be fetched. + * + * @author Joakim Erdfelt + * @version $Id$ + */ +public interface UrlFailureCache +{ + /** + * Store a URL in the cache as failed. + * + * @param url the url to store. + */ + public void cacheFailure( String url ); + + /** + * Test if a specified URL has failed before. + * + * NOTE: If the provided URL has failed, then making this call + * should refresh the expiration time on that URL entry. + * + * @param url the URL to test. + * @return true if it has failed before, false if not. + */ + public boolean hasFailedBefore( String url ); +} diff --git a/archiva-base/archiva-policies/src/main/resources/META-INF/plexus/components.xml b/archiva-base/archiva-policies/src/main/resources/META-INF/plexus/components.xml new file mode 100644 index 000000000..66d543fb6 --- /dev/null +++ b/archiva-base/archiva-policies/src/main/resources/META-INF/plexus/components.xml @@ -0,0 +1,24 @@ + + + + org.codehaus.plexus.cache.Cache + url-failures-cache + org.codehaus.plexus.cache.ehcache.EhcacheCache + URL Failure Cache + + 600 + true + ${java.io.tmpdir}/archiva/urlcache + false + 1000 + LRU + cache + false + + 2700 + + 1800 + + + + diff --git a/archiva-base/archiva-policies/src/test/java/org/apache/maven/archiva/policies/CachedFailuresPolicyTest.java b/archiva-base/archiva-policies/src/test/java/org/apache/maven/archiva/policies/CachedFailuresPolicyTest.java new file mode 100644 index 000000000..dd65f7a90 --- /dev/null +++ b/archiva-base/archiva-policies/src/test/java/org/apache/maven/archiva/policies/CachedFailuresPolicyTest.java @@ -0,0 +1,102 @@ +package org.apache.maven.archiva.policies; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.archiva.policies.urlcache.UrlFailureCache; +import org.codehaus.plexus.PlexusTestCase; + +import java.io.File; +import java.util.Properties; + +/** + * CachedFailuresPolicyTest + * + * @author Joakim Erdfelt + * @version $Id$ + */ +public class CachedFailuresPolicyTest + extends PlexusTestCase +{ + private DownloadPolicy lookupPolicy() + throws Exception + { + return (DownloadPolicy) lookup( PreDownloadPolicy.class.getName(), "cache-failures" ); + } + + private UrlFailureCache lookupUrlFailureCache() + throws Exception + { + return (UrlFailureCache) lookup( UrlFailureCache.class.getName(), "default" ); + } + + private File getFile() + { + return new File( "target/cache-failures/" + getName() + ".txt" ); + } + + private Properties createRequest() + { + Properties request = new Properties(); + + return request; + } + + public void testIgnored() + throws Exception + { + DownloadPolicy policy = lookupPolicy(); + File localFile = getFile(); + Properties request = createRequest(); + + request.setProperty( "url", "http://a.bad.hostname.maven.org/path/to/resource.txt" ); + + assertTrue( policy.applyPolicy( CachedFailuresPolicy.IGNORED, request, localFile ) ); + } + + public void testCachedNotInCache() + throws Exception + { + DownloadPolicy policy = lookupPolicy(); + File localFile = getFile(); + Properties request = createRequest(); + + request.setProperty( "url", "http://a.bad.hostname.maven.org/path/to/resource.txt" ); + + assertTrue( policy.applyPolicy( CachedFailuresPolicy.CACHED, request, localFile ) ); + } + + public void testCachedInCache() + throws Exception + { + UrlFailureCache urlFailureCache = lookupUrlFailureCache(); + + DownloadPolicy policy = lookupPolicy(); + File localFile = getFile(); + Properties request = createRequest(); + + String url = "http://a.bad.hostname.maven.org/path/to/resource.txt"; + + urlFailureCache.cacheFailure( url ); + + request.setProperty( "url", url ); + + assertFalse( policy.applyPolicy( CachedFailuresPolicy.CACHED, request, localFile ) ); + } +} diff --git a/archiva-base/archiva-policies/src/test/java/org/apache/maven/archiva/policies/ChecksumPolicyTest.java b/archiva-base/archiva-policies/src/test/java/org/apache/maven/archiva/policies/ChecksumPolicyTest.java new file mode 100644 index 000000000..d37b42d24 --- /dev/null +++ b/archiva-base/archiva-policies/src/test/java/org/apache/maven/archiva/policies/ChecksumPolicyTest.java @@ -0,0 +1,314 @@ +package org.apache.maven.archiva.policies; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.codehaus.plexus.PlexusTestCase; +import org.codehaus.plexus.util.FileUtils; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.Properties; + +/** + * ChecksumPolicyTest + * + * @author Joakim Erdfelt + * @version $Id$ + */ +public class ChecksumPolicyTest + extends PlexusTestCase +{ + private static final String GOOD = "good"; + + private static final String BAD = "bad"; + + public void testFailOnFileOnly() + throws Exception + { + assertFailSetting( false, null, null ); + } + + public void testFailOnFileWithBadMd5AndBadSha1() + throws Exception + { + assertFailSetting( false, BAD, BAD ); + } + + public void testFailOnFileWithBadMd5AndGoodSha1() + throws Exception + { + assertFailSetting( false, BAD, GOOD ); + } + + public void testFailOnFileWithBadMd5Only() + throws Exception + { + assertFailSetting( false, BAD, null ); + } + + public void testFailOnFileWithBadSha1Only() + throws Exception + { + assertFailSetting( false, null, BAD ); + } + + public void testFailOnFileWithGoodMd5AndBadSha1() + throws Exception + { + assertFailSetting( false, GOOD, BAD ); + } + + public void testFailOnFileWithGoodMd5AndGoodSha1() + throws Exception + { + assertFailSetting( true, GOOD, GOOD ); + } + + public void testFailOnFileWithGoodMd5Only() + throws Exception + { + assertFailSetting( true, GOOD, null ); + } + + public void testFailOnFileWithGoodSha1Only() + throws Exception + { + assertFailSetting( true, null, GOOD ); + } + + public void testFixOnFileOnly() + throws Exception + { + assertFixSetting( true, null, null ); + } + + public void testFixOnFileWithBadMd5AndBadSha1() + throws Exception + { + assertFixSetting( true, BAD, BAD ); + } + + public void testFixOnFileWithBadMd5AndGoodSha1() + throws Exception + { + assertFixSetting( true, BAD, GOOD ); + } + + public void testFixOnFileWithBadMd5Only() + throws Exception + { + assertFixSetting( true, BAD, null ); + } + + public void testFixOnFileWithBadSha1Only() + throws Exception + { + assertFixSetting( true, null, BAD ); + } + + public void testFixOnFileWithGoodMd5AndBadSha1() + throws Exception + { + assertFixSetting( true, GOOD, BAD ); + } + + public void testFixOnFileWithGoodMd5AndGoodSha1() + throws Exception + { + assertFixSetting( true, GOOD, GOOD ); + } + + public void testFixOnFileWithGoodMd5Only() + throws Exception + { + assertFixSetting( true, GOOD, null ); + } + + public void testFixOnFileWithGoodSha1Only() + throws Exception + { + assertFixSetting( true, null, GOOD ); + } + + public void testIgnored() + throws Exception + { + PostDownloadPolicy policy = lookupPolicy(); + File localFile = createTestableFiles( null, null ); + Properties request = createRequest(); + + assertTrue( policy.applyPolicy( ChecksumPolicy.IGNORED, request, localFile ) ); + } + + private void assertFailSetting( boolean expectedResult, String md5State, String sha1State ) + throws Exception + { + PostDownloadPolicy policy = lookupPolicy(); + File localFile = createTestableFiles( md5State, sha1State ); + Properties request = createRequest(); + + boolean actualResult = policy.applyPolicy( ChecksumPolicy.FAIL, request, localFile ); + String msg = createMessage( ChecksumPolicy.FAIL, md5State, sha1State ); + + if ( actualResult == false ) + { + assertFalse( msg + " local file should not exist:", localFile.exists() ); + File md5File = new File( localFile.getAbsolutePath() + ".sha1" ); + File sha1File = new File( localFile.getAbsolutePath() + ".md5" ); + assertFalse( msg + " local md5 file should not exist:", md5File.exists() ); + assertFalse( msg + " local sha1 file should not exist:", sha1File.exists() ); + } + + assertEquals( createMessage( ChecksumPolicy.FAIL, md5State, sha1State ), expectedResult, actualResult ); + } + + private void assertFixSetting( boolean expectedResult, String md5State, String sha1State ) + throws Exception + { + PostDownloadPolicy policy = lookupPolicy(); + File localFile = createTestableFiles( md5State, sha1State ); + Properties request = createRequest(); + + boolean actualResult = policy.applyPolicy( ChecksumPolicy.FIX, request, localFile ); + assertEquals( createMessage( ChecksumPolicy.FIX, md5State, sha1State ), expectedResult, actualResult ); + + // End result should be legitimate SHA1 and MD5 files. + File md5File = new File( localFile.getAbsolutePath() + ".md5" ); + File sha1File = new File( localFile.getAbsolutePath() + ".sha1" ); + + assertTrue( "ChecksumPolicy.apply(FIX) md5 should exist.", md5File.exists() && md5File.isFile() ); + assertTrue( "ChecksumPolicy.apply(FIX) sha1 should exist.", sha1File.exists() && sha1File.isFile() ); + + String actualMd5Contents = readChecksumFile( md5File ); + String actualSha1Contents = readChecksumFile( sha1File ); + + String expectedMd5Contents = "360ccd01d8a0a2d94b86f9802c2fc548 artifact.jar"; + String expectedSha1Contents = "7dd8929150664f182db60ad15f20359d875f059f artifact.jar"; + + assertEquals( "ChecksumPolicy.apply(FIX) md5 contents:", expectedMd5Contents, actualMd5Contents ); + assertEquals( "ChecksumPolicy.apply(FIX) sha1 contents:", expectedSha1Contents, actualSha1Contents ); + } + + /** + * Read the first line from the checksum file, and return it (trimmed). + */ + private String readChecksumFile( File checksumFile ) + throws Exception + { + FileReader freader = null; + BufferedReader buf = null; + + try + { + freader = new FileReader( checksumFile ); + buf = new BufferedReader( freader ); + return buf.readLine(); + } + finally + { + if ( buf != null ) + { + buf.close(); + } + + if ( freader != null ) + { + freader.close(); + } + } + } + + private String createMessage( String settingType, String md5State, String sha1State ) + { + StringBuffer msg = new StringBuffer(); + msg.append( "Expected result of ChecksumPolicy.apply(" ); + msg.append( settingType.toUpperCase() ); + msg.append( ") when working with " ); + if ( md5State == null ) + { + msg.append( "NO" ); + } + else + { + msg.append( "a " ).append( md5State.toUpperCase() ); + } + + msg.append( " MD5 and " ); + + if ( sha1State == null ) + { + msg.append( "NO" ); + } + else + { + msg.append( "a " ).append( sha1State.toUpperCase() ); + } + msg.append( " SHA1:" ); + + return msg.toString(); + } + + private Properties createRequest() + { + Properties request = new Properties(); + + request.setProperty( "url", "http://a.bad.hostname.maven.org/path/to/resource.txt" ); + + return request; + } + + private File createTestableFiles( String md5State, String sha1State ) + throws Exception + { + File sourceDir = new File( "src/test/resources/checksums/" ); + File destDir = new File( "target/checksum-tests/" + getName() + "/" ); + + FileUtils.copyFileToDirectory( new File( sourceDir, "artifact.jar" ), destDir ); + + if ( md5State != null ) + { + File md5File = new File( sourceDir, "artifact.jar.md5-" + md5State ); + assertTrue( "Testable file exists: " + md5File.getName() + ":", md5File.exists() && md5File.isFile() ); + File destFile = new File( destDir, "artifact.jar.md5" ); + FileUtils.copyFile( md5File, destFile ); + } + + if ( sha1State != null ) + { + File sha1File = new File( sourceDir, "artifact.jar.sha1-" + sha1State ); + assertTrue( "Testable file exists: " + sha1File.getName() + ":", sha1File.exists() && sha1File.isFile() ); + File destFile = new File( destDir, "artifact.jar.sha1" ); + FileUtils.copyFile( sha1File, destFile ); + } + + File localFile = new File( destDir, "artifact.jar" ); + return localFile; + } + + private PostDownloadPolicy lookupPolicy() + throws Exception + { + PostDownloadPolicy policy = (PostDownloadPolicy) lookup( PostDownloadPolicy.class.getName(), "checksum" ); + assertNotNull( policy ); + return policy; + } + +} diff --git a/archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar b/archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar new file mode 100644 index 0000000000000000000000000000000000000000..d1b610e5ec784ce3e22b3c40775c522bf8797743 GIT binary patch literal 2422 zcmWIWW@h1H0DuQ}lbAEG>!4=~NPm6TC&YjTl)^*}wf3hTOikS8R zm5QBnx`TwhgMv%uYONKK;TD=~93)yJd^+eeP{zx+*z3Tf$e*1zXYLf3C=$DVO3s9j z%c|HuvWe}9*%QM6a~P)k`H>x#n^=~b2loZ0Vl7O?`97 zrKP!e%yA~k9Jqmdfnk*}1A`ZJEGWp& z)vL(O*&E^8f7?u8@B8%u;#Ps@tB_=jSfZ_3pE{qj-JEbT^mOy(KR*4VDrRYG+lEZJ&5 zSWoRK?(ll>e)|2i`)LOqRkwfaeeP;GZOZFUf?^R_-VDR*{0nDuediJIn)fY(bM z^OtB8MKD&bJ+6`a&27c88M4({q7{PYn|J>IQLw%0&xfDuIj&y1BvZ0U{gjK-W&Lld zPorC`HqG9ww){(gM!cB9iH!SSIv)2N`)+zGIyB?`d8ydFdWD>4HT^Zzd$e9VDqBf4 zTJvyDeVu&%=eo6G7yC6ELf9Kw{nZgGpWsqOx!QTvU4S(k{^_nT(oCrII$Un;xEa#N)4tbN9suMZaz_aaB}Z zm@?f+G&|BkC927+Ym!rWYi?n5)GnQZRlAI|dp8D|L@)nh(if6sZsz%F)4F2?sS{!( zlwZ&4l_}fal6!n%h5bff#lriiPu!}%)Uu#V(x@Xy%U5j-L_7eFrnbUghJJo zPfts)oV{)9>4gccU(K#XGO+h+dT^|8=snXv7{$%$K4fmjC^-lZ|?oB z#2R{>^YuRC#ufHE+P)T8P261m^>E$6`3~{y#^Or6x4W+|^u4CS5296-d>@u4S3Y!V z&zUu;#q)vSrwnG9S^5DAFK-)6*LVD7_9WGK&as-TztHs=kp6aI$_k1pEy)^Gu5@%m^6oZl`$5)Zxv&}BQT+wJSx24Qw=9}e9 zyhJ7ioCrF%`f(-iwOA#mA3A!vwa*RS=C#gwtL1ce=98x#mu4RHBkDd1X z@@pYunkei3bc3IL<^}F&KRw#%feuN_OOBzQlj&Ie7Uv>ShVy3 zaUk`In1Z7Gg4Cjt%+zArGkduX8HhMMwDm7sSnPD!NwbxYZxLUVVr^q~RW9?hb`#BC z->x0~`naG=*s^OzM$>Wjbvq^|ADzL;Hg~}^h1u)!cCTt(EVWSUbX%@S_~Tgp)+evZ zcC7wvu*ve5j9&2j$2tZJ;yiBL_s)1fsn9aI&2Xmrt1aR6Pae9y-}7lk`GzC=0=yZS zM3`~cbwFPOfdIo>M-Yuv^TD)XulqoXL10OvI*^2GL#he!Sq!SAAOK|X0U#4@0<6k{ zS&zNaLTG-AsTpq-hTB|FB?bW?N0~BWI0}!sc&ap*h1e@Kn3YQ!r%}g3XcdPDee5Y6 fVed~?s(2J+FCyIsc(byBtY8PiGA0IwS706hN(Y&# literal 0 HcmV?d00001 diff --git a/archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.md5-bad b/archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.md5-bad new file mode 100644 index 000000000..aafbb1c77 --- /dev/null +++ b/archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.md5-bad @@ -0,0 +1 @@ +444ccc111aaa222999888eee222fff00 artifact.jar diff --git a/archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.md5-good b/archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.md5-good new file mode 100644 index 000000000..1c8465238 --- /dev/null +++ b/archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.md5-good @@ -0,0 +1 @@ +360ccd01d8a0a2d94b86f9802c2fc548 artifact.jar diff --git a/archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.sha1-bad b/archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.sha1-bad new file mode 100644 index 000000000..2d809c29b --- /dev/null +++ b/archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.sha1-bad @@ -0,0 +1 @@ +ddd888999000444888bbbaaa555333999777eee0 artifact.jar diff --git a/archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.sha1-good b/archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.sha1-good new file mode 100644 index 000000000..0f10d257e --- /dev/null +++ b/archiva-base/archiva-policies/src/test/resources/checksums/artifact.jar.sha1-good @@ -0,0 +1 @@ +7dd8929150664f182db60ad15f20359d875f059f artifact.jar diff --git a/archiva-base/archiva-policies/src/test/resources/log4j.xml b/archiva-base/archiva-policies/src/test/resources/log4j.xml new file mode 100644 index 000000000..3c782b138 --- /dev/null +++ b/archiva-base/archiva-policies/src/test/resources/log4j.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 2.39.5