1 package org.apache.archiva.repository.scanner;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import junit.framework.TestCase;
23 import org.apache.archiva.common.filelock.DefaultFileLockManager;
24 import org.apache.archiva.common.filelock.FileLockManager;
25 import org.apache.archiva.consumers.InvalidRepositoryContentConsumer;
26 import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
27 import org.apache.archiva.repository.BasicManagedRepository;
28 import org.apache.archiva.repository.BasicRemoteRepository;
29 import org.apache.archiva.repository.EditableManagedRepository;
30 import org.apache.archiva.repository.EditableRemoteRepository;
31 import org.apache.archiva.repository.ManagedRepository;
32 import org.apache.archiva.repository.content.FilesystemStorage;
33 import org.apache.archiva.repository.scanner.mock.ManagedRepositoryContentMock;
34 import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
35 import org.apache.commons.io.FileUtils;
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 import org.springframework.context.ApplicationContext;
39 import org.springframework.test.context.ContextConfiguration;
41 import javax.inject.Inject;
42 import java.io.IOException;
44 import java.net.URISyntaxException;
45 import java.nio.file.Files;
46 import java.nio.file.Path;
47 import java.nio.file.Paths;
48 import java.nio.file.attribute.FileTime;
49 import java.text.ParseException;
50 import java.text.SimpleDateFormat;
51 import java.util.ArrayList;
52 import java.util.Arrays;
53 import java.util.List;
54 import java.util.Locale;
55 import java.util.TimeZone;
58 * RepositoryScannerTest
60 @RunWith(ArchivaSpringJUnit4ClassRunner.class)
61 @ContextConfiguration(locations = { "classpath*:/META-INF/spring-context.xml" })
62 public class RepositoryScannerTest
67 ApplicationContext applicationContext;
69 protected EditableManagedRepository createRepository( String id, String name, Path location ) throws IOException {
70 FileLockManager lockManager = new DefaultFileLockManager();
71 FilesystemStorage storage = new FilesystemStorage(location.toAbsolutePath(), lockManager);
72 BasicManagedRepository repo = new BasicManagedRepository(id, name, storage);
73 repo.setLocation( location.toAbsolutePath().toUri());
74 repo.setContent(new ManagedRepositoryContentMock(repo));
78 protected EditableRemoteRepository createRemoteRepository( String id, String name, String url ) throws URISyntaxException, IOException {
79 BasicRemoteRepository repo = BasicRemoteRepository.newFilesystemInstance(id, name, Paths.get("remotes"));
80 repo.setLocation( new URI( url ) );
84 private static final String[] ARTIFACT_PATTERNS =
85 new String[]{ "**/*.jar", "**/*.pom", "**/*.rar", "**/*.zip", "**/*.war", "**/*.tar.gz" };
87 private ManagedRepository createDefaultRepository() throws IOException {
89 Paths.get( System.getProperty( "basedir" ), "src/test/repositories/default-repository" );
91 assertTrue( "Default Test Repository should exist.", Files.exists(repoDir) && Files.isDirectory(repoDir) );
93 return createRepository( "testDefaultRepo", "Test Default Repository", repoDir );
96 private ManagedRepository createSimpleRepository()
97 throws IOException, ParseException
99 Path srcDir = Paths.get( System.getProperty( "basedir" ), "src/test/repositories/simple-repository" );
101 Path repoDir = Paths.get( System.getProperty( "basedir" ), "target/test-repos/simple-repository" );
103 org.apache.archiva.common.utils.FileUtils.deleteDirectory( repoDir );
105 FileUtils.copyDirectory( srcDir.toFile(), repoDir.toFile() );
107 Path repoFile = repoDir.resolve(
108 "groupId/snapshot-artifact/1.0-alpha-1-SNAPSHOT/snapshot-artifact-1.0-alpha-1-20050611.202024-1.pom" );
109 Files.setLastModifiedTime(repoFile, FileTime.fromMillis(getTimestampAsMillis( "20050611.202024" ) ));
111 assertTrue( "Simple Test Repository should exist.", Files.exists(repoDir) && Files.isDirectory(repoDir) );
113 return createRepository( "testSimpleRepo", "Test Simple Repository", repoDir );
116 private static long getTimestampAsMillis( String timestamp )
117 throws ParseException
119 SimpleDateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss", Locale.US );
120 fmt.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
121 return fmt.parse( timestamp ).getTime();
124 private ManagedRepository createLegacyRepository() throws IOException {
125 Path repoDir = Paths.get( System.getProperty( "basedir" ), "src/test/repositories/legacy-repository" );
127 assertTrue( "Legacy Test Repository should exist.", Files.exists(repoDir) && Files.isDirectory(repoDir) );
129 EditableManagedRepository repo = createRepository( "testLegacyRepo", "Test Legacy Repository", repoDir );
130 repo.setLayout( "legacy" );
135 private void assertMinimumHits( String msg, int minimumHitCount, long actualCount )
137 if ( actualCount < minimumHitCount )
139 fail( "Minimum hit count on " + msg + " not satisfied. Expected more than <" + minimumHitCount
140 + ">, but actually got <" + actualCount + ">." );
144 private RepositoryScanner lookupRepositoryScanner()
147 return applicationContext.getBean( RepositoryScanner.class );
150 private List<String> getIgnoreList()
152 List<String> ignores = new ArrayList<>();
153 ignores.addAll( Arrays.asList( RepositoryScanner.IGNORABLE_CONTENT ) );
158 public void testTimestampRepositoryScanner()
161 ManagedRepository repository = createSimpleRepository();
163 List<KnownRepositoryContentConsumer> knownConsumers = new ArrayList<>();
164 KnownScanConsumer consumer = new KnownScanConsumer();
165 consumer.setIncludes( ARTIFACT_PATTERNS );
166 knownConsumers.add( consumer );
168 List<InvalidRepositoryContentConsumer> invalidConsumers = new ArrayList<>();
169 InvalidScanConsumer badconsumer = new InvalidScanConsumer();
170 invalidConsumers.add( badconsumer );
172 RepositoryScanner scanner = lookupRepositoryScanner();
174 RepositoryScanStatistics stats = scanner.scan( repository, knownConsumers, invalidConsumers, getIgnoreList(),
175 getTimestampAsMillis( "20061101.000000" ) );
177 assertNotNull( "Stats should not be null.", stats );
178 assertEquals( "Stats.totalFileCount", 4, stats.getTotalFileCount() );
179 assertEquals( "Stats.newFileCount", 3, stats.getNewFileCount() );
180 assertEquals( "Processed Count", 2, consumer.getProcessCount() );
181 assertEquals( "Processed Count (of invalid items)", 1, badconsumer.getProcessCount() );
185 public void testTimestampRepositoryScannerFreshScan()
188 ManagedRepository repository = createSimpleRepository();
190 List<KnownRepositoryContentConsumer> knownConsumers = new ArrayList<>();
191 KnownScanConsumer consumer = new KnownScanConsumer();
192 consumer.setIncludes( ARTIFACT_PATTERNS );
193 knownConsumers.add( consumer );
195 List<InvalidRepositoryContentConsumer> invalidConsumers = new ArrayList<>();
196 InvalidScanConsumer badconsumer = new InvalidScanConsumer();
197 invalidConsumers.add( badconsumer );
199 RepositoryScanner scanner = lookupRepositoryScanner();
200 RepositoryScanStatistics stats =
201 scanner.scan( repository, knownConsumers, invalidConsumers, getIgnoreList(), RepositoryScanner.FRESH_SCAN );
203 assertNotNull( "Stats should not be null.", stats );
204 assertEquals( "Stats.totalFileCount", 4, stats.getTotalFileCount() );
205 assertEquals( "Stats.newFileCount", 4, stats.getNewFileCount() );
206 assertEquals( "Processed Count", 3, consumer.getProcessCount() );
207 assertEquals( "Processed Count (of invalid items)", 1, badconsumer.getProcessCount() );
211 public void testTimestampRepositoryScannerProcessUnmodified()
214 ManagedRepository repository = createSimpleRepository();
216 List<KnownRepositoryContentConsumer> knownConsumers = new ArrayList<>();
217 KnownScanConsumer consumer = new KnownScanConsumer();
218 consumer.setProcessUnmodified( true );
219 consumer.setIncludes( ARTIFACT_PATTERNS );
220 knownConsumers.add( consumer );
222 List<InvalidRepositoryContentConsumer> invalidConsumers = new ArrayList<>();
223 InvalidScanConsumer badconsumer = new InvalidScanConsumer();
224 invalidConsumers.add( badconsumer );
226 RepositoryScanner scanner = lookupRepositoryScanner();
227 RepositoryScanStatistics stats = scanner.scan( repository, knownConsumers, invalidConsumers, getIgnoreList(),
228 getTimestampAsMillis( "20061101.000000" ) );
230 assertNotNull( "Stats should not be null.", stats );
231 assertEquals( "Stats.totalFileCount", 4, stats.getTotalFileCount() );
232 assertEquals( "Stats.newFileCount", 3, stats.getNewFileCount() );
233 assertEquals( "Processed Count", 3, consumer.getProcessCount() );
234 assertEquals( "Processed Count (of invalid items)", 1, badconsumer.getProcessCount() );
238 public void testDefaultRepositoryScanner()
241 ManagedRepository repository = createDefaultRepository();
243 List<KnownRepositoryContentConsumer> knownConsumers = new ArrayList<>();
244 KnownScanConsumer consumer = new KnownScanConsumer();
245 consumer.setIncludes(
246 new String[]{ "**/*.jar", "**/*.war", "**/*.pom", "**/maven-metadata.xml", "**/*-site.xml", "**/*.zip",
247 "**/*.tar.gz", "**/*.sha1", "**/*.md5" }
249 knownConsumers.add( consumer );
251 List<InvalidRepositoryContentConsumer> invalidConsumers = new ArrayList<>();
252 InvalidScanConsumer badconsumer = new InvalidScanConsumer();
253 invalidConsumers.add( badconsumer );
255 RepositoryScanner scanner = lookupRepositoryScanner();
256 RepositoryScanStatistics stats =
257 scanner.scan( repository, knownConsumers, invalidConsumers, getIgnoreList(), RepositoryScanner.FRESH_SCAN );
259 assertNotNull( "Stats should not be null.", stats );
260 assertMinimumHits( "Stats.totalFileCount", 17, stats.getTotalFileCount() );
261 assertMinimumHits( "Processed Count", 17, consumer.getProcessCount() );
262 assertEquals( "Processed Count (of invalid items):" + badconsumer.getPaths(), 6, badconsumer.getProcessCount() );
266 public void testDefaultRepositoryArtifactScanner()
269 List<String> actualArtifactPaths = new ArrayList<>();
271 actualArtifactPaths.add( "invalid/invalid/1.0-20050611.123456-1/invalid-1.0-20050611.123456-1.jar" );
272 actualArtifactPaths.add( "invalid/invalid/1.0-SNAPSHOT/invalid-1.0.jar" );
273 actualArtifactPaths.add( "invalid/invalid/1.0/invalid-1.0b.jar" );
274 actualArtifactPaths.add( "invalid/invalid/1.0/invalid-2.0.jar" );
275 actualArtifactPaths.add( "invalid/invalid-1.0.jar" );
276 actualArtifactPaths.add( "org/apache/maven/test/1.0-SNAPSHOT/wrong-artifactId-1.0-20050611.112233-1.jar" );
277 actualArtifactPaths.add( "org/apache/maven/test/1.0-SNAPSHOT/test-1.0-20050611.112233-1-javadoc.jar" );
278 actualArtifactPaths.add( "org/apache/maven/test/1.0-SNAPSHOT/test-1.0-20050611.112233-1.jar" );
279 actualArtifactPaths.add( "org/apache/maven/A/1.0/A-1.0.war" );
280 actualArtifactPaths.add( "org/apache/maven/A/1.0/A-1.0.pom" );
281 actualArtifactPaths.add( "org/apache/maven/B/2.0/B-2.0.pom" );
282 actualArtifactPaths.add( "org/apache/maven/B/1.0/B-1.0.pom" );
283 actualArtifactPaths.add( "org/apache/maven/some-ejb/1.0/some-ejb-1.0-client.jar" );
284 actualArtifactPaths.add( "org/apache/maven/C/1.0/C-1.0.war" );
285 actualArtifactPaths.add( "org/apache/maven/C/1.0/C-1.0.pom" );
286 actualArtifactPaths.add( "org/apache/maven/update/test-not-updated/1.0/test-not-updated-1.0.pom" );
287 actualArtifactPaths.add( "org/apache/maven/update/test-not-updated/1.0/test-not-updated-1.0.jar" );
288 actualArtifactPaths.add( "org/apache/maven/update/test-updated/1.0/test-updated-1.0.pom" );
289 actualArtifactPaths.add( "org/apache/maven/update/test-updated/1.0/test-updated-1.0.jar" );
290 actualArtifactPaths.add( "org/apache/maven/discovery/1.0/discovery-1.0.pom" );
291 actualArtifactPaths.add( "org/apache/maven/testing/1.0/testing-1.0-test-sources.jar" );
292 actualArtifactPaths.add( "org/apache/maven/testing/1.0/testing-1.0.jar" );
293 actualArtifactPaths.add( "org/apache/maven/testing/1.0/testing-1.0-sources.jar" );
294 actualArtifactPaths.add( "org/apache/maven/testing/1.0/testing-1.0.zip" );
295 actualArtifactPaths.add( "org/apache/maven/testing/1.0/testing-1.0.tar.gz" );
296 actualArtifactPaths.add( "org/apache/maven/samplejar/2.0/samplejar-2.0.pom" );
297 actualArtifactPaths.add( "org/apache/maven/samplejar/2.0/samplejar-2.0.jar" );
298 actualArtifactPaths.add( "org/apache/maven/samplejar/1.0/samplejar-1.0.pom" );
299 actualArtifactPaths.add( "org/apache/maven/samplejar/1.0/samplejar-1.0.jar" );
300 actualArtifactPaths.add( "org/apache/testgroup/discovery/1.0/discovery-1.0.pom" );
301 actualArtifactPaths.add( "javax/sql/jdbc/2.0/jdbc-2.0.jar" );
303 ManagedRepository repository = createDefaultRepository();
305 List<KnownRepositoryContentConsumer> knownConsumers = new ArrayList<>();
306 KnownScanConsumer consumer = new KnownScanConsumer();
307 consumer.setIncludes( ARTIFACT_PATTERNS );
308 knownConsumers.add( consumer );
310 List<InvalidRepositoryContentConsumer> invalidConsumers = new ArrayList<>();
311 InvalidScanConsumer badconsumer = new InvalidScanConsumer();
312 invalidConsumers.add( badconsumer );
314 RepositoryScanner scanner = lookupRepositoryScanner();
315 RepositoryScanStatistics stats =
316 scanner.scan( repository, knownConsumers, invalidConsumers, getIgnoreList(), RepositoryScanner.FRESH_SCAN );
318 assertNotNull( "Stats should not be null.", stats );
319 assertMinimumHits( "Stats.totalFileCount", actualArtifactPaths.size(), stats.getTotalFileCount() );
320 assertMinimumHits( "Processed Count", actualArtifactPaths.size(), consumer.getProcessCount() );
324 public void testDefaultRepositoryMetadataScanner()
327 List<String> actualMetadataPaths = new ArrayList<>();
329 actualMetadataPaths.add( "org/apache/maven/some-ejb/1.0/maven-metadata.xml" );
330 actualMetadataPaths.add( "org/apache/maven/update/test-not-updated/maven-metadata.xml" );
331 actualMetadataPaths.add( "org/apache/maven/update/test-updated/maven-metadata.xml" );
332 actualMetadataPaths.add( "org/apache/maven/maven-metadata.xml" );
333 actualMetadataPaths.add( "org/apache/testgroup/discovery/1.0/maven-metadata.xml" );
334 actualMetadataPaths.add( "org/apache/testgroup/discovery/maven-metadata.xml" );
335 actualMetadataPaths.add( "javax/sql/jdbc/2.0/maven-metadata-repository.xml" );
336 actualMetadataPaths.add( "javax/sql/jdbc/maven-metadata-repository.xml" );
337 actualMetadataPaths.add( "javax/sql/maven-metadata-repository.xml" );
338 actualMetadataPaths.add( "javax/maven-metadata.xml" );
340 ManagedRepository repository = createDefaultRepository();
342 List<KnownRepositoryContentConsumer> knownConsumers = new ArrayList<>();
343 KnownScanConsumer knownConsumer = new KnownScanConsumer();
344 knownConsumer.setIncludes( new String[]{ "**/maven-metadata*.xml" } );
345 knownConsumers.add( knownConsumer );
347 List<InvalidRepositoryContentConsumer> invalidConsumers = new ArrayList<>();
348 InvalidScanConsumer badconsumer = new InvalidScanConsumer();
349 invalidConsumers.add( badconsumer );
351 RepositoryScanner scanner = lookupRepositoryScanner();
352 RepositoryScanStatistics stats =
353 scanner.scan( repository, knownConsumers, invalidConsumers, getIgnoreList(), RepositoryScanner.FRESH_SCAN );
355 assertNotNull( "Stats should not be null.", stats );
356 assertMinimumHits( "Stats.totalFileCount", actualMetadataPaths.size(), stats.getTotalFileCount() );
357 assertMinimumHits( "Processed Count", actualMetadataPaths.size(), knownConsumer.getProcessCount() );
361 public void testDefaultRepositoryProjectScanner()
364 List<String> actualProjectPaths = new ArrayList<>();
366 actualProjectPaths.add( "org/apache/maven/A/1.0/A-1.0.pom" );
367 actualProjectPaths.add( "org/apache/maven/B/2.0/B-2.0.pom" );
368 actualProjectPaths.add( "org/apache/maven/B/1.0/B-1.0.pom" );
369 actualProjectPaths.add( "org/apache/maven/C/1.0/C-1.0.pom" );
370 actualProjectPaths.add( "org/apache/maven/update/test-not-updated/1.0/test-not-updated-1.0.pom" );
371 actualProjectPaths.add( "org/apache/maven/update/test-updated/1.0/test-updated-1.0.pom" );
372 actualProjectPaths.add( "org/apache/maven/discovery/1.0/discovery-1.0.pom" );
373 actualProjectPaths.add( "org/apache/maven/samplejar/2.0/samplejar-2.0.pom" );
374 actualProjectPaths.add( "org/apache/maven/samplejar/1.0/samplejar-1.0.pom" );
375 actualProjectPaths.add( "org/apache/testgroup/discovery/1.0/discovery-1.0.pom" );
377 ManagedRepository repository = createDefaultRepository();
379 List<KnownRepositoryContentConsumer> knownConsumers = new ArrayList<>();
380 KnownScanConsumer consumer = new KnownScanConsumer();
381 consumer.setIncludes( new String[]{ "**/*.pom" } );
382 knownConsumers.add( consumer );
384 List<InvalidRepositoryContentConsumer> invalidConsumers = new ArrayList<>();
385 InvalidScanConsumer badconsumer = new InvalidScanConsumer();
386 invalidConsumers.add( badconsumer );
388 RepositoryScanner scanner = lookupRepositoryScanner();
389 RepositoryScanStatistics stats =
390 scanner.scan( repository, knownConsumers, invalidConsumers, getIgnoreList(), RepositoryScanner.FRESH_SCAN );
392 assertNotNull( "Stats should not be null.", stats );
393 assertMinimumHits( "Stats.totalFileCount", actualProjectPaths.size(), stats.getTotalFileCount() );
394 assertMinimumHits( "Processed Count", actualProjectPaths.size(), consumer.getProcessCount() );
398 public void testLegacyRepositoryArtifactScanner()
401 List<String> actualArtifactPaths = new ArrayList<>();
403 actualArtifactPaths.add( "invalid/jars/1.0/invalid-1.0.jar" );
404 actualArtifactPaths.add( "invalid/jars/invalid-1.0.rar" );
405 actualArtifactPaths.add( "invalid/jars/invalid.jar" );
406 actualArtifactPaths.add( "invalid/invalid-1.0.jar" );
407 actualArtifactPaths.add( "javax.sql/jars/jdbc-2.0.jar" );
408 actualArtifactPaths.add( "org.apache.maven/jars/some-ejb-1.0-client.jar" );
409 actualArtifactPaths.add( "org.apache.maven/jars/testing-1.0.jar" );
410 actualArtifactPaths.add( "org.apache.maven/jars/testing-1.0-sources.jar" );
411 actualArtifactPaths.add( "org.apache.maven/jars/testing-UNKNOWN.jar" );
412 actualArtifactPaths.add( "org.apache.maven/jars/testing-1.0.zip" );
413 actualArtifactPaths.add( "org.apache.maven/jars/testing-1.0-20050611.112233-1.jar" );
414 actualArtifactPaths.add( "org.apache.maven/jars/testing-1.0.tar.gz" );
415 actualArtifactPaths.add( "org.apache.maven.update/jars/test-not-updated-1.0.jar" );
416 actualArtifactPaths.add( "org.apache.maven.update/jars/test-updated-1.0.jar" );
418 ManagedRepository repository = createLegacyRepository();
420 List<KnownRepositoryContentConsumer> knownConsumers = new ArrayList<>();
421 KnownScanConsumer consumer = new KnownScanConsumer();
422 consumer.setIncludes( ARTIFACT_PATTERNS );
423 knownConsumers.add( consumer );
425 List<InvalidRepositoryContentConsumer> invalidConsumers = new ArrayList<>();
426 InvalidScanConsumer badconsumer = new InvalidScanConsumer();
427 invalidConsumers.add( badconsumer );
429 RepositoryScanner scanner = lookupRepositoryScanner();
430 RepositoryScanStatistics stats =
431 scanner.scan( repository, knownConsumers, invalidConsumers, getIgnoreList(), RepositoryScanner.FRESH_SCAN );
433 assertNotNull( "Stats should not be null.", stats );
434 assertMinimumHits( "Stats.totalFileCount", actualArtifactPaths.size(), stats.getTotalFileCount() );
435 assertMinimumHits( "Processed Count", actualArtifactPaths.size(), consumer.getProcessCount() );