001package org.apache.maven.artifact.resolver;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.util.ArrayList;
023import java.util.Collections;
024import java.util.HashSet;
025import java.util.Iterator;
026import java.util.LinkedHashSet;
027import java.util.List;
028import java.util.Set;
029
030import org.apache.maven.artifact.AbstractArtifactComponentTestCase;
031import org.apache.maven.artifact.Artifact;
032import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
033import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
034import org.apache.maven.artifact.metadata.ResolutionGroup;
035import org.apache.maven.artifact.repository.ArtifactRepository;
036import org.apache.maven.artifact.versioning.ArtifactVersion;
037import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest;
038import org.codehaus.plexus.component.repository.ComponentDescriptor;
039
040// It would be cool if there was a hook that i could use to setup a test environment.
041// I want to setup a local/remote repositories for testing but i don't want to have
042// to change them when i change the layout of the repositories. So i want to generate
043// the structure i want to test by using the artifact handler manager which dictates
044// the layout used for a particular artifact type.
045
046/**
047 * @author Jason van Zyl
048 */
049public class ArtifactResolverTest
050    extends AbstractArtifactComponentTestCase
051{
052    private DefaultArtifactResolver artifactResolver;
053
054    private Artifact projectArtifact;
055
056    @Override
057    protected void setUp()
058        throws Exception
059    {
060        super.setUp();
061
062        artifactResolver = (DefaultArtifactResolver) lookup( ArtifactResolver.class );
063
064        projectArtifact = createLocalArtifact( "project", "3.0" );
065    }
066    
067    @Override
068    protected void tearDown()
069        throws Exception
070    {
071        artifactFactory = null;
072        projectArtifact = null;
073        super.tearDown();
074    }
075
076    @Override
077    protected String component()
078    {
079        return "resolver";
080    }
081
082    public void testResolutionOfASingleArtifactWhereTheArtifactIsPresentInTheLocalRepository()
083        throws Exception
084    {
085        Artifact a = createLocalArtifact( "a", "1.0" );
086
087        artifactResolver.resolve( a, remoteRepositories(), localRepository() );
088
089        assertLocalArtifactPresent( a );
090    }
091
092    public void testResolutionOfASingleArtifactWhereTheArtifactIsNotPresentLocallyAndMustBeRetrievedFromTheRemoteRepository()
093        throws Exception
094    {
095        Artifact b = createRemoteArtifact( "b", "1.0-SNAPSHOT" );
096        deleteLocalArtifact( b );
097        artifactResolver.resolve( b, remoteRepositories(), localRepository() );
098        assertLocalArtifactPresent( b );
099    }
100
101    @Override
102    protected Artifact createArtifact( String groupId, String artifactId, String version, String type )
103        throws Exception
104    {
105        // for the anonymous classes
106        return super.createArtifact( groupId, artifactId, version, type );
107    }
108
109    public void testTransitiveResolutionWhereAllArtifactsArePresentInTheLocalRepository()
110        throws Exception
111    {
112        Artifact g = createLocalArtifact( "g", "1.0" );
113
114        Artifact h = createLocalArtifact( "h", "1.0" );
115
116        ArtifactResolutionResult result = artifactResolver.resolveTransitively( Collections.singleton( g ), projectArtifact, remoteRepositories(), localRepository(), null );
117
118        printErrors( result );
119
120        assertEquals( 2, result.getArtifacts().size() );
121
122        assertTrue( result.getArtifacts().contains( g ) );
123
124        assertTrue( result.getArtifacts().contains( h ) );
125
126        assertLocalArtifactPresent( g );
127
128        assertLocalArtifactPresent( h );
129    }
130
131    public void testTransitiveResolutionWhereAllArtifactsAreNotPresentInTheLocalRepositoryAndMustBeRetrievedFromTheRemoteRepository()
132        throws Exception
133    {
134        Artifact i = createRemoteArtifact( "i", "1.0-SNAPSHOT" );
135        deleteLocalArtifact( i );
136
137        Artifact j = createRemoteArtifact( "j", "1.0-SNAPSHOT" );
138        deleteLocalArtifact( j );
139
140        ArtifactResolutionResult result = artifactResolver.resolveTransitively( Collections.singleton( i ), projectArtifact, remoteRepositories(), localRepository(), null );
141
142        printErrors( result );
143
144        assertEquals( 2, result.getArtifacts().size() );
145
146        assertTrue( result.getArtifacts().contains( i ) );
147
148        assertTrue( result.getArtifacts().contains( j ) );
149
150        assertLocalArtifactPresent( i );
151
152        assertLocalArtifactPresent( j );
153    }
154
155    public void testResolutionFailureWhenArtifactNotPresentInRemoteRepository()
156        throws Exception
157    {
158        Artifact k = createArtifact( "k", "1.0" );
159
160        try
161        {
162            artifactResolver.resolve( k, remoteRepositories(), localRepository() );
163            fail( "Resolution succeeded when it should have failed" );
164        }
165        catch ( ArtifactNotFoundException expected )
166        {
167            assertTrue( true );
168        }
169    }
170
171    public void testResolutionOfAnArtifactWhereOneRemoteRepositoryIsBadButOneIsGood()
172        throws Exception
173    {
174        Artifact l = createRemoteArtifact( "l", "1.0-SNAPSHOT" );
175        deleteLocalArtifact( l );
176
177        List<ArtifactRepository> repositories = new ArrayList<ArtifactRepository>();
178        repositories.add( remoteRepository() );
179        repositories.add( badRemoteRepository() );
180
181        artifactResolver.resolve( l, repositories, localRepository() );
182
183        assertLocalArtifactPresent( l );
184    }
185
186    public void testTransitiveResolutionOrder()
187        throws Exception
188    {
189        Artifact m = createLocalArtifact( "m", "1.0" );
190
191        Artifact n = createLocalArtifact( "n", "1.0" );
192
193        ArtifactMetadataSource mds = new ArtifactMetadataSource()
194        {
195            public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository,
196                                             List<ArtifactRepository> remoteRepositories )
197                throws ArtifactMetadataRetrievalException
198            {
199                Set dependencies = new HashSet();
200
201                return new ResolutionGroup( artifact, dependencies, remoteRepositories );
202            }
203
204            public List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact,
205                                                                    ArtifactRepository localRepository,
206                                                                    List<ArtifactRepository> remoteRepositories )
207                throws ArtifactMetadataRetrievalException
208            {
209                throw new UnsupportedOperationException( "Cannot get available versions in this test case" );
210            }
211
212            public List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository(
213                                                                                            Artifact artifact,
214                                                                                            ArtifactRepository localRepository,
215                                                                                            ArtifactRepository remoteRepository )
216                throws ArtifactMetadataRetrievalException
217            {
218                throw new UnsupportedOperationException( "Cannot get available versions in this test case" );
219            }
220
221            public ResolutionGroup retrieve( MetadataResolutionRequest request )
222                throws ArtifactMetadataRetrievalException
223            {
224                return retrieve( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() );
225            }
226
227            public List<ArtifactVersion> retrieveAvailableVersions( MetadataResolutionRequest request )
228                throws ArtifactMetadataRetrievalException
229            {
230                return retrieveAvailableVersions( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() );
231            }
232        };
233
234        ArtifactResolutionResult result = null;
235
236        Set set = new LinkedHashSet();
237        set.add( n );
238        set.add( m );
239
240        result =
241            artifactResolver.resolveTransitively( set, projectArtifact, remoteRepositories(), localRepository(), mds );
242
243        printErrors( result );
244
245        Iterator i = result.getArtifacts().iterator();
246        assertEquals( "n should be first", n, i.next() );
247        assertEquals( "m should be second", m, i.next() );
248
249        // inverse order
250        set = new LinkedHashSet();
251        set.add( m );
252        set.add( n );
253
254        result =
255            artifactResolver.resolveTransitively( set, projectArtifact, remoteRepositories(), localRepository(), mds );
256
257        printErrors( result );
258
259        i = result.getArtifacts().iterator();
260        assertEquals( "m should be first", m, i.next() );
261        assertEquals( "n should be second", n, i.next() );
262    }
263
264    private void printErrors( ArtifactResolutionResult result )
265    {
266        if ( result.hasMissingArtifacts() )
267        {
268            for ( Artifact artifact : result.getMissingArtifacts() )
269            {
270                System.err.println( "Missing: " + artifact );
271            }
272        }
273
274        if ( result.hasExceptions() )
275        {
276            for ( Exception e : result.getExceptions() )
277            {
278                e.printStackTrace();
279            }
280        }
281    }
282
283}