| package org.apache.maven.index.updater; |
| |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| |
| import org.apache.lucene.index.Term; |
| import org.apache.lucene.search.TermQuery; |
| import org.apache.maven.index.ArtifactInfo; |
| import org.apache.maven.index.FlatSearchRequest; |
| import org.apache.maven.index.FlatSearchResponse; |
| import org.apache.maven.index.context.IndexingContext; |
| import org.apache.maven.index.context.UnsupportedExistingLuceneIndexException; |
| import org.apache.maven.index.fs.Locker; |
| import org.codehaus.plexus.util.FileUtils; |
| import org.codehaus.plexus.util.IOUtil; |
| |
| public class LocalIndexCacheTest |
| extends AbstractIndexUpdaterTest |
| { |
| private File remoteRepo; |
| |
| private File localCacheDir; |
| |
| private File indexDir; |
| |
| private IndexingContext tempContext; |
| |
| @Override |
| protected void setUp() |
| throws Exception |
| { |
| super.setUp(); |
| |
| remoteRepo = new File( "target/localcache/remoterepo" ).getCanonicalFile(); |
| FileUtils.deleteDirectory( remoteRepo ); |
| remoteRepo.mkdirs(); |
| |
| localCacheDir = new File( "target/localcache/cache" ).getCanonicalFile(); |
| FileUtils.deleteDirectory( localCacheDir ); |
| localCacheDir.mkdirs(); |
| |
| indexDir = new File( "target/localcache/index" ).getCanonicalFile(); |
| FileUtils.deleteDirectory( indexDir ); |
| indexDir.mkdirs(); |
| } |
| |
| @Override |
| protected void tearDown() |
| throws Exception |
| { |
| removeTempContext(); |
| |
| super.tearDown(); |
| } |
| |
| private IndexingContext getNewTempContext() |
| throws IOException, UnsupportedExistingLuceneIndexException |
| { |
| removeTempContext(); |
| |
| tempContext = |
| indexer.addIndexingContext( repositoryId + "temp", repositoryId, repoDir, indexDir, repositoryUrl, null, |
| MIN_CREATORS ); |
| |
| return tempContext; |
| } |
| |
| private void removeTempContext() |
| throws IOException |
| { |
| if ( tempContext != null ) |
| { |
| indexer.removeIndexingContext( tempContext, true ); |
| tempContext = null; |
| FileUtils.cleanDirectory( indexDir ); |
| } |
| } |
| |
| public void testBasic() |
| throws Exception |
| { |
| // create initial remote repo index |
| indexer.addArtifactToIndex( createArtifactContext( repositoryId, "commons-lang", "commons-lang", "2.2", null ), |
| context ); |
| packIndex( remoteRepo, context ); |
| |
| // |
| TrackingFetcher fetcher; |
| IndexUpdateRequest updateRequest; |
| IndexingContext testContext; |
| |
| // initial index download (expected: full index download) |
| testContext = getNewTempContext(); |
| fetcher = new TrackingFetcher( remoteRepo ); |
| updateRequest = new IndexUpdateRequest( testContext, fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| assertEquals( 2, fetcher.getRetrievedResources().size() ); |
| assertTrue( new File( localCacheDir, "nexus-maven-repository-index.gz" ).exists() ); |
| assertTrue( new File( localCacheDir, "nexus-maven-repository-index.properties" ).exists() ); |
| assertGroupCount( 1, "commons-lang", testContext ); |
| |
| // update the same index (expected: no index download) |
| fetcher = new TrackingFetcher( remoteRepo ); |
| updateRequest = new IndexUpdateRequest( testContext, fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| assertEquals( 1, fetcher.getRetrievedResources().size() ); |
| assertEquals( "nexus-maven-repository-index.properties", fetcher.getRetrievedResources().get( 0 ) ); |
| assertGroupCount( 1, "commons-lang", testContext ); |
| |
| // nuke index but keep the cache (expected: no index download) |
| testContext = getNewTempContext(); |
| fetcher = new TrackingFetcher( remoteRepo ); |
| updateRequest = new IndexUpdateRequest( testContext, fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| assertEquals( 1, fetcher.getRetrievedResources().size() ); |
| assertEquals( "nexus-maven-repository-index.properties", fetcher.getRetrievedResources().get( 0 ) ); |
| assertGroupCount( 1, "commons-lang", testContext ); |
| |
| // incremental remote update |
| indexer.addArtifactToIndex( createArtifactContext( repositoryId, "commons-lang", "commons-lang", "2.3", null ), |
| context ); |
| packIndex( remoteRepo, context ); |
| |
| // update via cache (expected: incremental chunk download) |
| fetcher = new TrackingFetcher( remoteRepo ); |
| updateRequest = new IndexUpdateRequest( testContext, fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| assertEquals( 2, fetcher.getRetrievedResources().size() ); |
| assertEquals( "nexus-maven-repository-index.properties", fetcher.getRetrievedResources().get( 0 ) ); |
| assertEquals( "nexus-maven-repository-index.1.gz", fetcher.getRetrievedResources().get( 1 ) ); |
| assertGroupCount( 2, "commons-lang", testContext ); |
| |
| // nuke index but keep the cache (expected: no index download, index contains both initial and delta chunks) |
| testContext = getNewTempContext(); |
| fetcher = new TrackingFetcher( remoteRepo ); |
| updateRequest = new IndexUpdateRequest( testContext, fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| assertEquals( 1, fetcher.getRetrievedResources().size() ); |
| assertEquals( "nexus-maven-repository-index.properties", fetcher.getRetrievedResources().get( 0 ) ); |
| assertGroupCount( 2, "commons-lang", testContext ); |
| |
| // kill the cache, but keep the index (expected: full index download) |
| // TODO how to assert if merge==false internally? |
| FileUtils.deleteDirectory( localCacheDir ); |
| fetcher = new TrackingFetcher( remoteRepo ); |
| updateRequest = new IndexUpdateRequest( testContext, fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| assertEquals( 2, fetcher.getRetrievedResources().size() ); |
| assertTrue( new File( localCacheDir, "nexus-maven-repository-index.gz" ).exists() ); |
| assertTrue( new File( localCacheDir, "nexus-maven-repository-index.properties" ).exists() ); |
| assertGroupCount( 2, "commons-lang", testContext ); |
| } |
| |
| private void assertGroupCount( int expectedCount, String groupId, IndexingContext context ) |
| throws IOException |
| { |
| TermQuery query = new TermQuery( new Term( ArtifactInfo.GROUP_ID, groupId ) ); |
| FlatSearchResponse response = indexer.searchFlat( new FlatSearchRequest( query, context ) ); |
| assertEquals( expectedCount, response.getTotalHits() ); |
| } |
| |
| public void testForceIndexDownload() |
| throws Exception |
| { |
| indexer.addArtifactToIndex( createArtifactContext( repositoryId, "commons-lang", "commons-lang", "2.2", null ), |
| context ); |
| packIndex( remoteRepo, context ); |
| |
| // |
| TrackingFetcher fetcher; |
| IndexUpdateRequest updateRequest; |
| |
| // initial index download (expected: no index download) |
| fetcher = new TrackingFetcher( remoteRepo ); |
| updateRequest = new IndexUpdateRequest( getNewTempContext(), fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| |
| // corrupt local cache |
| IOUtil.copy( "corrupted", new FileOutputStream( new File( localCacheDir, "nexus-maven-repository-index.gz" ) ) ); |
| |
| // try download again (it would have failed if force did not update local cache) |
| removeTempContext(); |
| fetcher = new TrackingFetcher( remoteRepo ); |
| updateRequest = new IndexUpdateRequest( getNewTempContext(), fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updateRequest.setForceFullUpdate( true ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| } |
| |
| public void testInitialForcedFullDownload() |
| throws Exception |
| { |
| indexer.addArtifactToIndex( createArtifactContext( repositoryId, "commons-lang", "commons-lang", "2.2", null ), |
| context ); |
| packIndex( remoteRepo, context ); |
| |
| // |
| TrackingFetcher fetcher; |
| IndexUpdateRequest updateRequest; |
| |
| // initial forced full index download (expected: successfull download) |
| fetcher = new TrackingFetcher( remoteRepo ); |
| updateRequest = new IndexUpdateRequest( getNewTempContext(), fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updateRequest.setForceFullUpdate( true ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| assertTrue( new File( localCacheDir, "nexus-maven-repository-index.gz" ).exists() ); |
| assertTrue( new File( localCacheDir, "nexus-maven-repository-index.properties" ).exists() ); |
| } |
| |
| public void testFailedIndexDownload() |
| throws Exception |
| { |
| indexer.addArtifactToIndex( createArtifactContext( repositoryId, "commons-lang", "commons-lang", "2.2", null ), |
| context ); |
| packIndex( remoteRepo, context ); |
| |
| // |
| TrackingFetcher fetcher; |
| IndexUpdateRequest updateRequest; |
| |
| // failed download |
| fetcher = new TrackingFetcher( remoteRepo ) |
| { |
| public InputStream retrieve( String name ) |
| throws IOException, java.io.FileNotFoundException |
| { |
| if ( name.equals( IndexingContext.INDEX_FILE_PREFIX + ".gz" ) |
| || name.equals( IndexingContext.INDEX_FILE_PREFIX + ".zip" ) ) |
| { |
| throw new IOException(); |
| } |
| return super.retrieve( name ); |
| }; |
| }; |
| updateRequest = new IndexUpdateRequest( getNewTempContext(), fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| try |
| { |
| updater.fetchAndUpdateIndex( updateRequest ); |
| fail(); |
| } |
| catch ( IOException e ) |
| { |
| // expected |
| } |
| |
| // try successful download |
| fetcher = new TrackingFetcher( remoteRepo ); |
| updateRequest = new IndexUpdateRequest( getNewTempContext(), fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| assertTrue( new File( localCacheDir, "nexus-maven-repository-index.gz" ).exists() ); |
| assertTrue( new File( localCacheDir, "nexus-maven-repository-index.properties" ).exists() ); |
| } |
| |
| public void testCleanCacheDirectory() |
| throws Exception |
| { |
| indexer.addArtifactToIndex( createArtifactContext( repositoryId, "commons-lang", "commons-lang", "2.2", null ), |
| context ); |
| packIndex( remoteRepo, context ); |
| |
| // |
| TrackingFetcher fetcher; |
| IndexUpdateRequest updateRequest; |
| |
| // initial index download (expected: successfull download) |
| fetcher = new TrackingFetcher( remoteRepo ); |
| updateRequest = new IndexUpdateRequest( getNewTempContext(), fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| |
| // new remote index delta |
| indexer.addArtifactToIndex( createArtifactContext( repositoryId, "commons-lang", "commons-lang", "2.3", null ), |
| context ); |
| packIndex( remoteRepo, context ); |
| |
| // delta index download (expected: successfull download) |
| fetcher = new TrackingFetcher( remoteRepo ); |
| updateRequest = new IndexUpdateRequest( getNewTempContext(), fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| |
| // sanity check |
| assertTrue( new File( localCacheDir, "nexus-maven-repository-index.1.gz" ).canRead() ); |
| |
| // .lock files are expected to be preserved |
| File lockFile = new File( localCacheDir, Locker.LOCK_FILE ); |
| IOUtil.copy( "", new FileOutputStream( lockFile ) ); |
| assertTrue( lockFile.canRead() ); |
| |
| // all unknown files and directories are expected to be removed |
| File unknownFile = new File( localCacheDir, "unknownFile" ); |
| IOUtil.copy( "", new FileOutputStream( unknownFile ) ); |
| File unknownDirectory = new File( localCacheDir, "unknownDirectory" ); |
| unknownDirectory.mkdirs(); |
| assertTrue( unknownFile.canRead() ); |
| assertTrue( unknownDirectory.isDirectory() ); |
| |
| // forced full update |
| fetcher = new TrackingFetcher( remoteRepo ); |
| updateRequest = new IndexUpdateRequest( getNewTempContext(), fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updateRequest.setForceFullUpdate( true ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| |
| assertTrue( lockFile.canRead() ); |
| assertFalse( new File( localCacheDir, "nexus-maven-repository-index.1.gz" ).canRead() ); |
| assertFalse( unknownFile.canRead() ); |
| assertFalse( unknownDirectory.isDirectory() ); |
| } |
| |
| public void testOffline() |
| throws Exception |
| { |
| indexer.addArtifactToIndex( createArtifactContext( repositoryId, "commons-lang", "commons-lang", "2.2", null ), |
| context ); |
| packIndex( remoteRepo, context ); |
| |
| // |
| TrackingFetcher fetcher; |
| IndexUpdateRequest updateRequest; |
| |
| // initial index download (expected: successfull download) |
| fetcher = new TrackingFetcher( remoteRepo ); |
| IndexingContext testContext = getNewTempContext(); |
| updateRequest = new IndexUpdateRequest( testContext, fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| |
| // recreate local index from the cache without remote access (and NULL fetcher) |
| // fetcher is null, so we no way to assert that |
| updateRequest = new IndexUpdateRequest( testContext, fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updateRequest.setOffline( true ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| assertGroupCount( 1, "commons-lang", testContext ); |
| |
| // recreate local index from the cache without remote access (and NOT NULL fetcher) |
| fetcher = new TrackingFetcher( remoteRepo ); |
| updateRequest = new IndexUpdateRequest( testContext, fetcher ); |
| updateRequest.setLocalIndexCacheDir( localCacheDir ); |
| updateRequest.setOffline( true ); |
| updater.fetchAndUpdateIndex( updateRequest ); |
| assertEquals( 0, fetcher.getRetrievedResources().size() ); |
| assertGroupCount( 1, "commons-lang", testContext ); |
| } |
| |
| } |