View Javadoc
1   package org.apache.maven.plugin.surefire;
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 org.apache.maven.artifact.Artifact;
23  import org.apache.maven.artifact.DefaultArtifact;
24  import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
25  import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
26  import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
27  import org.apache.maven.artifact.versioning.VersionRange;
28  import org.apache.maven.model.Dependency;
29  import org.apache.maven.model.Plugin;
30  import org.apache.maven.plugin.descriptor.PluginDescriptor;
31  import org.apache.maven.plugin.surefire.SurefireDependencyResolver.RuntimeArtifactFilter;
32  import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
33  import org.apache.maven.project.ProjectBuildingRequest;
34  import org.apache.maven.repository.RepositorySystem;
35  import org.apache.maven.shared.artifact.filter.resolve.ScopeFilter;
36  import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
37  import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;
38  import org.junit.Rule;
39  import org.junit.Test;
40  import org.junit.rules.ExpectedException;
41  import org.mockito.ArgumentCaptor;
42  import org.mockito.invocation.InvocationOnMock;
43  import org.mockito.stubbing.Answer;
44  import org.powermock.api.mockito.PowerMockito;
45  
46  import java.io.File;
47  import java.util.Collection;
48  import java.util.Iterator;
49  import java.util.LinkedHashSet;
50  import java.util.Map;
51  import java.util.Set;
52  
53  import static java.util.Collections.singleton;
54  import static java.util.Collections.singletonList;
55  import static java.util.Collections.singletonMap;
56  import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE;
57  import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE_PLUS_RUNTIME;
58  import static org.apache.maven.artifact.Artifact.SCOPE_RUNTIME;
59  import static org.apache.maven.artifact.versioning.VersionRange.createFromVersionSpec;
60  import static org.apache.maven.plugin.surefire.SurefireDependencyResolver.PROVIDER_GROUP_ID;
61  import static org.fest.assertions.Assertions.assertThat;
62  import static org.mockito.ArgumentMatchers.isNull;
63  import static org.mockito.ArgumentMatchers.same;
64  import static org.mockito.Mockito.any;
65  import static org.mockito.Mockito.mock;
66  import static org.mockito.Mockito.times;
67  import static org.mockito.Mockito.verify;
68  import static org.mockito.Mockito.when;
69  import static org.powermock.reflect.Whitebox.invokeMethod;
70  
71  /**
72   *
73   */
74  public class SurefireDependencyResolverTest
75  {
76      @Rule
77      public final ExpectedException expectedException = ExpectedException.none();
78  
79      @Test
80      public void shouldNotBeWithinRangeNullArtifact()
81      {
82          boolean result = SurefireDependencyResolver.isWithinVersionSpec( null, "[4.7,)" );
83          assertThat( result )
84                  .isFalse();
85      }
86  
87      @Test
88      public void shouldNotBeWithinRange() throws InvalidVersionSpecificationException
89      {
90          Artifact api = createArtifact( "junit", "junit", "4.6" );
91          boolean result = SurefireDependencyResolver.isWithinVersionSpec( api, "[4.7,)" );
92          assertThat( result )
93                  .isFalse();
94      }
95  
96      @Test
97      public void shouldBeWithinRange() throws InvalidVersionSpecificationException
98      {
99          Artifact api = createArtifact( "junit", "junit", "4.7" );
100         boolean result = SurefireDependencyResolver.isWithinVersionSpec( api, "[4.7,)" );
101         assertThat( result )
102                 .isTrue();
103     }
104 
105     @Test
106     public void shouldBeFarWithinRange() throws InvalidVersionSpecificationException
107     {
108         Artifact api = createArtifact( "junit", "junit", "4.13" );
109         boolean result = SurefireDependencyResolver.isWithinVersionSpec( api, "[4.7,)" );
110         assertThat( result )
111                 .isTrue();
112     }
113 
114     @Test
115     public void shouldBeFailWithinRange() throws InvalidVersionSpecificationException
116     {
117         Artifact api = createArtifact( "junit", "junit", "" );
118         expectedException.expect( RuntimeException.class );
119         expectedException.expectMessage( "Bug in plugin. Please report with stacktrace" );
120         SurefireDependencyResolver.isWithinVersionSpec( api, "[4.7,)" );
121     }
122 
123     @Test
124     public void testResolveArtifact() throws InvalidVersionSpecificationException
125     {
126         final Artifact provider = createArtifact( "surefire-junit-platform" );
127         RepositorySystem repositorySystem = mock( RepositorySystem.class );
128         final ArtifactResolutionResult expectedResult = mock( ArtifactResolutionResult.class );
129         when( repositorySystem.resolve( any( ArtifactResolutionRequest.class ) ) )
130                 .then( new Answer<ArtifactResolutionResult>()
131                 {
132                     @Override
133                     public ArtifactResolutionResult answer( InvocationOnMock invocation )
134                     {
135                         Object[] args = invocation.getArguments();
136                         assertThat( args )
137                                 .hasSize( 1 );
138                         ArtifactResolutionRequest request = (ArtifactResolutionRequest) args[0];
139                         assertThat( request.getArtifact() )
140                                 .isSameAs( provider );
141                         assertThat( request.isResolveTransitively() )
142                                 .isTrue();
143                         assertThat( request.getArtifactDependencies() )
144                                 .isNull();
145                         assertThat( request.getRemoteRepositories() )
146                                 .isNull();
147                         assertThat( request.getLocalRepository() )
148                                 .isNull();
149                         assertThat( request.getCache() )
150                                 .isNull();
151                         assertThat( request.getCollectionFilter() )
152                                 .isNotNull();
153                         assertThat( request.getCollectionFilter() )
154                                 .isInstanceOf( RuntimeArtifactFilter.class );
155                         assertThat( request.getManagedVersionMap() )
156                                 .isNull();
157                         assertThat( request.getMirrors() )
158                                 .isEmpty();
159                         assertThat( request.getProxies() )
160                                 .isEmpty();
161                         assertThat( request.getResolutionFilter() )
162                                 .isNull();
163                         assertThat( request.getServers() )
164                                 .isEmpty();
165                         return expectedResult;
166                     }
167                 } );
168 
169         SurefireDependencyResolver surefireDependencyResolver =
170                 new SurefireDependencyResolver( repositorySystem, null, null, null, null, null, null, false );
171 
172         ArtifactResolutionResult actualResult = surefireDependencyResolver.resolvePluginArtifact( provider );
173 
174         assertThat( actualResult )
175                 .isSameAs( expectedResult );
176     }
177 
178     @Test
179     public void testGetProviderClasspath() throws Exception
180     {
181         Artifact api = createArtifact( "surefire-api" );
182         api.setFile( new File( "" ) );
183 
184         final Artifact provider = createArtifact( "surefire-junit-platform" );
185         provider.setFile( new File( "" ) );
186 
187         Artifact ext = createArtifact( "org.apiguardian", "apiguardian-api" );
188         ext.setFile( new File( "" ) );
189 
190         Artifact logger = createArtifact( "surefire-logger-api" );
191         logger.setFile( new File( "" ) );
192 
193         Set<Artifact> providerArtifacts = new LinkedHashSet<>();
194         providerArtifacts.add( api );
195         providerArtifacts.add( provider );
196         providerArtifacts.add( ext );
197         providerArtifacts.add( logger );
198 
199         final ArtifactResolutionResult result = mock( ArtifactResolutionResult.class );
200         when( result.getArtifacts() )
201                 .thenReturn( providerArtifacts );
202 
203         RepositorySystem repositorySystem = mock( RepositorySystem.class );
204         when( repositorySystem.resolve( any( ArtifactResolutionRequest.class ) ) )
205                 .then( new Answer<ArtifactResolutionResult>()
206                 {
207                     @Override
208                     public ArtifactResolutionResult answer( InvocationOnMock invocation )
209                     {
210                         Object[] args = invocation.getArguments();
211                         assertThat( args )
212                                 .hasSize( 1 );
213                         ArtifactResolutionRequest request = (ArtifactResolutionRequest) args[0];
214                         assertThat( request.getArtifact() )
215                                 .isSameAs( provider );
216                         assertThat( request.isResolveTransitively() )
217                                 .isTrue();
218                         assertThat( request.getArtifactDependencies() )
219                                 .isNull();
220                         assertThat( request.getRemoteRepositories() )
221                                 .isNull();
222                         assertThat( request.getLocalRepository() )
223                                 .isNull();
224                         assertThat( request.getCache() )
225                                 .isNull();
226                         assertThat( request.getCollectionFilter() )
227                                 .isNotNull();
228                         assertThat( request.getCollectionFilter() )
229                                 .isInstanceOf( RuntimeArtifactFilter.class );
230                         assertThat( request.getManagedVersionMap() )
231                                 .isNull();
232                         assertThat( request.getMirrors() )
233                                 .isEmpty();
234                         assertThat( request.getProxies() )
235                                 .isEmpty();
236                         assertThat( request.getResolutionFilter() )
237                                 .isNull();
238                         assertThat( request.getServers() )
239                                 .isEmpty();
240                         return result;
241                     }
242                 } );
243         when( repositorySystem.createDependencyArtifact( any( Dependency.class ) ) )
244                 .then( new Answer<Artifact>()
245                 {
246                     @Override
247                     public Artifact answer( InvocationOnMock invocation )
248                     {
249                         Object[] args = invocation.getArguments();
250                         assertThat( args )
251                                 .hasSize( 1 );
252                         Dependency request = (Dependency) args[0];
253                         assertThat( request.getGroupId() )
254                                 .isEqualTo( provider.getGroupId() );
255                         assertThat( request.getArtifactId() )
256                                 .isEqualTo( provider.getArtifactId() );
257                         assertThat( request.getVersion() )
258                                 .isEqualTo( provider.getVersion() );
259                         assertThat( request.getType() )
260                                 .isEqualTo( provider.getType() );
261                         assertThat( request.getScope() )
262                                 .isNull();
263                         return provider;
264                     }
265                 } );
266 
267         ConsoleLogger log = mock( ConsoleLogger.class );
268 
269         SurefireDependencyResolver surefireDependencyResolver =
270                 new SurefireDependencyResolver( repositorySystem, log, null, null, null, null, null, false );
271 
272         when( log.isDebugEnabled() )
273                 .thenReturn( true );
274 
275         Set<Artifact> classpath = surefireDependencyResolver.getProviderClasspath( "surefire-junit-platform", "1" );
276 
277         assertThat( classpath )
278                 .hasSize( 4 );
279 
280         Iterator<Artifact> it = classpath.iterator();
281 
282         assertThat( it.next() )
283                 .isSameAs( provider );
284 
285         assertThat( it.next() )
286                 .isSameAs( api );
287 
288         assertThat( it.next() )
289                 .isSameAs( logger );
290 
291         assertThat( it.next() )
292                 .isSameAs( ext );
293     }
294 
295     @Test
296     public void testAddProviderToClasspath() throws Exception
297     {
298         Dependency providerAsDependency = new Dependency();
299         providerAsDependency.setGroupId( PROVIDER_GROUP_ID );
300         providerAsDependency.setArtifactId( "surefire-shadefire" );
301         providerAsDependency.setVersion( "1" );
302 
303         final Artifact providerAsArtifact = createArtifact( "surefire-shadefire" );
304 
305         PluginDescriptor pluginDescriptor = PowerMockito.mock( PluginDescriptor.class );
306         Plugin plugin = PowerMockito.mock( Plugin.class );
307         when( pluginDescriptor.getPlugin() )
308             .thenReturn( plugin );
309         when( plugin.getDependencies() )
310             .thenReturn( singletonList( providerAsDependency ) );
311 
312         DependencyResolver depencencyResolver = mock( DependencyResolver.class );
313         SurefireDependencyResolver surefireDependencyResolver =
314             new SurefireDependencyResolver( null, null, null, null, null, null, depencencyResolver, false );
315 
316         ProjectBuildingRequest request = mock( ProjectBuildingRequest.class );
317 
318         ArgumentCaptor<Collection<Dependency>> dep = ArgumentCaptor.forClass( Collection.class );
319         ArgumentCaptor<ScopeFilter> filter = ArgumentCaptor.forClass( ScopeFilter.class );
320         ArtifactResult result = mock( ArtifactResult.class );
321         when( result.getArtifact() ).thenReturn( providerAsArtifact );
322         when( depencencyResolver.resolveDependencies( same( request ), dep.capture(), isNull( Collection.class ),
323             filter.capture() ) )
324             .thenReturn( singleton( result ) );
325 
326         final ArtifactResolutionResult resolutionResult = mock( ArtifactResolutionResult.class );
327         when( resolutionResult.getArtifacts() )
328             .thenReturn( singleton( providerAsArtifact ) );
329 
330         Map<String, Artifact> pluginResolvedDependencies =
331             singletonMap( PROVIDER_GROUP_ID + ":surefire-shadefire", providerAsArtifact );
332         Map<String, Artifact> providers =
333             surefireDependencyResolver.resolvePluginDependencies( request, plugin, pluginResolvedDependencies );
334 
335         verify( depencencyResolver, times( 1 ) )
336             .resolveDependencies( request, dep.getValue(), null, filter.getValue() );
337 
338         assertThat( providers.values() )
339             .hasSize( 1 )
340             .containsOnly( providerAsArtifact );
341 
342         assertThat( dep.getValue() )
343             .hasSize( 1 )
344             .containsOnly( providerAsDependency );
345 
346         assertThat( filter.getValue().getIncluded() )
347             .containsOnly( SCOPE_COMPILE, SCOPE_COMPILE_PLUS_RUNTIME, SCOPE_RUNTIME );
348 
349         assertThat( filter.getValue().getExcluded() )
350 
351             .isNull();
352     }
353 
354     @Test
355     public void shouldOrderedProviderArtifacts() throws Exception
356     {
357         Artifact api = createArtifact( "surefire-api" );
358         Artifact provider = createArtifact( "surefire-junit-platform" );
359         Artifact ext = createArtifact( "org.apiguardian", "apiguardian-api" );
360         Artifact logger = createArtifact( "surefire-logger-api" );
361 
362         Set<Artifact> providerArtifacts = new LinkedHashSet<>();
363         providerArtifacts.add( api );
364         providerArtifacts.add( provider );
365         providerArtifacts.add( ext );
366         providerArtifacts.add( logger );
367 
368         Iterator<Artifact> it = providerArtifacts.iterator();
369 
370         assertThat( it.next() )
371                 .isEqualTo( api );
372 
373         assertThat( it.next() )
374                 .isEqualTo( provider );
375 
376         assertThat( it.next() )
377                 .isEqualTo( ext );
378 
379         assertThat( it.next() )
380                 .isEqualTo( logger );
381 
382         Set<Artifact> actual =
383                 invokeMethod( SurefireDependencyResolver.class, "orderProviderArtifacts", providerArtifacts );
384 
385         Set<Artifact> expected = new LinkedHashSet<>();
386         expected.add( provider );
387         expected.add( api );
388         expected.add( logger );
389         expected.add( ext );
390 
391         assertThat( actual )
392                 .isEqualTo( expected );
393     }
394 
395     private static Artifact createArtifact( String artifactId ) throws InvalidVersionSpecificationException
396     {
397         return createArtifact( PROVIDER_GROUP_ID, artifactId );
398     }
399 
400     private static Artifact createArtifact( String groupId, String artifactId )
401             throws InvalidVersionSpecificationException
402     {
403         return createArtifact( groupId, artifactId, "1" );
404     }
405 
406     private static Artifact createArtifact( String groupId, String artifactId, String version )
407             throws InvalidVersionSpecificationException
408     {
409         VersionRange versionSpec = createFromVersionSpec( version );
410         return new DefaultArtifact( groupId, artifactId, versionSpec, "compile", "jar", "", null );
411     }
412 }