1 package org.apache.maven.archiva.indexer.search;
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.commons.io.FileUtils;
23 import org.apache.lucene.search.Hits;
24 import org.apache.lucene.search.MatchAllDocsQuery;
25 import org.apache.lucene.search.Query;
26 import org.apache.lucene.search.Searcher;
27 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
28 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
29 import org.apache.maven.archiva.indexer.MockConfiguration;
30 import org.apache.maven.archiva.indexer.RepositoryContentIndex;
31 import org.apache.maven.archiva.indexer.RepositoryContentIndexFactory;
32 import org.apache.maven.archiva.indexer.bytecode.BytecodeRecord;
33 import org.apache.maven.archiva.indexer.filecontent.FileContentRecord;
34 import org.apache.maven.archiva.indexer.hashcodes.HashcodesRecord;
35 import org.codehaus.plexus.spring.PlexusInSpringTestCase;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.List;
44 * DefaultCrossRepositorySearchTest
48 public class DefaultCrossRepositorySearchTest
49 extends PlexusInSpringTestCase
51 private static final String TEST_DEFAULT_REPOSITORY_NAME = "Test Default Repository";
53 private static final String TEST_DEFAULT_REPO_ID = "testDefaultRepo";
56 protected void setUp()
61 RepositoryContentIndexFactory indexFactory =
62 (RepositoryContentIndexFactory) lookup( RepositoryContentIndexFactory.class
63 .getName(), "lucene" );
65 File repoDir = new File( getBasedir(), "src/test/managed-repository" );
67 assertTrue( "Default Test Repository should exist.", repoDir.exists() && repoDir.isDirectory() );
69 ManagedRepositoryConfiguration repository = createRepository( TEST_DEFAULT_REPO_ID, TEST_DEFAULT_REPOSITORY_NAME, repoDir );
71 File indexLocation = new File( "target/index-crossrepo-" + getName() + "/" );
73 MockConfiguration config = (MockConfiguration) lookup( ArchivaConfiguration.class.getName(), "mock" );
75 ManagedRepositoryConfiguration repoConfig = new ManagedRepositoryConfiguration();
76 repoConfig.setId( TEST_DEFAULT_REPO_ID );
77 repoConfig.setName( TEST_DEFAULT_REPOSITORY_NAME );
78 repoConfig.setLocation( repoDir.getAbsolutePath() );
79 repoConfig.setIndexDir( indexLocation.getAbsolutePath() );
80 repoConfig.setScanned( true );
82 if ( indexLocation.exists() )
84 FileUtils.deleteDirectory( indexLocation );
87 config.getConfiguration().addManagedRepository( repoConfig );
89 // Create the (empty) indexes.
90 RepositoryContentIndex indexHashcode = indexFactory.createHashcodeIndex( repository );
91 RepositoryContentIndex indexBytecode = indexFactory.createBytecodeIndex( repository );
92 RepositoryContentIndex indexContents = indexFactory.createFileContentIndex( repository );
95 Map<String, HashcodesRecord> hashcodesMap = new HashcodesIndexPopulator().populate( new File( getBasedir() ) );
96 indexHashcode.indexRecords( hashcodesMap.values() );
97 assertEquals( "Hashcode Key Count", hashcodesMap.size(), indexHashcode.getAllRecordKeys().size() );
98 assertRecordCount( indexHashcode, hashcodesMap.size() );
100 Map<String, BytecodeRecord> bytecodeMap = new BytecodeIndexPopulator().populate( new File( getBasedir() ) );
101 indexBytecode.indexRecords( bytecodeMap.values() );
102 assertEquals( "Bytecode Key Count", bytecodeMap.size(), indexBytecode.getAllRecordKeys().size() );
103 assertRecordCount( indexBytecode, bytecodeMap.size() );
105 Map<String, FileContentRecord> contentMap = new FileContentIndexPopulator().populate( new File( getBasedir() ) );
106 indexContents.indexRecords( contentMap.values() );
107 assertEquals( "File Content Key Count", contentMap.size(), indexContents.getAllRecordKeys().size() );
108 assertRecordCount( indexContents, contentMap.size() );
111 private void assertRecordCount( RepositoryContentIndex index, int expectedCount )
114 Query query = new MatchAllDocsQuery();
115 Searcher searcher = (Searcher) index.getSearchable();
116 Hits hits = searcher.search( query );
117 assertEquals( "Expected Record Count for " + index.getId(), expectedCount, hits.length() );
120 private CrossRepositorySearch lookupCrossRepositorySearch()
123 CrossRepositorySearch search =
124 (CrossRepositorySearch) lookup( CrossRepositorySearch.class.getName(), "default" );
125 assertNotNull( "CrossRepositorySearch:default should not be null.", search );
129 public void testSearchTerm_Org()
132 CrossRepositorySearch search = lookupCrossRepositorySearch();
134 SearchResults results = search.searchForTerm( "guest", Arrays.asList(TEST_DEFAULT_REPO_ID), "org", new SearchResultLimits(1) );
136 assertNotNull(results);
137 assertEquals(7, results.getHits().size());
140 public void testSearchArtifactIdHasMoreWieghtThanGroupId() throws Exception
142 CrossRepositorySearch search = lookupCrossRepositorySearch();
144 String expectedRepos[] = new String[] {
148 List<SearchResultHit> expectedHits = new ArrayList<SearchResultHit>();
149 SearchResultHit hit = new SearchResultHit();
150 hit.setGroupId("ant");
151 hit.setArtifactId("ant");
152 hit.setVersion("1.5.1");
153 expectedHits.add(hit);
155 hit = new SearchResultHit();
156 hit.setGroupId("ant");
157 hit.setArtifactId("ant");
158 hit.setVersion("1.5");
159 expectedHits.add(hit);
161 hit = new SearchResultHit();
162 hit.setGroupId("ant");
163 hit.setArtifactId("ant-optional");
164 hit.setVersion("1.5.1");
165 expectedHits.add(hit);
167 hit = new SearchResultHit();
168 hit.setGroupId("ant");
169 hit.setArtifactId("ant-junit");
170 hit.setVersion("1.6.5");
171 expectedHits.add(hit);
173 assertSearchResults( expectedRepos, expectedHits, search, "ant", null, false );
176 public void testSearchInvalidTerm()
179 CrossRepositorySearch search = lookupCrossRepositorySearch();
181 String expectedRepos[] = new String[] {
185 assertSearchResults( expectedRepos, new ArrayList<SearchResultHit>(), search, "monosodium", null, false );
188 public void testSearchForClassesAndPackages()
191 CrossRepositorySearch search = lookupCrossRepositorySearch();
193 String expectedRepos[] = new String[] {
197 // String expectedResults[] = new String[] {
198 // "archiva-common-1.0.jar"
201 ArrayList<SearchResultHit> expectedHits = new ArrayList<SearchResultHit>();
203 // class with packagename search
204 assertSearchResults( expectedRepos, expectedHits, search,
205 "org.apache.maven.archiva.common.utils.BaseFile", null, true );
207 assertSearchResults( expectedRepos, expectedHits, search,
208 "BaseFile", null, true );
210 // String expectedMethodSearchResults[] = new String[] {
211 // "continuum-webapp-1.0.3-SNAPSHOT.war"
214 ArrayList<SearchResultHit> expectedMethodSearchResults = new ArrayList<SearchResultHit>();
217 assertSearchResults( expectedRepos, expectedMethodSearchResults, search,
218 "org.apache.maven.continuum.web.action.BuildDefinitionAction.isBuildFresh", null, true );
221 public void testExecuteFilteredSearch()
224 CrossRepositorySearch search = lookupCrossRepositorySearch();
226 String expectedRepos[] = new String[] { TEST_DEFAULT_REPO_ID };
228 String expectedResults[] = new String[] { "org1", "org2", "org3", "org4", "org5", "org6", "org7", "org8" };
230 String secondExpectedResults[] = new String[] { "continuum-webapp" };
232 String thirdExpectedResults[] = new String[] { "archiva-common" };
234 // search for groupId
235 assertFilteredSearchResults( expectedRepos, expectedResults, search, "org", null, null, null, 30 );
237 // search for groupId and artifactId
238 assertFilteredSearchResults( expectedRepos, secondExpectedResults, search, "org.apache.maven",
239 "continuum-webapp", null, null, 30 );
241 // search for groupId , artifactId and version
242 assertFilteredSearchResults( expectedRepos, thirdExpectedResults, search, "org.apache.maven.archiva",
243 "archiva-common", "1.0", null, 30 );
246 // MRM-981 - artifactIds with numeric characters aren't found in advanced search
247 public void testFilteredSearchArtifactIdHasNumericChar()
250 CrossRepositorySearch search = lookupCrossRepositorySearch();
252 String expectedRepos[] = new String[] { TEST_DEFAULT_REPO_ID };
254 String expectedResults[] = new String[] { "a-common5" };
256 assertFilteredSearchResults( expectedRepos, expectedResults, search, null, "a-common5", null, null, 30 );
258 assertFilteredSearchResults( expectedRepos, expectedResults, search, "a", "a-common5", null, null, 30 );
260 assertFilteredSearchResults( expectedRepos, expectedResults, search, "a", "a-common5", "1.0", null, 30 );
262 assertFilteredSearchResults( expectedRepos, expectedResults, search, "a", "a-common5", "1.0", "ACommonTestFile", 30 );
264 assertFilteredSearchResults( expectedRepos, expectedResults, search, "a", "a-common5", "1.0", "a.common5.package.", 30 );
266 String noHitsExpectedResults[] = new String[] {};
268 assertFilteredSearchResults( expectedRepos, noHitsExpectedResults, search, "org.apache.maven.archiva",
269 "a-common5", null, null, 30 );
272 private void assertFilteredSearchResults ( String expectedRepos[], String expectedResults[], CrossRepositorySearch search,
273 String groupId, String artifactId, String version, String className , int rowCount )
275 SearchResultLimits limits = new SearchResultLimits( 0 );
276 limits.setPageSize( rowCount );
278 List<String> selectedRepos = new ArrayList<String>();
279 selectedRepos.addAll( Arrays.asList( expectedRepos ) );
281 SearchResults results = null;
283 results = search.executeFilteredSearch( "guest" , selectedRepos, groupId, artifactId, version, className, limits );
285 assertNotNull( "Search Results should not be null.", results );
286 assertEquals( "Repository Hits", expectedRepos.length, results.getRepositories().size() );
287 assertEquals( expectedRepos.length, 1);
288 assertEquals( TEST_DEFAULT_REPO_ID , selectedRepos.get( 0 ) );
289 assertEquals( "Search Result Hits", expectedResults.length, results.getHits().size() );
292 private void assertSearchResults( String expectedRepos[], List<SearchResultHit> expectedResults, CrossRepositorySearch search,
293 String term, List<String> previousSearchTerms, boolean bytecode )
296 SearchResultLimits limits = new SearchResultLimits( 0 );
297 limits.setPageSize( 20 );
299 List<String> selectedRepos = new ArrayList<String>();
300 selectedRepos.addAll( Arrays.asList( expectedRepos ) );
302 SearchResults results = null;
304 if( previousSearchTerms == null )
308 results = search.searchForBytecode( "guest", selectedRepos, term, limits );
312 results = search.searchForTerm( "guest", selectedRepos, term, limits );
317 results = search.searchForTerm( "guest", selectedRepos, term, limits, previousSearchTerms );
321 assertNotNull( "Search Results should not be null.", results );
322 assertEquals( "Repository Hits", expectedRepos.length, results.getRepositories().size() );
324 // TODO: test the repository ids returned.
326 assertEquals( "Search Result Hits", expectedResults.size(), results.getHits().size() );
328 for (int i = 0; i < expectedResults.size(); i++)
330 final SearchResultHit expectedResult = expectedResults.get(i);
331 final SearchResultHit hit = results.getHits().get(i);
332 assertEquals("artifactid", expectedResult.getArtifactId(), hit.getArtifactId());
333 assertEquals("groupid", expectedResult.getGroupId(), hit.getGroupId());
334 assertEquals("version", expectedResult.getVersion(), hit.getVersion());
338 protected ManagedRepositoryConfiguration createRepository( String id, String name, File location )
340 ManagedRepositoryConfiguration repo = new ManagedRepositoryConfiguration();
342 repo.setName( name );
343 repo.setLocation( location.getAbsolutePath() );