]> source.dussan.org Git - archiva.git/blob
35166df414482828946f284f57fdef2c51cf4bc4
[archiva.git] /
1 package org.apache.archiva.metadata.repository.stats;
2
3 /*
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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
19  * under the License.
20  */
21
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;
46 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
47
48 import javax.jcr.ImportUUIDBehavior;
49 import javax.jcr.Node;
50 import javax.jcr.Repository;
51 import javax.jcr.RepositoryException;
52 import javax.jcr.Session;
53 import javax.jcr.nodetype.NodeTypeManager;
54 import javax.jcr.nodetype.NodeTypeTemplate;
55 import java.io.IOException;
56 import java.io.InputStream;
57 import java.nio.file.Files;
58 import java.nio.file.Path;
59 import java.nio.file.Paths;
60 import java.util.Calendar;
61 import java.util.Date;
62 import java.util.List;
63 import java.util.Map;
64 import java.util.zip.GZIPInputStream;
65
66 @RunWith( SpringJUnit4ClassRunner.class )
67 @ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } )
68 public class JcrRepositoryStatisticsGatheringTest
69     extends TestCase
70 {
71     private static final Logger log = LoggerFactory.getLogger( JcrRepositoryStatisticsGatheringTest.class );
72     private static final int TOTAL_FILE_COUNT = 1000;
73
74     private static final int NEW_FILE_COUNT = 500;
75
76     private static final String TEST_REPO = "test-repo";
77
78     static JcrMetadataRepository repository;
79     static JcrRepositorySessionFactory sessionFactory;
80
81     Session jcrSession;
82
83     private static Repository jcrRepository;
84
85     Logger logger = LoggerFactory.getLogger( getClass() );
86     private int assertRetrySleepMs = 500;
87     private int assertMaxTries = 5;
88
89     @BeforeClass
90     public static void setupSpec()
91         throws IOException, InvalidFileStoreVersionException
92     {
93         Path directory = Paths.get( "target/test-repositories" );
94         if ( Files.exists(directory) )
95         {
96             org.apache.archiva.common.utils.FileUtils.deleteDirectory( directory );
97         }
98         directory = Paths.get( "target/jcr" );
99         if (Files.exists( directory )) {
100             org.apache.archiva.common.utils.FileUtils.deleteDirectory( directory );
101         }
102
103         List<MetadataFacetFactory> factories = AbstractMetadataRepositoryTest.createTestMetadataFacetFactories();
104
105         MetadataService metadataService = new MetadataService( );
106         metadataService.setMetadataFacetFactories( factories );
107
108         JcrRepositorySessionFactory jcrSessionFactory = new JcrRepositorySessionFactory();
109         jcrSessionFactory.setMetadataResolver(new DefaultMetadataResolver());
110         jcrSessionFactory.setMetadataService(metadataService);
111
112         jcrSessionFactory.open();
113         sessionFactory = jcrSessionFactory;
114         repository = jcrSessionFactory.getMetadataRepository();
115     }
116
117
118     @AfterClass
119     public static void stopSpec() {
120         try
121         {
122             repository.close();
123         }
124         catch ( MetadataRepositoryException e )
125         {
126             e.printStackTrace( );
127         }
128         sessionFactory.close();
129     }
130
131     /*
132      * Used by tryAssert to allow to throw exceptions in the lambda expression.
133      */
134     @FunctionalInterface
135     protected interface AssertFunction
136     {
137         void accept( ) throws Exception;
138     }
139
140     protected void tryAssert( AssertFunction func ) throws Exception
141     {
142         tryAssert( func, assertMaxTries, assertRetrySleepMs );
143     }
144
145
146     /*
147      * Runs the assert method until the assert is successful or the number of retries
148      * is reached. This is needed because the JCR Oak index update is asynchronous, so updates
149      * may not be visible immediately after the modification.
150      */
151     private void tryAssert( AssertFunction func, int retries, int sleepMillis ) throws Exception
152     {
153         Throwable t = null;
154         int retry = retries;
155         while ( retry-- > 0 )
156         {
157             try
158             {
159                 func.accept( );
160                 return;
161             }
162             catch ( Exception | AssertionError e )
163             {
164                 t = e;
165                 Thread.currentThread( ).sleep( sleepMillis );
166                 log.warn( "Retrying assert {}: {}", retry, e.getMessage( ) );
167             }
168         }
169         log.warn( "Retries: {}, Exception: {}", retry, t.getMessage( ) );
170         if ( retry <= 0 && t != null )
171         {
172             if ( t instanceof RuntimeException )
173             {
174                 throw (RuntimeException) t;
175             }
176             else if ( t instanceof Exception )
177             {
178                 throw (Exception) t;
179             }
180             else if ( t instanceof Error )
181             {
182                 throw (Error) t;
183             }
184         }
185     }
186
187     private static void registerMixinNodeType( NodeTypeManager nodeTypeManager, String type )
188         throws RepositoryException
189     {
190         NodeTypeTemplate nodeType = nodeTypeManager.createNodeTypeTemplate();
191         nodeType.setMixin( true );
192         nodeType.setName( type );
193         nodeTypeManager.registerNodeType( nodeType, false );
194     }
195
196     @After
197     public void tearDown()
198         throws Exception
199     {
200         if ( repository != null )
201         {
202             try
203             {
204                 repository.close( );
205             } catch (Throwable e) {
206                 //
207             }
208         }
209         if (sessionFactory!=null) {
210             try
211             {
212                 sessionFactory.close( );
213             } catch (Throwable e) {
214                 //
215             }
216         }
217         super.tearDown();
218
219     }
220
221     @Test
222     public void testJcrStatisticsQuery()
223         throws Exception
224     {
225         try(RepositorySession repSession = sessionFactory.createSession()) {
226             Calendar cal = Calendar.getInstance();
227             Date endTime = cal.getTime();
228             cal.add(Calendar.HOUR, -1);
229             Date startTime = cal.getTime();
230
231             loadContentIntoRepo(repSession, TEST_REPO);
232             loadContentIntoRepo( repSession, "another-repo");
233
234             DefaultRepositoryStatistics testedStatistics = new DefaultRepositoryStatistics();
235             testedStatistics.setNewFileCount(NEW_FILE_COUNT);
236             testedStatistics.setTotalFileCount(TOTAL_FILE_COUNT);
237             testedStatistics.setScanStartTime(startTime);
238             testedStatistics.setScanEndTime(endTime);
239
240
241             DefaultRepositoryStatistics expectedStatistics = new DefaultRepositoryStatistics();
242             expectedStatistics.setNewFileCount(NEW_FILE_COUNT);
243             expectedStatistics.setTotalFileCount(TOTAL_FILE_COUNT);
244             expectedStatistics.setScanEndTime(endTime);
245             expectedStatistics.setScanStartTime(startTime);
246             expectedStatistics.setTotalArtifactFileSize(95954585);
247             expectedStatistics.setTotalArtifactCount(269);
248             expectedStatistics.setTotalGroupCount(1);
249             expectedStatistics.setTotalProjectCount(43);
250             expectedStatistics.setTotalCountForType("zip", 1);
251             expectedStatistics.setTotalCountForType("gz", 1); // FIXME: should be tar.gz
252             expectedStatistics.setTotalCountForType("java-source", 10);
253             expectedStatistics.setTotalCountForType("jar", 108);
254             expectedStatistics.setTotalCountForType("xml", 3);
255             expectedStatistics.setTotalCountForType("war", 2);
256             expectedStatistics.setTotalCountForType("pom", 144);
257             expectedStatistics.setRepositoryId(TEST_REPO);
258
259             tryAssert( () -> {
260                 repository.populateStatistics(repSession, repository, TEST_REPO, testedStatistics);
261
262                 logger.info("getTotalCountForType: {}", testedStatistics.getTotalCountForType());
263
264             assertEquals(NEW_FILE_COUNT, testedStatistics.getNewFileCount());
265             assertEquals(TOTAL_FILE_COUNT, testedStatistics.getTotalFileCount());
266             assertEquals(endTime, testedStatistics.getScanEndTime());
267             assertEquals(startTime, testedStatistics.getScanStartTime());
268             assertEquals(269, testedStatistics.getTotalArtifactCount());
269             assertEquals(1, testedStatistics.getTotalGroupCount());
270             assertEquals(43, testedStatistics.getTotalProjectCount());
271             assertEquals(1, testedStatistics.getTotalCountForType("zip"));
272             assertEquals(1, testedStatistics.getTotalCountForType("gz"));
273             assertEquals(10, testedStatistics.getTotalCountForType("java-source"));
274             assertEquals(108, testedStatistics.getTotalCountForType("jar"));
275             assertEquals(3, testedStatistics.getTotalCountForType("xml"));
276             assertEquals(2, testedStatistics.getTotalCountForType("war"));
277             assertEquals(144, testedStatistics.getTotalCountForType("pom"));
278             assertEquals(10, testedStatistics.getTotalCountForType("java-source"));
279             assertEquals(95954585, testedStatistics.getTotalArtifactFileSize());
280         });
281
282         }
283     }
284
285     private void loadContentIntoRepo( RepositorySession repoSession, String repoId )
286         throws RepositoryException, IOException, MetadataRepositoryException
287     {
288             jcrSession = ((JcrRepositorySession) repoSession).getJcrSession();
289         Node n = JcrUtils.getOrAddNode( jcrSession.getRootNode( ), "repositories" );
290         n = JcrUtils.getOrAddNode( n, repoId );
291         n = JcrUtils.getOrAddNode( n, "content" );
292         n = JcrUtils.getOrAddNode( n, "org" );
293         n = JcrUtils.getOrAddNode( n, "apache" );
294
295         InputStream inputStream = getClass( ).getResourceAsStream( "/artifacts.xml" );
296         jcrSession.importXML( n.getPath( ), inputStream, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW );
297         jcrSession.save( );
298     }
299 }