1 package org.apache.archiva.metadata.repository.stats;
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.metadata.model.MetadataFacetFactory;
24 import org.apache.archiva.metadata.repository.AbstractMetadataRepositoryTest;
25 import org.apache.archiva.metadata.repository.DefaultMetadataResolver;
26 import org.apache.archiva.metadata.repository.MetadataRepository;
27 import org.apache.archiva.metadata.repository.MetadataRepositoryException;
28 import org.apache.archiva.metadata.repository.MetadataService;
29 import org.apache.archiva.metadata.repository.RepositorySession;
30 import org.apache.archiva.metadata.repository.RepositorySessionFactory;
31 import org.apache.archiva.metadata.repository.jcr.JcrMetadataRepository;
32 import org.apache.archiva.metadata.repository.jcr.JcrRepositorySessionFactory;
33 import org.apache.archiva.metadata.repository.jcr.JcrRepositorySession;
34 import org.apache.archiva.metadata.repository.stats.model.DefaultRepositoryStatistics;
35 import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
36 import org.apache.jackrabbit.commons.JcrUtils;
37 import org.apache.jackrabbit.oak.segment.file.InvalidFileStoreVersionException;
38 import org.junit.After;
39 import org.junit.AfterClass;
40 import org.junit.BeforeClass;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45 import org.springframework.test.context.ContextConfiguration;
47 import javax.jcr.ImportUUIDBehavior;
48 import javax.jcr.Node;
49 import javax.jcr.Repository;
50 import javax.jcr.RepositoryException;
51 import javax.jcr.Session;
52 import javax.jcr.nodetype.NodeTypeManager;
53 import javax.jcr.nodetype.NodeTypeTemplate;
54 import java.io.IOException;
55 import java.io.InputStream;
56 import java.nio.file.Files;
57 import java.nio.file.Path;
58 import java.nio.file.Paths;
59 import java.util.Calendar;
60 import java.util.Date;
61 import java.util.List;
63 import java.util.zip.GZIPInputStream;
65 @RunWith( ArchivaSpringJUnit4ClassRunner.class )
66 @ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } )
67 public class JcrRepositoryStatisticsGatheringTest
70 private static final Logger log = LoggerFactory.getLogger( JcrRepositoryStatisticsGatheringTest.class );
71 private static final int TOTAL_FILE_COUNT = 1000;
73 private static final int NEW_FILE_COUNT = 500;
75 private static final String TEST_REPO = "test-repo";
77 static JcrMetadataRepository repository;
78 static JcrRepositorySessionFactory sessionFactory;
82 private static Repository jcrRepository;
84 Logger logger = LoggerFactory.getLogger( getClass() );
85 private int assertRetrySleepMs = 500;
86 private int assertMaxTries = 5;
89 public static void setupSpec()
90 throws IOException, InvalidFileStoreVersionException
92 Path directory = Paths.get( "target/test-repositories" );
93 if ( Files.exists(directory) )
95 org.apache.archiva.common.utils.FileUtils.deleteDirectory( directory );
97 directory = Paths.get( "target/jcr" );
98 if (Files.exists( directory )) {
99 org.apache.archiva.common.utils.FileUtils.deleteDirectory( directory );
102 List<MetadataFacetFactory> factories = AbstractMetadataRepositoryTest.createTestMetadataFacetFactories();
104 MetadataService metadataService = new MetadataService( );
105 metadataService.setMetadataFacetFactories( factories );
107 JcrRepositorySessionFactory jcrSessionFactory = new JcrRepositorySessionFactory();
108 jcrSessionFactory.setMetadataResolver(new DefaultMetadataResolver());
109 jcrSessionFactory.setMetadataService(metadataService);
111 jcrSessionFactory.open();
112 sessionFactory = jcrSessionFactory;
113 repository = jcrSessionFactory.getMetadataRepository();
118 public static void stopSpec() {
123 catch ( MetadataRepositoryException e )
125 e.printStackTrace( );
127 sessionFactory.close();
131 * Used by tryAssert to allow to throw exceptions in the lambda expression.
134 protected interface AssertFunction
136 void accept( ) throws Exception;
139 protected void tryAssert( AssertFunction func ) throws Exception
141 tryAssert( func, assertMaxTries, assertRetrySleepMs );
146 * Runs the assert method until the assert is successful or the number of retries
147 * is reached. This is needed because the JCR Oak index update is asynchronous, so updates
148 * may not be visible immediately after the modification.
150 private void tryAssert( AssertFunction func, int retries, int sleepMillis ) throws Exception
154 while ( retry-- > 0 )
161 catch ( Exception | AssertionError e )
164 Thread.currentThread( ).sleep( sleepMillis );
165 log.warn( "Retrying assert {}: {}", retry, e.getMessage( ) );
168 log.warn( "Retries: {}, Exception: {}", retry, t.getMessage( ) );
169 if ( retry <= 0 && t != null )
171 if ( t instanceof RuntimeException )
173 throw (RuntimeException) t;
175 else if ( t instanceof Exception )
179 else if ( t instanceof Error )
186 private static void registerMixinNodeType( NodeTypeManager nodeTypeManager, String type )
187 throws RepositoryException
189 NodeTypeTemplate nodeType = nodeTypeManager.createNodeTypeTemplate();
190 nodeType.setMixin( true );
191 nodeType.setName( type );
192 nodeTypeManager.registerNodeType( nodeType, false );
196 public void tearDown()
199 if ( repository != null )
204 } catch (Throwable e) {
208 if (sessionFactory!=null) {
211 sessionFactory.close( );
212 } catch (Throwable e) {
221 public void testJcrStatisticsQuery()
224 try(RepositorySession repSession = sessionFactory.createSession()) {
225 Calendar cal = Calendar.getInstance();
226 Date endTime = cal.getTime();
227 cal.add(Calendar.HOUR, -1);
228 Date startTime = cal.getTime();
230 loadContentIntoRepo(repSession, TEST_REPO);
231 loadContentIntoRepo( repSession, "another-repo");
233 DefaultRepositoryStatistics testedStatistics = new DefaultRepositoryStatistics();
234 testedStatistics.setNewFileCount(NEW_FILE_COUNT);
235 testedStatistics.setTotalFileCount(TOTAL_FILE_COUNT);
236 testedStatistics.setScanStartTime(startTime);
237 testedStatistics.setScanEndTime(endTime);
240 DefaultRepositoryStatistics expectedStatistics = new DefaultRepositoryStatistics();
241 expectedStatistics.setNewFileCount(NEW_FILE_COUNT);
242 expectedStatistics.setTotalFileCount(TOTAL_FILE_COUNT);
243 expectedStatistics.setScanEndTime(endTime);
244 expectedStatistics.setScanStartTime(startTime);
245 expectedStatistics.setTotalArtifactFileSize(95954585);
246 expectedStatistics.setTotalArtifactCount(269);
247 expectedStatistics.setTotalGroupCount(1);
248 expectedStatistics.setTotalProjectCount(43);
249 expectedStatistics.setTotalCountForType("zip", 1);
250 expectedStatistics.setTotalCountForType("gz", 1); // FIXME: should be tar.gz
251 expectedStatistics.setTotalCountForType("java-source", 10);
252 expectedStatistics.setTotalCountForType("jar", 108);
253 expectedStatistics.setTotalCountForType("xml", 3);
254 expectedStatistics.setTotalCountForType("war", 2);
255 expectedStatistics.setTotalCountForType("pom", 144);
256 expectedStatistics.setRepositoryId(TEST_REPO);
259 repository.populateStatistics(repSession, repository, TEST_REPO, testedStatistics);
261 logger.info("getTotalCountForType: {}", testedStatistics.getTotalCountForType());
263 assertEquals(NEW_FILE_COUNT, testedStatistics.getNewFileCount());
264 assertEquals(TOTAL_FILE_COUNT, testedStatistics.getTotalFileCount());
265 assertEquals(endTime, testedStatistics.getScanEndTime());
266 assertEquals(startTime, testedStatistics.getScanStartTime());
267 assertEquals(269, testedStatistics.getTotalArtifactCount());
268 assertEquals(1, testedStatistics.getTotalGroupCount());
269 assertEquals(43, testedStatistics.getTotalProjectCount());
270 assertEquals(1, testedStatistics.getTotalCountForType("zip"));
271 assertEquals(1, testedStatistics.getTotalCountForType("gz"));
272 assertEquals(10, testedStatistics.getTotalCountForType("java-source"));
273 assertEquals(108, testedStatistics.getTotalCountForType("jar"));
274 assertEquals(3, testedStatistics.getTotalCountForType("xml"));
275 assertEquals(2, testedStatistics.getTotalCountForType("war"));
276 assertEquals(144, testedStatistics.getTotalCountForType("pom"));
277 assertEquals(10, testedStatistics.getTotalCountForType("java-source"));
278 assertEquals(95954585, testedStatistics.getTotalArtifactFileSize());
284 private void loadContentIntoRepo( RepositorySession repoSession, String repoId )
285 throws RepositoryException, IOException, MetadataRepositoryException
287 jcrSession = ((JcrRepositorySession) repoSession).getJcrSession();
288 Node n = JcrUtils.getOrAddNode( jcrSession.getRootNode( ), "repositories" );
289 n = JcrUtils.getOrAddNode( n, repoId );
290 n = JcrUtils.getOrAddNode( n, "content" );
291 n = JcrUtils.getOrAddNode( n, "org" );
292 n = JcrUtils.getOrAddNode( n, "apache" );
294 InputStream inputStream = getClass( ).getResourceAsStream( "/artifacts.xml" );
295 jcrSession.importXML( n.getPath( ), inputStream, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW );