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;
038
039// It would be cool if there was a hook that i could use to setup a test environment.
040// I want to setup a local/remote repositories for testing but i don't want to have
041// to change them when i change the layout of the repositories. So i want to generate
042// the structure i want to test by using the artifact handler manager which dictates
043// the layout used for a particular artifact type.
044
045/**
046 * @author Jason van Zyl
047 */
048public class ArtifactResolverTest
049    extends AbstractArtifactComponentTestCase
050{
051    private DefaultArtifactResolver artifactResolver;
052
053    private Artifact projectArtifact;
054
055    @Override
056    protected void setUp()
057        throws Exception
058    {
059        super.setUp();
060
061        artifactResolver = (DefaultArtifactResolver) lookup( ArtifactResolver.class );
062
063        projectArtifact = createLocalArtifact( "project", "3.0" );
064    }
065
066    @Override
067    protected void tearDown()
068        throws Exception
069    {
070        artifactFactory = null;
071        projectArtifact = null;
072        super.tearDown();
073    }
074
075    @Override
076    protected String component()
077    {
078        return "resolver";
079    }
080
081    public void testResolutionOfASingleArtifactWhereTheArtifactIsPresentInTheLocalRepository()
082        throws Exception
083    {
084        Artifact a = createLocalArtifact( "a", "1.0" );
085
086        artifactResolver.resolve( a, remoteRepositories(), localRepository() );
087
088        assertLocalArtifactPresent( a );
089    }
090
091    public void testResolutionOfASingleArtifactWhereTheArtifactIsNotPresentLocallyAndMustBeRetrievedFromTheRemoteRepository()
092        throws Exception
093    {
094        Artifact b = createRemoteArtifact( "b", "1.0-SNAPSHOT" );
095        deleteLocalArtifact( b );
096        artifactResolver.resolve( b, remoteRepositories(), localRepository() );
097        assertLocalArtifactPresent( b );
098    }
099
100    @Override
101    protected Artifact createArtifact( String groupId, String artifactId, String version, String type )
102        throws Exception
103    {
104        // for the anonymous classes
105        return super.createArtifact( groupId, artifactId, version, type );
106    }
107
108    public void testTransitiveResolutionWhereAllArtifactsArePresentInTheLocalRepository()
109        throws Exception
110    {
111        Artifact g = createLocalArtifact( "g", "1.0" );
112
113        Artifact h = createLocalArtifact( "h", "1.0" );
114
115        ArtifactResolutionResult result = artifactResolver.resolveTransitively( Collections.singleton( g ), projectArtifact, remoteRepositories(), localRepository(), null );
116
117        printErrors( result );
118
119        assertEquals( 2, result.getArtifacts().size() );
120
121        assertTrue( result.getArtifacts().contains( g ) );
122
123        assertTrue( result.getArtifacts().contains( h ) );
124
125        assertLocalArtifactPresent( g );
126
127        assertLocalArtifactPresent( h );
128    }
129
130    public void testTransitiveResolutionWhereAllArtifactsAreNotPresentInTheLocalRepositoryAndMustBeRetrievedFromTheRemoteRepository()
131        throws Exception
132    {
133        Artifact i = createRemoteArtifact( "i", "1.0-SNAPSHOT" );
134        deleteLocalArtifact( i );
135
136        Artifact j = createRemoteArtifact( "j", "1.0-SNAPSHOT" );
137        deleteLocalArtifact( j );
138
139        ArtifactResolutionResult result = artifactResolver.resolveTransitively( Collections.singleton( i ), projectArtifact, remoteRepositories(), localRepository(), null );
140
141        printErrors( result );
142
143        assertEquals( 2, result.getArtifacts().size() );
144
145        assertTrue( result.getArtifacts().contains( i ) );
146
147        assertTrue( result.getArtifacts().contains( j ) );
148
149        assertLocalArtifactPresent( i );
150
151        assertLocalArtifactPresent( j );
152    }
153
154    public void testResolutionFailureWhenArtifactNotPresentInRemoteRepository()
155        throws Exception
156    {
157        Artifact k = createArtifact( "k", "1.0" );
158
159        try
160        {
161            artifactResolver.resolve( k, remoteRepositories(), localRepository() );
162            fail( "Resolution succeeded when it should have failed" );
163        }
164        catch ( ArtifactNotFoundException expected )
165        {
166            assertTrue( true );
167        }
168    }
169
170    public void testResolutionOfAnArtifactWhereOneRemoteRepositoryIsBadButOneIsGood()
171        throws Exception
172    {
173        Artifact l = createRemoteArtifact( "l", "1.0-SNAPSHOT" );
174        deleteLocalArtifact( l );
175
176        List<ArtifactRepository> repositories = new ArrayList<>();
177        repositories.add( remoteRepository() );
178        repositories.add( badRemoteRepository() );
179
180        artifactResolver.resolve( l, repositories, localRepository() );
181
182        assertLocalArtifactPresent( l );
183    }
184
185    public void testTransitiveResolutionOrder()
186        throws Exception
187    {
188        Artifact m = createLocalArtifact( "m", "1.0" );
189
190        Artifact n = createLocalArtifact( "n", "1.0" );
191
192        ArtifactMetadataSource mds = new ArtifactMetadataSource()
193        {
194            public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository,
195                                             List<ArtifactRepository> remoteRepositories )
196                throws ArtifactMetadataRetrievalException
197            {
198                Set<Artifact> dependencies = new HashSet<>();
199
200                return new ResolutionGroup( artifact, dependencies, remoteRepositories );
201            }
202
203            public List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact,
204                                                                    ArtifactRepository localRepository,
205                                                                    List<ArtifactRepository> remoteRepositories )
206                throws ArtifactMetadataRetrievalException
207            {
208                throw new UnsupportedOperationException( "Cannot get available versions in this test case" );
209            }
210
211            public List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository(
212                                                                                            Artifact artifact,
213                                                                                            ArtifactRepository localRepository,
214                                                                                            ArtifactRepository remoteRepository )
215                throws ArtifactMetadataRetrievalException
216            {
217                throw new UnsupportedOperationException( "Cannot get available versions in this test case" );
218            }
219
220            public ResolutionGroup retrieve( MetadataResolutionRequest request )
221                throws ArtifactMetadataRetrievalException
222            {
223                return retrieve( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() );
224            }
225
226            public List<ArtifactVersion> retrieveAvailableVersions( MetadataResolutionRequest request )
227                throws ArtifactMetadataRetrievalException
228            {
229                return retrieveAvailableVersions( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() );
230            }
231        };
232
233        ArtifactResolutionResult result = null;
234
235        Set<Artifact> set = new LinkedHashSet<>();
236        set.add( n );
237        set.add( m );
238
239        result =
240            artifactResolver.resolveTransitively( set, projectArtifact, remoteRepositories(), localRepository(), mds );
241
242        printErrors( result );
243
244        Iterator<Artifact> i = result.getArtifacts().iterator();
245        assertEquals( "n should be first", n, i.next() );
246        assertEquals( "m should be second", m, i.next() );
247
248        // inverse order
249        set = new LinkedHashSet<>();
250        set.add( m );
251        set.add( n );
252
253        result =
254            artifactResolver.resolveTransitively( set, projectArtifact, remoteRepositories(), localRepository(), mds );
255
256        printErrors( result );
257
258        i = result.getArtifacts().iterator();
259        assertEquals( "m should be first", m, i.next() );
260        assertEquals( "n should be second", n, i.next() );
261    }
262
263    private void printErrors( ArtifactResolutionResult result )
264    {
265        if ( result.hasMissingArtifacts() )
266        {
267            for ( Artifact artifact : result.getMissingArtifacts() )
268            {
269                System.err.println( "Missing: " + artifact );
270            }
271        }
272
273        if ( result.hasExceptions() )
274        {
275            for ( Exception e : result.getExceptions() )
276            {
277                e.printStackTrace();
278            }
279        }
280    }
281
282}