1 package org.apache.archiva.consumers.core.repository;
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 org.apache.archiva.metadata.model.ArtifactMetadata;
23 import org.apache.archiva.repository.events.RepositoryListener;
24 import org.apache.archiva.repository.features.ArtifactCleanupFeature;
25 import org.apache.commons.lang3.time.DateUtils;
26 import org.easymock.EasyMock;
27 import org.junit.After;
28 import org.junit.Test;
29 import org.mockito.ArgumentCaptor;
31 import java.io.IOException;
32 import java.nio.file.Files;
33 import java.nio.file.Path;
34 import java.nio.file.Paths;
35 import java.nio.file.attribute.FileTime;
36 import java.text.SimpleDateFormat;
39 import static org.junit.Assert.assertTrue;
40 import static org.mockito.Matchers.eq;
41 import static org.mockito.Mockito.*;
45 public class DaysOldRepositoryPurgeTest
46 extends AbstractRepositoryPurgeTest
48 private static final int OLD_TIMESTAMP = 1179382029;
50 private void setLastModified( String dirPath, long lastModified ) throws IOException
52 Path dir = Paths.get( dirPath );
53 Path[] contents = Files.list( dir ).toArray(Path[]::new );
54 for ( Path content : contents )
56 Files.setLastModifiedTime( content, FileTime.fromMillis( lastModified ));
62 public void tearDown()
70 public void testByLastModified()
73 org.apache.archiva.repository.ManagedRepository repoConfiguration = getRepoConfiguration( TEST_REPO_ID, TEST_REPO_NAME );
74 ArtifactCleanupFeature atf = repoConfiguration.getFeature( ArtifactCleanupFeature.class ).get();
77 sessionControl.reset();
78 sessionFactoryControl.reset();
79 EasyMock.expect( sessionFactory.createSession( ) ).andStubReturn( repositorySession );
80 EasyMock.expect( repositorySession.getRepository()).andStubReturn( metadataRepository );
81 repositorySession.save();
82 EasyMock.expectLastCall().anyTimes();
83 sessionFactoryControl.replay();
84 sessionControl.replay();
86 repoPurge = new DaysOldRepositoryPurge( getRepository(), atf.getRetentionPeriod().getDays(),
87 atf.getRetentionCount(), repositorySession,
88 Collections.singletonList( listener ) );
90 String repoRoot = prepareTestRepos();
91 String projectNs = "org.apache.maven.plugins";
92 String projectPath = projectNs.replaceAll("\\.","/");
93 String projectName = "maven-install-plugin";
94 String projectVersion = "2.2-SNAPSHOT";
95 String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
96 Path repo = getTestRepoRootPath();
97 Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
98 Set<String> deletedVersions = new HashSet<>();
99 deletedVersions.add("2.2-SNAPSHOT");
100 deletedVersions.add("2.2-20061118.060401-2");
102 setLastModified( projectRoot + "/" + projectVersion + "/", OLD_TIMESTAMP );
104 // test listeners for the correct artifacts
105 String[] exts = {".md5",".sha1",""};
106 for (int i=0; i<exts.length; i++) {
108 listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.apache.maven.plugins",
109 "maven-install-plugin", "2.2-SNAPSHOT", "maven-install-plugin-2.2-SNAPSHOT.jar"+exts[i]);
110 listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.apache.maven.plugins",
111 "maven-install-plugin", "2.2-SNAPSHOT", "maven-install-plugin-2.2-SNAPSHOT.pom"+exts[i]);
112 listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.apache.maven.plugins",
113 "maven-install-plugin", "2.2-20061118.060401-2",
114 "maven-install-plugin-2.2-20061118.060401-2.jar"+exts[i]);
115 listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.apache.maven.plugins",
116 "maven-install-plugin", "2.2-20061118.060401-2",
117 "maven-install-plugin-2.2-20061118.060401-2.pom"+exts[i]);
119 listenerControl.replay();
121 // Provide the metadata list
122 List<ArtifactMetadata> ml = getArtifactMetadataFromDir(TEST_REPO_ID , projectName, repo.getParent(), vDir );
123 when(metadataRepository.getArtifacts( repositorySession, TEST_REPO_ID,
124 projectNs, projectName, projectVersion )).thenReturn(ml);
126 repoPurge.process( PATH_TO_BY_DAYS_OLD_ARTIFACT );
128 listenerControl.verify();
130 // Verify the metadataRepository invocations
131 verify(metadataRepository, never()).removeProjectVersion(eq(repositorySession) , eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion) );
132 ArgumentCaptor<ArtifactMetadata> metadataArg = ArgumentCaptor.forClass(ArtifactMetadata.class);
133 verify(metadataRepository, times(2)).removeTimestampedArtifact(eq(repositorySession) , metadataArg.capture(), eq(projectVersion) );
134 List<ArtifactMetadata> metaL = metadataArg.getAllValues();
135 for (ArtifactMetadata meta : metaL) {
136 assertTrue(meta.getId().startsWith(projectName));
137 assertTrue(deletedVersions.contains(meta.getVersion()));
141 assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.jar" );
142 assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.jar.md5" );
143 assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.jar.sha1" );
144 assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.pom" );
145 assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.pom.md5" );
146 assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.pom.sha1" );
148 // shouldn't be deleted because even if older than 30 days (because retention count = 2)
149 assertExists( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20070513.034619-5.jar" );
150 assertExists( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20070513.034619-5.jar.md5" );
151 assertExists( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20070513.034619-5.jar.sha1" );
152 assertExists( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20070513.034619-5.pom" );
153 assertExists( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20070513.034619-5.pom.md5" );
154 assertExists( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20070513.034619-5.pom.sha1" );
156 assertExists( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20070510.010101-4.jar" );
157 assertExists( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20070510.010101-4.jar.md5" );
158 assertExists( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20070510.010101-4.jar.sha1" );
159 assertExists( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20070510.010101-4.pom" );
160 assertExists( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20070510.010101-4.pom.md5" );
161 assertExists( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20070510.010101-4.pom.sha1" );
163 assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20061118.060401-2.jar" );
164 assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20061118.060401-2.jar.md5" );
165 assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20061118.060401-2.jar.sha1" );
166 assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20061118.060401-2.pom" );
167 assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20061118.060401-2.pom.md5" );
168 assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-20061118.060401-2.pom.sha1" );
172 public void testOrderOfDeletion()
175 org.apache.archiva.repository.ManagedRepository repoConfiguration = getRepoConfiguration( TEST_REPO_ID, TEST_REPO_NAME );
176 ArtifactCleanupFeature atf = repoConfiguration.getFeature( ArtifactCleanupFeature.class ).get();
177 List<RepositoryListener> listeners = Collections.singletonList( listener );
179 sessionControl.reset();
180 sessionFactoryControl.reset();
181 EasyMock.expect( sessionFactory.createSession( ) ).andStubReturn( repositorySession );
182 EasyMock.expect( repositorySession.getRepository()).andStubReturn( metadataRepository );
183 repositorySession.save();
184 EasyMock.expectLastCall().anyTimes();
185 sessionFactoryControl.replay();
186 sessionControl.replay();
187 repoPurge = new DaysOldRepositoryPurge( getRepository(), atf.getRetentionPeriod().getDays(),
188 atf.getRetentionCount(), repositorySession, listeners );
190 String repoRoot = prepareTestRepos();
191 String projectNs = "org.apache.maven.plugins";
192 String projectPath = projectNs.replaceAll("\\.","/");
193 String projectName = "maven-assembly-plugin";
194 String projectVersion = "1.1.2-SNAPSHOT";
195 String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
196 Path repo = getTestRepoRootPath();
197 Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
198 Set<String> deletedVersions = new HashSet<>();
199 deletedVersions.add("1.1.2-20070427.065136-1");
201 setLastModified( projectRoot + "/" + projectVersion + "/", OLD_TIMESTAMP );
203 // test listeners for the correct artifacts
204 String[] exts = {".md5",".sha1",""};
205 for (int i=0; i<exts.length; i++) {
206 listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.apache.maven.plugins",
207 "maven-assembly-plugin", "1.1.2-20070427.065136-1",
208 "maven-assembly-plugin-1.1.2-20070427.065136-1.jar"+exts[i]);
209 listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.apache.maven.plugins",
210 "maven-assembly-plugin", "1.1.2-20070427.065136-1",
211 "maven-assembly-plugin-1.1.2-20070427.065136-1.pom"+exts[i]);
213 listenerControl.replay();
215 // Provide the metadata list
216 List<ArtifactMetadata> ml = getArtifactMetadataFromDir(TEST_REPO_ID , projectName, repo.getParent(), vDir );
217 when(metadataRepository.getArtifacts(repositorySession , TEST_REPO_ID,
218 projectNs, projectName, projectVersion )).thenReturn(ml);
221 repoPurge.process( PATH_TO_TEST_ORDER_OF_DELETION );
223 listenerControl.verify();
225 // Verify the metadataRepository invocations
226 verify(metadataRepository, never()).removeProjectVersion(eq(repositorySession) , eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion) );
227 ArgumentCaptor<ArtifactMetadata> metadataArg = ArgumentCaptor.forClass(ArtifactMetadata.class);
228 verify(metadataRepository, times(deletedVersions.size())).removeTimestampedArtifact(eq(repositorySession) , metadataArg.capture(), eq(projectVersion) );
229 List<ArtifactMetadata> metaL = metadataArg.getAllValues();
230 for (ArtifactMetadata meta : metaL) {
231 assertTrue(meta.getId().startsWith(projectName));
232 assertTrue(deletedVersions.contains(meta.getVersion()));
236 assertDeleted( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070427.065136-1.jar" );
237 assertDeleted( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070427.065136-1.jar.sha1" );
238 assertDeleted( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070427.065136-1.jar.md5" );
239 assertDeleted( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070427.065136-1.pom" );
240 assertDeleted( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070427.065136-1.pom.sha1" );
241 assertDeleted( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070427.065136-1.pom.md5" );
243 // the following should not have been deleted
244 assertExists( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070506.163513-2.jar" );
245 assertExists( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070506.163513-2.jar.sha1" );
246 assertExists( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070506.163513-2.jar.md5" );
247 assertExists( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070506.163513-2.pom" );
248 assertExists( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070506.163513-2.pom.sha1" );
249 assertExists( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070506.163513-2.pom.md5" );
251 assertExists( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070615.105019-3.jar" );
252 assertExists( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070615.105019-3.jar.sha1" );
253 assertExists( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070615.105019-3.jar.md5" );
254 assertExists( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070615.105019-3.pom" );
255 assertExists( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070615.105019-3.pom.sha1" );
256 assertExists( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070615.105019-3.pom.md5" );
260 public void testMetadataDrivenSnapshots()
263 org.apache.archiva.repository.ManagedRepository repoConfiguration = getRepoConfiguration( TEST_REPO_ID, TEST_REPO_NAME );
264 ArtifactCleanupFeature atf = repoConfiguration.getFeature( ArtifactCleanupFeature.class ).get();
265 List<RepositoryListener> listeners = Collections.singletonList( listener );
267 sessionControl.reset();
268 sessionFactoryControl.reset();
269 EasyMock.expect( sessionFactory.createSession( ) ).andStubReturn( repositorySession );
270 EasyMock.expect( repositorySession.getRepository()).andStubReturn( metadataRepository );
271 repositorySession.save();
272 EasyMock.expectLastCall().anyTimes();
273 sessionFactoryControl.replay();
274 sessionControl.replay();
275 repoPurge = new DaysOldRepositoryPurge( getRepository(), atf.getRetentionPeriod().getDays(),
276 atf.getRetentionCount(), repositorySession, listeners );
278 String repoRoot = prepareTestRepos();
279 String projectNs = "org.codehaus.plexus";
280 String projectPath = projectNs.replaceAll("\\.","/");
281 String projectName = "plexus-utils";
282 String projectVersion = "1.4.3-SNAPSHOT";
283 String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
284 Path repo = getTestRepoRootPath();
285 Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
286 Set<String> deletedVersions = new HashSet<>();
287 deletedVersions.add("1.4.3-20070113.163208-4");
290 String versionRoot = projectRoot + "/"+ projectVersion;
292 Calendar currentDate = Calendar.getInstance( TimeZone.getTimeZone("UTC") );
293 setLastModified( versionRoot, currentDate.getTimeInMillis() );
295 String timestamp = new SimpleDateFormat( "yyyyMMdd.HHmmss" ).format( currentDate.getTime() );
297 for ( int i = 5; i <= 7; i++ )
299 Path jarFile = Paths.get( versionRoot, "/plexus-utils-1.4.3-" + timestamp + "-" + i + ".jar" );
300 Files.createFile( jarFile );
301 Path pomFile = Paths.get( versionRoot, "/plexus-utils-1.4.3-" + timestamp + "-" + i + ".pom" );
302 Files.createFile(pomFile);
304 // set timestamp to older than 100 days for the first build, but ensure the filename timestamp is honoured instead
307 Files.setLastModifiedTime( jarFile, FileTime.fromMillis( OLD_TIMESTAMP ));
308 Files.setLastModifiedTime( pomFile, FileTime.fromMillis( OLD_TIMESTAMP ));
312 // test listeners for the correct artifacts
313 String[] exts = {".sha1",""};
314 for (int i=0; i<exts.length; i++) {
316 listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.codehaus.plexus", "plexus-utils",
317 "1.4.3-20070113.163208-4", "plexus-utils-1.4.3-20070113.163208-4.jar"+exts[i]);
318 listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.codehaus.plexus", "plexus-utils",
319 "1.4.3-20070113.163208-4", "plexus-utils-1.4.3-20070113.163208-4.pom"+exts[i]);
321 listenerControl.replay();
323 // Provide the metadata list
324 List<ArtifactMetadata> ml = getArtifactMetadataFromDir(TEST_REPO_ID , projectName, repo.getParent(), vDir );
325 when(metadataRepository.getArtifacts(repositorySession , TEST_REPO_ID,
326 projectNs, projectName, projectVersion )).thenReturn(ml);
329 repoPurge.process( PATH_TO_BY_DAYS_OLD_METADATA_DRIVEN_ARTIFACT );
331 listenerControl.verify();
333 // Verify the metadataRepository invocations
334 verify(metadataRepository, never()).removeProjectVersion(eq(repositorySession) , eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion) );
335 ArgumentCaptor<ArtifactMetadata> metadataArg = ArgumentCaptor.forClass(ArtifactMetadata.class);
336 verify(metadataRepository, times(deletedVersions.size())).removeTimestampedArtifact( eq(repositorySession), metadataArg.capture(), eq(projectVersion) );
337 List<ArtifactMetadata> metaL = metadataArg.getAllValues();
338 for (ArtifactMetadata meta : metaL) {
339 assertTrue(meta.getId().startsWith(projectName));
340 assertTrue(deletedVersions.contains(meta.getVersion()));
344 // this should be deleted since the filename version (timestamp) is older than
345 // 100 days even if the last modified date was <100 days ago
346 assertDeleted( versionRoot + "/plexus-utils-1.4.3-20070113.163208-4.jar" );
347 assertDeleted( versionRoot + "/plexus-utils-1.4.3-20070113.163208-4.jar.sha1" );
348 assertDeleted( versionRoot + "/plexus-utils-1.4.3-20070113.163208-4.pom" );
349 assertDeleted( versionRoot + "/plexus-utils-1.4.3-20070113.163208-4.pom.sha1" );
351 // this should not be deleted because last modified date is <100 days ago
352 assertExists( versionRoot + "/plexus-utils-1.4.3-SNAPSHOT.jar" );
353 assertExists( versionRoot + "/plexus-utils-1.4.3-SNAPSHOT.pom" );
355 for ( int i = 5; i <= 7; i++ )
357 assertExists( versionRoot + "/plexus-utils-1.4.3-" + timestamp + "-" + i + ".jar" );
358 assertExists( versionRoot + "/plexus-utils-1.4.3-" + timestamp + "-" + i + ".pom" );