View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugin.surefire;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.io.OutputStream;
24  import java.io.UncheckedIOException;
25  import java.nio.file.Files;
26  import java.nio.file.Path;
27  import java.nio.file.Paths;
28  import java.util.ArrayList;
29  import java.util.Collection;
30  import java.util.Collections;
31  import java.util.HashMap;
32  import java.util.HashSet;
33  import java.util.LinkedHashMap;
34  import java.util.LinkedHashSet;
35  import java.util.LinkedList;
36  import java.util.List;
37  import java.util.Map;
38  import java.util.Properties;
39  import java.util.Set;
40  
41  import org.apache.commons.io.FileUtils;
42  import org.apache.maven.artifact.Artifact;
43  import org.apache.maven.artifact.DefaultArtifact;
44  import org.apache.maven.artifact.handler.ArtifactHandler;
45  import org.apache.maven.artifact.handler.DefaultArtifactHandler;
46  import org.apache.maven.artifact.versioning.VersionRange;
47  import org.apache.maven.execution.MavenSession;
48  import org.apache.maven.model.Dependency;
49  import org.apache.maven.model.Plugin;
50  import org.apache.maven.plugin.MojoFailureException;
51  import org.apache.maven.plugin.descriptor.PluginDescriptor;
52  import org.apache.maven.plugin.surefire.booterclient.Platform;
53  import org.apache.maven.plugin.surefire.log.PluginConsoleLogger;
54  import org.apache.maven.project.MavenProject;
55  import org.apache.maven.surefire.api.suite.RunResult;
56  import org.apache.maven.surefire.api.util.DefaultScanResult;
57  import org.apache.maven.surefire.api.util.SureFireFileManager;
58  import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
59  import org.apache.maven.surefire.booter.Classpath;
60  import org.apache.maven.surefire.booter.ModularClasspathConfiguration;
61  import org.apache.maven.surefire.booter.StartupConfiguration;
62  import org.apache.maven.surefire.extensions.ForkNodeFactory;
63  import org.apache.maven.surefire.providerapi.ProviderInfo;
64  import org.apache.maven.toolchain.Toolchain;
65  import org.assertj.core.api.Assertions;
66  import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor;
67  import org.codehaus.plexus.languages.java.jpms.LocationManager;
68  import org.codehaus.plexus.languages.java.jpms.ResolvePathRequest;
69  import org.codehaus.plexus.languages.java.jpms.ResolvePathResult;
70  import org.codehaus.plexus.languages.java.jpms.ResolvePathsRequest;
71  import org.codehaus.plexus.languages.java.jpms.ResolvePathsResult;
72  import org.junit.Before;
73  import org.junit.Rule;
74  import org.junit.Test;
75  import org.junit.rules.TemporaryFolder;
76  import org.junit.runner.RunWith;
77  import org.mockito.ArgumentCaptor;
78  import org.mockito.Mock;
79  import org.powermock.core.classloader.annotations.PowerMockIgnore;
80  import org.powermock.core.classloader.annotations.PrepareForTest;
81  import org.powermock.modules.junit4.PowerMockRunner;
82  import org.slf4j.Logger;
83  
84  import static java.io.File.separatorChar;
85  import static java.nio.charset.StandardCharsets.UTF_8;
86  import static java.nio.file.Files.write;
87  import static java.util.Arrays.asList;
88  import static java.util.Collections.emptyList;
89  import static java.util.Collections.emptyMap;
90  import static java.util.Collections.singleton;
91  import static java.util.Collections.singletonList;
92  import static org.apache.maven.artifact.ArtifactUtils.artifactMapByVersionlessId;
93  import static org.apache.maven.artifact.versioning.VersionRange.createFromVersion;
94  import static org.apache.maven.artifact.versioning.VersionRange.createFromVersionSpec;
95  import static org.apache.maven.surefire.shared.lang3.JavaVersion.JAVA_9;
96  import static org.apache.maven.surefire.shared.lang3.JavaVersion.JAVA_RECENT;
97  import static org.apache.maven.surefire.shared.lang3.SystemUtils.IS_OS_WINDOWS;
98  import static org.assertj.core.api.Assertions.assertThat;
99  import static org.codehaus.plexus.languages.java.jpms.ModuleNameSource.MODULEDESCRIPTOR;
100 import static org.junit.Assert.assertThrows;
101 import static org.mockito.ArgumentMatchers.any;
102 import static org.mockito.ArgumentMatchers.anyString;
103 import static org.mockito.ArgumentMatchers.eq;
104 import static org.mockito.Mockito.times;
105 import static org.mockito.Mockito.verify;
106 import static org.mockito.Mockito.when;
107 import static org.powermock.api.mockito.PowerMockito.doNothing;
108 import static org.powermock.api.mockito.PowerMockito.doReturn;
109 import static org.powermock.api.mockito.PowerMockito.mock;
110 import static org.powermock.api.mockito.PowerMockito.spy;
111 import static org.powermock.api.mockito.PowerMockito.verifyPrivate;
112 import static org.powermock.reflect.Whitebox.invokeMethod;
113 import static org.powermock.reflect.Whitebox.setInternalState;
114 
115 /**
116  * Test for {@link AbstractSurefireMojo}.
117  */
118 @RunWith(PowerMockRunner.class)
119 @PrepareForTest(AbstractSurefireMojo.class)
120 @PowerMockIgnore({"org.jacoco.agent.rt.*", "com.vladium.emma.rt.*"})
121 public class AbstractSurefireMojoTest {
122 
123     @Rule
124     public final TemporaryFolder tempFolder = new TemporaryFolder();
125 
126     @Mock
127     private ArtifactHandler handler;
128 
129     private final Mojo mojo = new Mojo();
130 
131     @Before
132     public void setupMojo() {
133         Artifact mojoArtifact = mojo.getMojoArtifact();
134 
135         mojo.setProperties(new Properties());
136 
137         mojo.setPluginArtifactMap(new LinkedHashMap<>());
138         mojo.getPluginArtifactMap().put(mojoArtifact.getGroupId() + ":" + mojoArtifact.getArtifactId(), mojoArtifact);
139         Artifact forkedBooter = new DefaultArtifact(
140                 "org.apache.maven.surefire",
141                 "surefire-booter",
142                 mojoArtifact.getVersion(),
143                 null,
144                 "jar",
145                 null,
146                 mock(ArtifactHandler.class));
147         mojo.getPluginArtifactMap().put("org.apache.maven.surefire:surefire-booter", forkedBooter);
148 
149         mojo.setProjectArtifactMap(new LinkedHashMap<>());
150 
151         MavenSession session = mock(MavenSession.class);
152         mojo.setSession(session);
153 
154         PluginDescriptor pluginDescriptor = mock(PluginDescriptor.class);
155         Plugin plugin = new Plugin();
156         plugin.setGroupId(mojoArtifact.getGroupId());
157         plugin.setArtifactId(mojoArtifact.getArtifactId());
158         plugin.setVersion(mojoArtifact.getVersion());
159         when(pluginDescriptor.getPlugin()).thenReturn(plugin);
160         mojo.setPluginDescriptor(pluginDescriptor);
161     }
162 
163     @Test
164     public void noModuleDescriptorFile() throws Exception {
165         AbstractSurefireMojo mojo = spy(new Mojo());
166         mojo.setMainBuildPath(tempFolder.newFolder());
167         File testClassesDir = tempFolder.newFolder();
168         mojo.setTestClassesDirectory(testClassesDir);
169         File jdkHome = new File(System.getProperty("java.home"));
170         ResolvePathResultWrapper wrapper = invokeMethod(mojo, "findModuleDescriptor", jdkHome);
171 
172         assertThat(wrapper).isNotNull();
173 
174         assertThat(wrapper.getResolvePathResult()).isNull();
175 
176         assertThat((boolean) invokeMethod(mojo, "existsModuleDescriptor", wrapper))
177                 .isEqualTo(false);
178 
179         when(mojo.useModulePath()).thenReturn(true);
180 
181         File jvmExecutable = new File(jdkHome, IS_OS_WINDOWS ? "bin\\java.exe" : "bin/java");
182         JdkAttributes jdkAttributes = new JdkAttributes(jvmExecutable, jdkHome, true);
183         Platform platform = new Platform().withJdkExecAttributesForTests(jdkAttributes);
184         assertThat((boolean) invokeMethod(mojo, "canExecuteProviderWithModularPath", platform, wrapper))
185                 .isEqualTo(false);
186     }
187 
188     @Test
189     public void correctModuleDescriptor() throws Exception {
190         AbstractSurefireMojo mojo = spy(new Mojo());
191         LocationManager locationManager = mock(LocationManager.class);
192         ResolvePathResult result = mock(ResolvePathResult.class);
193         when(result.getModuleNameSource()).thenReturn(MODULEDESCRIPTOR);
194         JavaModuleDescriptor descriptor = mock(JavaModuleDescriptor.class);
195         when(result.getModuleDescriptor()).thenReturn(descriptor);
196         when(locationManager.resolvePath(any(ResolvePathRequest.class))).thenReturn(result);
197         doReturn(locationManager).when(mojo, "getLocationManager");
198         File classesDir = tempFolder.newFolder();
199         mojo.setMainBuildPath(classesDir);
200         File testClassesDir = tempFolder.newFolder();
201         mojo.setTestClassesDirectory(testClassesDir);
202         File descriptorFile = new File(classesDir, "module-info.class");
203         assertThat(descriptorFile.createNewFile()).isTrue();
204         File jdkHome = new File(System.getProperty("java.home"));
205         ResolvePathResultWrapper wrapper = invokeMethod(mojo, "findModuleDescriptor", jdkHome);
206 
207         assertThat(wrapper).isNotNull();
208 
209         assertThat(wrapper.getResolvePathResult()).isSameAs(result);
210 
211         assertThat(wrapper.getResolvePathResult().getModuleNameSource()).isSameAs(MODULEDESCRIPTOR);
212 
213         assertThat(wrapper.getResolvePathResult().getModuleDescriptor()).isSameAs(descriptor);
214 
215         assertThat((boolean) invokeMethod(mojo, "existsModuleDescriptor", wrapper))
216                 .isEqualTo(true);
217 
218         when(mojo.useModulePath()).thenReturn(true);
219 
220         File jvmExecutable = new File(jdkHome, IS_OS_WINDOWS ? "bin\\java.exe" : "bin/java");
221         JdkAttributes jdkAttributes = new JdkAttributes(jvmExecutable, jdkHome, true);
222         Platform platform = new Platform().withJdkExecAttributesForTests(jdkAttributes);
223         assertThat((boolean) invokeMethod(mojo, "canExecuteProviderWithModularPath", platform, wrapper))
224                 .isEqualTo(true);
225 
226         jdkAttributes = new JdkAttributes(jvmExecutable, jdkHome, false);
227         platform = new Platform().withJdkExecAttributesForTests(jdkAttributes);
228         assertThat((boolean) invokeMethod(mojo, "canExecuteProviderWithModularPath", platform, wrapper))
229                 .isEqualTo(false);
230 
231         when(mojo.useModulePath()).thenReturn(false);
232 
233         jdkAttributes = new JdkAttributes(jvmExecutable, jdkHome, true);
234         platform = new Platform().withJdkExecAttributesForTests(jdkAttributes);
235         assertThat((boolean) invokeMethod(mojo, "canExecuteProviderWithModularPath", platform, wrapper))
236                 .isEqualTo(false);
237     }
238 
239     @Test
240     @SuppressWarnings("checkstyle:magicnumber")
241     public void corruptedModuleDescriptor() throws Exception {
242         if (!JAVA_RECENT.atLeast(JAVA_9)) {
243             return;
244         }
245 
246         AbstractSurefireMojo mojo = spy(new Mojo());
247         doReturn(new LocationManager()).when(mojo, "getLocationManager");
248         File classesDir = tempFolder.newFolder();
249         mojo.setMainBuildPath(classesDir);
250         File testClassesDir = tempFolder.newFolder();
251         mojo.setTestClassesDirectory(testClassesDir);
252 
253         File descriptorFile = new File(classesDir, "module-info.class");
254         assertThat(descriptorFile.createNewFile()).isTrue();
255         write(descriptorFile.toPath(), new byte[] {(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE});
256 
257         File jdkHome = new File(System.getProperty("java.home"));
258         ResolvePathResultWrapper wrapper = invokeMethod(mojo, "findModuleDescriptor", jdkHome);
259 
260         assertThat(wrapper).isNotNull();
261 
262         assertThat(wrapper.getResolvePathResult()).isNull();
263 
264         assertThat((boolean) invokeMethod(mojo, "existsModuleDescriptor", wrapper))
265                 .isEqualTo(false);
266     }
267 
268     @Test
269     public void shouldShowArray() throws Exception {
270         Logger logger = mock(Logger.class);
271         when(logger.isDebugEnabled()).thenReturn(true);
272         doNothing().when(logger).debug(anyString());
273 
274         AbstractSurefireMojo mojo = spy(this.mojo);
275 
276         when(mojo.getConsoleLogger()).thenReturn(new PluginConsoleLogger(logger));
277 
278         Object[] array = {"ABC", "XYZ"};
279         invokeMethod(mojo, "showArray", array, "prefix");
280 
281         ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
282         verify(logger, times(2)).debug(argument.capture());
283         assertThat(argument.getAllValues()).containsExactly("Setting prefix [ABC]", "Setting prefix [XYZ]");
284     }
285 
286     @Test
287     public void shouldShowMap() throws Exception {
288         Logger logger = mock(Logger.class);
289         when(logger.isDebugEnabled()).thenReturn(true);
290         doNothing().when(logger).debug(anyString());
291 
292         AbstractSurefireMojo mojo = spy(this.mojo);
293 
294         when(mojo.getConsoleLogger()).thenReturn(new PluginConsoleLogger(logger));
295 
296         Map<String, String> map = new LinkedHashMap<>();
297         map.put("ABC", "123");
298         map.put("XYZ", "987");
299         invokeMethod(mojo, "showMap", map, "prefix");
300 
301         ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
302         verify(logger, times(2)).debug(argument.capture());
303         assertThat(argument.getAllValues()).containsExactly("Setting prefix [ABC]=[123]", "Setting prefix [XYZ]=[987]");
304     }
305 
306     @Test
307     public void shouldRetainInPluginArtifacts() throws Exception {
308         Artifact provider = new DefaultArtifact("g", "a", createFromVersionSpec("1"), "compile", "jar", "", null);
309         Artifact common = new DefaultArtifact("g", "c", createFromVersionSpec("1"), "compile", "jar", "", null);
310         Artifact api = new DefaultArtifact("g", "a", createFromVersionSpec("1"), "compile", "jar", "", null);
311 
312         Set<Artifact> providerArtifacts = singleton(provider);
313         Artifact[] inPluginArtifacts = {common, api};
314         Set<Artifact> inPluginClasspath = invokeMethod(
315                 AbstractSurefireMojo.class, "retainInProcArtifactsUnique", providerArtifacts, inPluginArtifacts);
316 
317         assertThat(inPluginClasspath).containsOnly(common);
318     }
319 
320     @Test
321     public void shouldRetainInProcArtifactsUnique() throws Exception {
322         Artifact provider = new DefaultArtifact("g", "p", createFromVersionSpec("1"), "compile", "jar", "", null);
323         Artifact common = new DefaultArtifact("g", "c", createFromVersionSpec("1"), "compile", "jar", "", null);
324         Artifact api = new DefaultArtifact("g", "a", createFromVersionSpec("1"), "compile", "jar", "", null);
325 
326         Set<Artifact> providerArtifacts = singleton(provider);
327         Artifact[] inPluginArtifacts = {common, api};
328         Set<Artifact> inPluginClasspath = invokeMethod(
329                 AbstractSurefireMojo.class, "retainInProcArtifactsUnique", providerArtifacts, inPluginArtifacts);
330 
331         assertThat(inPluginClasspath).containsOnly(common, api);
332     }
333 
334     @Test
335     public void shouldCreateInProcClasspath() throws Exception {
336         Artifact provider = new DefaultArtifact("g", "p", createFromVersionSpec("1"), "compile", "jar", "", null);
337         provider.setFile(mockFile("provider.jar"));
338 
339         Artifact common = new DefaultArtifact("g", "c", createFromVersionSpec("1"), "compile", "jar", "", null);
340         common.setFile(mockFile("maven-surefire-common.jar"));
341 
342         Artifact api = new DefaultArtifact("g", "a", createFromVersionSpec("1"), "compile", "jar", "", null);
343         api.setFile(mockFile("surefire-api.jar"));
344 
345         Set<Artifact> newArtifacts = new LinkedHashSet<>();
346         newArtifacts.add(common);
347         newArtifacts.add(api);
348 
349         Classpath providerClasspath = new Classpath(singleton(provider.getFile().getAbsolutePath()));
350 
351         Classpath inPluginClasspath =
352                 invokeMethod(AbstractSurefireMojo.class, "createInProcClasspath", providerClasspath, newArtifacts);
353 
354         Classpath expectedClasspath = new Classpath(asList(
355                 provider.getFile().getAbsolutePath(),
356                 common.getFile().getAbsolutePath(),
357                 api.getFile().getAbsolutePath()));
358 
359         assertThat((Object) inPluginClasspath).isEqualTo(expectedClasspath);
360     }
361 
362     @Test
363     public void shouldGenerateTestClasspath() throws Exception {
364         AbstractSurefireMojo mojo = spy(this.mojo);
365 
366         when(mojo.getMainBuildPath()).thenReturn(new File("target" + separatorChar + "classes"));
367         when(mojo.getTestClassesDirectory()).thenReturn(new File("target" + separatorChar + "test-classes"));
368         when(mojo.getClasspathDependencyScopeExclude()).thenReturn("runtime");
369         when(mojo.getClasspathDependencyExcludes()).thenReturn(new String[] {"g3:a3"});
370         doReturn(mock(Artifact.class)).when(mojo, "getTestNgArtifact");
371 
372         Set<Artifact> artifacts = new HashSet<>();
373 
374         Artifact a1 = mock(Artifact.class);
375         when(a1.getGroupId()).thenReturn("g1");
376         when(a1.getArtifactId()).thenReturn("a1");
377         when(a1.getVersion()).thenReturn("1");
378         when(a1.getScope()).thenReturn("runtime");
379         when(a1.getDependencyConflictId()).thenReturn("g1:a1:jar");
380         when(a1.getId()).thenReturn("g1:a1:jar:1");
381         artifacts.add(a1);
382 
383         ArtifactHandler artifactHandler = mock(ArtifactHandler.class);
384         when(artifactHandler.isAddedToClasspath()).thenReturn(true);
385 
386         Artifact a2 = mock(Artifact.class);
387         when(a2.getGroupId()).thenReturn("g2");
388         when(a2.getArtifactId()).thenReturn("a2");
389         when(a2.getVersion()).thenReturn("2");
390         when(a2.getScope()).thenReturn("test");
391         when(a2.getDependencyConflictId()).thenReturn("g2:a2:jar");
392         when(a2.getId()).thenReturn("g2:a2:jar:2");
393         when(a2.getFile()).thenReturn(new File("a2-2.jar"));
394         when(a2.getArtifactHandler()).thenReturn(artifactHandler);
395         artifacts.add(a2);
396 
397         Artifact a3 = mock(Artifact.class);
398         when(a3.getGroupId()).thenReturn("g3");
399         when(a3.getArtifactId()).thenReturn("a3");
400         when(a3.getVersion()).thenReturn("3");
401         when(a3.getScope()).thenReturn("test");
402         when(a3.getDependencyConflictId()).thenReturn("g3:a3:jar");
403         when(a3.getId()).thenReturn("g3:a3:jar:3");
404         when(a3.getFile()).thenReturn(new File("a3-3.jar"));
405         when(a3.getArtifactHandler()).thenReturn(artifactHandler);
406         artifacts.add(a3);
407 
408         MavenProject project = mock(MavenProject.class);
409         when(project.getArtifacts()).thenReturn(artifacts);
410         when(mojo.getProject()).thenReturn(project);
411 
412         TestClassPath cp = invokeMethod(mojo, "generateTestClasspath");
413 
414         verifyPrivate(mojo, times(1)).invoke("generateTestClasspath");
415         verify(mojo, times(1)).getMainBuildPath();
416         verify(mojo, times(1)).getTestClassesDirectory();
417         verify(mojo, times(3)).getClasspathDependencyScopeExclude();
418         verify(mojo, times(2)).getClasspathDependencyExcludes();
419         verify(mojo, times(1)).getAdditionalClasspathElements();
420 
421         assertThat(cp.toClasspath().getClassPath()).hasSize(3);
422         assertThat(cp.toClasspath().getClassPath().get(0)).endsWith("test-classes");
423         assertThat(cp.toClasspath().getClassPath().get(1)).endsWith("classes");
424         assertThat(cp.toClasspath().getClassPath().get(2)).endsWith("a2-2.jar");
425     }
426 
427     @Test
428     @SuppressWarnings("checkstyle:linelength")
429     public void shouldHaveStartupConfigForNonModularClasspath() throws Exception {
430         AbstractSurefireMojo mojo = spy(this.mojo);
431 
432         Artifact common = new DefaultArtifact(
433                 "org.apache.maven.surefire",
434                 "maven-surefire-common",
435                 createFromVersion("1"),
436                 "runtime",
437                 "jar",
438                 "",
439                 handler);
440         common.setFile(mockFile("maven-surefire-common.jar"));
441 
442         Artifact ext = new DefaultArtifact(
443                 "org.apache.maven.surefire",
444                 "surefire-extensions-api",
445                 createFromVersion("1"),
446                 "runtime",
447                 "jar",
448                 "",
449                 handler);
450         ext.setFile(mockFile("surefire-extensions-api.jar"));
451 
452         Artifact api = new DefaultArtifact(
453                 "org.apache.maven.surefire", "surefire-api", createFromVersion("1"), "runtime", "jar", "", handler);
454         api.setFile(mockFile("surefire-api.jar"));
455 
456         Artifact loggerApi = new DefaultArtifact(
457                 "org.apache.maven.surefire",
458                 "surefire-logger-api",
459                 createFromVersion("1"),
460                 "runtime",
461                 "jar",
462                 "",
463                 handler);
464         loggerApi.setFile(mockFile("surefire-logger-api.jar"));
465 
466         Artifact spi = new DefaultArtifact(
467                 "org.apache.maven.surefire",
468                 "surefire-extensions-spi",
469                 createFromVersion("1"),
470                 "runtime",
471                 "jar",
472                 "",
473                 handler);
474         spi.setFile(mockFile("surefire-extensions-spi.jar"));
475 
476         Artifact booter = new DefaultArtifact(
477                 "org.apache.maven.surefire", "surefire-booter", createFromVersion("1"), "runtime", "jar", "", handler);
478         booter.setFile(mockFile("surefire-booter.jar"));
479 
480         Artifact utils = new DefaultArtifact(
481                 "org.apache.maven.surefire",
482                 "surefire-shared-utils",
483                 createFromVersion("1"),
484                 "runtime",
485                 "jar",
486                 "",
487                 handler);
488         utils.setFile(mockFile("surefire-shared-utils.jar"));
489 
490         Map<String, Artifact> providerArtifactsMap = new HashMap<>();
491         providerArtifactsMap.put("org.apache.maven.surefire:maven-surefire-common", common);
492         providerArtifactsMap.put("org.apache.maven.surefire:surefire-extensions-api", ext);
493         providerArtifactsMap.put("org.apache.maven.surefire:surefire-api", api);
494         providerArtifactsMap.put("org.apache.maven.surefire:surefire-logger-api", loggerApi);
495         providerArtifactsMap.put("org.apache.maven.surefire:surefire-extensions-spi", spi);
496         providerArtifactsMap.put("org.apache.maven.surefire:surefire-booter", booter);
497         providerArtifactsMap.put("org.apache.maven.surefire:surefire-shared-utils", utils);
498 
499         when(mojo.getPluginArtifactMap()).thenReturn(providerArtifactsMap);
500 
501         when(handler.isAddedToClasspath()).thenReturn(true);
502 
503         VersionRange v1 = createFromVersion("4.12");
504         Artifact junit = new DefaultArtifact("junit", "junit", v1, "test", "jar", "", handler);
505         junit.setFile(mockFile("junit.jar"));
506 
507         VersionRange v2 = createFromVersion("1.3.0");
508         Artifact hamcrest = new DefaultArtifact("org.hamcrest", "hamcrest-core", v2, "test", "jar", "", handler);
509         hamcrest.setFile(mockFile("hamcrest.jar"));
510 
511         File classesDir = mockFile("classes");
512         File testClassesDir = mockFile("test-classes");
513         TestClassPath testClasspath = new TestClassPath(asList(junit, hamcrest), classesDir, testClassesDir, null);
514 
515         doReturn(testClasspath).when(mojo, "generateTestClasspath");
516         doReturn(1).when(mojo, "getEffectiveForkCount");
517         doReturn(true).when(mojo, "effectiveIsEnableAssertions");
518         when(mojo.isChildDelegation()).thenReturn(false);
519 
520         ClassLoaderConfiguration classLoaderConfiguration = new ClassLoaderConfiguration(false, true);
521 
522         VersionRange v3 = createFromVersion("1");
523         Artifact provider = new DefaultArtifact("x", "surefire-provider", v3, "runtime", "jar", "", handler);
524         provider.setFile(mockFile("surefire-provider.jar"));
525         Set<Artifact> providerArtifacts = singleton(provider);
526 
527         Logger logger = mock(Logger.class);
528         when(logger.isDebugEnabled()).thenReturn(true);
529         doNothing().when(logger).debug(anyString());
530         when(mojo.getConsoleLogger()).thenReturn(new PluginConsoleLogger(logger));
531 
532         ProviderInfo providerInfo = mock(ProviderInfo.class);
533         when(providerInfo.getProviderName()).thenReturn("org.asf.Provider");
534         when(providerInfo.getProviderClasspath()).thenReturn(providerArtifacts);
535         when(providerInfo.decorateTestClassPath(any())).thenReturn(testClasspath);
536 
537         StartupConfiguration conf = invokeMethod(
538                 mojo, "newStartupConfigWithClasspath", classLoaderConfiguration, providerInfo, testClasspath);
539 
540         verify(mojo, times(1)).effectiveIsEnableAssertions();
541         verify(mojo, times(1)).isChildDelegation();
542         ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
543         verify(logger, times(6)).debug(argument.capture());
544         assertThat(argument.getAllValues())
545                 .containsExactly(
546                         "test classpath:  test-classes  classes  junit.jar  hamcrest.jar",
547                         "provider classpath:  surefire-provider.jar",
548                         "test(compact) classpath:  test-classes  classes  junit.jar  hamcrest.jar",
549                         "provider(compact) classpath:  surefire-provider.jar",
550                         "in-process classpath:  surefire-provider.jar  maven-surefire-common.jar  surefire-booter.jar  surefire-extensions-api.jar  surefire-api.jar  surefire-extensions-spi.jar  surefire-logger-api.jar  surefire-shared-utils.jar",
551                         "in-process(compact) classpath:  surefire-provider.jar  maven-surefire-common.jar  surefire-booter.jar  surefire-extensions-api.jar  surefire-api.jar  surefire-extensions-spi.jar  surefire-logger-api.jar  surefire-shared-utils.jar");
552 
553         assertThat(conf.getClassLoaderConfiguration()).isSameAs(classLoaderConfiguration);
554 
555         assertThat((Object) conf.getClasspathConfiguration().getTestClasspath()).isEqualTo(testClasspath.toClasspath());
556 
557         Collection<String> files = new ArrayList<>();
558         for (Artifact providerArtifact : providerArtifacts) {
559             files.add(providerArtifact.getFile().getAbsolutePath());
560         }
561         assertThat((Object) conf.getClasspathConfiguration().getProviderClasspath())
562                 .isEqualTo(new Classpath(files));
563 
564         assertThat((Object) conf.getClasspathConfiguration().isClassPathConfig())
565                 .isEqualTo(true);
566 
567         assertThat((Object) conf.getClasspathConfiguration().isModularPathConfig())
568                 .isEqualTo(false);
569 
570         assertThat((Object) conf.getClasspathConfiguration().isEnableAssertions())
571                 .isEqualTo(true);
572 
573         assertThat(conf.getProviderClassName()).isEqualTo("org.asf.Provider");
574     }
575 
576     @Test
577     public void providerClasspathCachingIsNotSharedAcrossMojoInstances() throws Exception {
578         ProviderInfo providerInfo = mock(ProviderInfo.class);
579         when(providerInfo.getProviderName()).thenReturn("test-provider");
580         Artifact provider =
581                 new DefaultArtifact("com.example", "provider", createFromVersion("1"), "runtime", "jar", "", handler);
582         provider.setFile(mockFile("original-test-provider.jar"));
583         Set<Artifact> providerClasspath = singleton(provider);
584         when(providerInfo.getProviderClasspath()).thenReturn(providerClasspath);
585         TestClassPath testClassPath =
586                 new TestClassPath(providerClasspath, new File("target"), new File("target"), Collections.emptyList());
587         when(providerInfo.decorateTestClassPath(any())).thenReturn(testClassPath);
588 
589         StartupConfiguration startupConfiguration = startupConfigurationForProvider(providerInfo);
590         assertThat(startupConfiguration
591                         .getClasspathConfiguration()
592                         .getProviderClasspath()
593                         .getClassPath())
594                 .containsExactly("original-test-provider.jar");
595 
596         provider.setFile(mockFile("modified-test-provider.jar"));
597         startupConfiguration = startupConfigurationForProvider(providerInfo);
598         assertThat(startupConfiguration
599                         .getClasspathConfiguration()
600                         .getProviderClasspath()
601                         .getClassPath())
602                 .containsExactly("modified-test-provider.jar");
603     }
604 
605     private StartupConfiguration startupConfigurationForProvider(ProviderInfo providerInfo) throws Exception {
606         AbstractSurefireMojo mojo = spy(new Mojo());
607 
608         Logger logger = mock(Logger.class);
609         when(logger.isDebugEnabled()).thenReturn(true);
610         doNothing().when(logger).debug(anyString());
611         when(mojo.getConsoleLogger()).thenReturn(new PluginConsoleLogger(logger));
612 
613         File classesDir = mockFile("classes");
614         File testClassesDir = mockFile("test-classes");
615         TestClassPath testClassPath =
616                 new TestClassPath(new ArrayList<>(), classesDir, testClassesDir, Collections.emptyList());
617 
618         Artifact common = new DefaultArtifact(
619                 "org.apache.maven.surefire",
620                 "maven-surefire-common",
621                 createFromVersion("1"),
622                 "runtime",
623                 "jar",
624                 "",
625                 handler);
626         common.setFile(mockFile("maven-surefire-common.jar"));
627 
628         Artifact ext = new DefaultArtifact(
629                 "org.apache.maven.surefire",
630                 "surefire-extensions-api",
631                 createFromVersion("1"),
632                 "runtime",
633                 "jar",
634                 "",
635                 handler);
636         ext.setFile(mockFile("surefire-extensions-api.jar"));
637 
638         Artifact api = new DefaultArtifact(
639                 "org.apache.maven.surefire", "surefire-api", createFromVersion("1"), "runtime", "jar", "", handler);
640         api.setFile(mockFile("surefire-api.jar"));
641 
642         Artifact loggerApi = new DefaultArtifact(
643                 "org.apache.maven.surefire",
644                 "surefire-logger-api",
645                 createFromVersion("1"),
646                 "runtime",
647                 "jar",
648                 "",
649                 handler);
650         loggerApi.setFile(mockFile("surefire-logger-api.jar"));
651 
652         Artifact spi = new DefaultArtifact(
653                 "org.apache.maven.surefire",
654                 "surefire-extensions-spi",
655                 createFromVersion("1"),
656                 "runtime",
657                 "jar",
658                 "",
659                 handler);
660         spi.setFile(mockFile("surefire-extensions-spi.jar"));
661 
662         Artifact booter = new DefaultArtifact(
663                 "org.apache.maven.surefire", "surefire-booter", createFromVersion("1"), "runtime", "jar", "", handler);
664         booter.setFile(mockFile("surefire-booter.jar"));
665 
666         Artifact utils = new DefaultArtifact(
667                 "org.apache.maven.surefire",
668                 "surefire-shared-utils",
669                 createFromVersion("1"),
670                 "runtime",
671                 "jar",
672                 "",
673                 handler);
674         utils.setFile(mockFile("surefire-shared-utils.jar"));
675 
676         Map<String, Artifact> providerArtifactsMap = new HashMap<>();
677         providerArtifactsMap.put("org.apache.maven.surefire:maven-surefire-common", common);
678         providerArtifactsMap.put("org.apache.maven.surefire:surefire-extensions-api", ext);
679         providerArtifactsMap.put("org.apache.maven.surefire:surefire-api", api);
680         providerArtifactsMap.put("org.apache.maven.surefire:surefire-logger-api", loggerApi);
681         providerArtifactsMap.put("org.apache.maven.surefire:surefire-extensions-spi", spi);
682         providerArtifactsMap.put("org.apache.maven.surefire:surefire-booter", booter);
683         providerArtifactsMap.put("org.apache.maven.surefire:surefire-shared-utils", utils);
684 
685         when(mojo.getPluginArtifactMap()).thenReturn(providerArtifactsMap);
686 
687         doReturn(1).when(mojo, "getEffectiveForkCount");
688 
689         return invokeMethod(
690                 mojo, "createStartupConfiguration", providerInfo, false, null, null, testClassPath, null, null);
691     }
692 
693     @Test
694     public void shouldCreateStartupConfigWithModularPath() throws Exception {
695         String baseDir = System.getProperty("user.dir");
696 
697         Mojo mojo = new Mojo();
698 
699         // ### BEGIN
700         // we cannot mock private method newStartupConfigWithModularPath() - mocking the data to prevent from errors
701         LocationManager locationManager = mock(LocationManager.class);
702         ResolvePathsResult resolvePathsResult = mock(ResolvePathsResult.class);
703         when(locationManager.resolvePaths(any(ResolvePathsRequest.class))).thenReturn(resolvePathsResult);
704         when(resolvePathsResult.getPathExceptions()).thenReturn(emptyMap());
705         when(resolvePathsResult.getClasspathElements()).thenReturn(emptyList());
706         when(resolvePathsResult.getModulepathElements()).thenReturn(emptyMap());
707 
708         mojo.setLogger(mock(Logger.class));
709         mojo.setUseModulePath(true);
710         setInternalState(mojo, "locationManager", locationManager);
711 
712         File jdkHome = new File(System.getProperty("java.home"));
713         File jvmExecutable = new File(jdkHome, IS_OS_WINDOWS ? "bin\\java.exe" : "bin/java");
714         JdkAttributes jdkAttributes = new JdkAttributes(jvmExecutable, jdkHome, true);
715         Platform platform = new Platform().withJdkExecAttributesForTests(jdkAttributes);
716 
717         File classesDirectory = new File(baseDir, "mock-dir");
718         File testClassesDirectory = new File(baseDir, "mock-dir");
719         mojo.setTestClassesDirectory(testClassesDirectory);
720         TestClassPath testClassPath = new TestClassPath(
721                 Collections.emptySet(), classesDirectory, testClassesDirectory, Collections.emptyList());
722 
723         ProviderInfo providerInfo = mock(ProviderInfo.class);
724         when(providerInfo.getProviderName()).thenReturn("provider mock");
725         when(providerInfo.getProviderClasspath()).thenReturn(Collections.emptySet());
726 
727         DefaultScanResult defaultScanResult = mock(DefaultScanResult.class);
728         when(defaultScanResult.getClasses()).thenReturn(Collections.emptyList());
729 
730         Path pathToModularDescriptor =
731                 Paths.get(baseDir, "src", "test", "resources", "org", "apache", "maven", "plugin", "surefire");
732         mojo.setMainBuildPath(pathToModularDescriptor.toFile());
733 
734         Map<String, Artifact> artifacts = new HashMap<>();
735         Artifact dummyArtifact = mock(Artifact.class);
736         when(dummyArtifact.getFile()).thenReturn(new File(baseDir, "mock-file"));
737         artifacts.put("org.apache.maven.surefire:maven-surefire-common", dummyArtifact);
738         artifacts.put("org.apache.maven.surefire:surefire-extensions-api", dummyArtifact);
739         artifacts.put("org.apache.maven.surefire:surefire-api", dummyArtifact);
740         artifacts.put("org.apache.maven.surefire:surefire-logger-api", dummyArtifact);
741         artifacts.put("org.apache.maven.surefire:surefire-extensions-spi", dummyArtifact);
742         artifacts.put("org.apache.maven.surefire:surefire-booter", dummyArtifact);
743         artifacts.put("org.apache.maven.surefire:surefire-shared-utils", dummyArtifact);
744         mojo.setPluginArtifactMap(artifacts);
745 
746         ResolvePathResult resolvePathResult = mock(ResolvePathResult.class);
747         JavaModuleDescriptor desc = mock(JavaModuleDescriptor.class);
748         when(desc.name()).thenReturn("");
749         when(resolvePathResult.getModuleDescriptor()).thenReturn(desc);
750         ResolvePathResultWrapper wrapper = new ResolvePathResultWrapper(resolvePathResult, true);
751         // ### END
752 
753         StartupConfiguration actualConfig = invokeMethod(
754                 mojo,
755                 "createStartupConfiguration",
756                 new Class[] {
757                     ProviderInfo.class,
758                     boolean.class,
759                     ClassLoaderConfiguration.class,
760                     DefaultScanResult.class,
761                     TestClassPath.class,
762                     Platform.class,
763                     ResolvePathResultWrapper.class
764                 },
765                 providerInfo,
766                 true,
767                 mock(ClassLoaderConfiguration.class),
768                 defaultScanResult,
769                 testClassPath,
770                 platform,
771                 wrapper);
772 
773         assertThat(actualConfig).isNotNull();
774 
775         assertThat(actualConfig.getClasspathConfiguration()).isInstanceOf(ModularClasspathConfiguration.class);
776     }
777 
778     @Test
779     public void shouldExistTmpDirectory() throws IOException {
780         String systemTmpDir = System.getProperty("java.io.tmpdir");
781         String usrDir = new File(System.getProperty("user.dir")).getCanonicalPath();
782 
783         String tmpDir = "surefireX" + System.currentTimeMillis();
784 
785         //noinspection ResultOfMethodCallIgnored
786         new File(systemTmpDir, tmpDir).delete();
787 
788         File targetDir = new File(usrDir, "target");
789         //noinspection ResultOfMethodCallIgnored
790         new File(targetDir, tmpDir).delete();
791 
792         AbstractSurefireMojo mojo = mock(AbstractSurefireMojo.class);
793         Logger logger = mock(Logger.class);
794         when(logger.isDebugEnabled()).thenReturn(false);
795         when(logger.isErrorEnabled()).thenReturn(false);
796         doNothing().when(logger).debug(anyString());
797         doNothing().when(logger).error(anyString(), any(Throwable.class));
798         when(mojo.getConsoleLogger()).thenReturn(new PluginConsoleLogger(logger));
799         when(mojo.getTempDir()).thenReturn(tmpDir);
800         when(mojo.getProjectBuildDirectory()).thenReturn(targetDir);
801         when(mojo.createSurefireBootDirectoryInTemp()).thenCallRealMethod();
802         when(mojo.createSurefireBootDirectoryInBuild()).thenCallRealMethod();
803         when(mojo.getSurefireTempDir()).thenCallRealMethod();
804 
805         File bootDir = mojo.createSurefireBootDirectoryInTemp();
806         assertThat(bootDir).isNotNull();
807         assertThat(bootDir).isDirectory();
808 
809         assertThat(new File(systemTmpDir, bootDir.getName())).isDirectory();
810         assertThat(bootDir.getName()).startsWith(tmpDir);
811 
812         File buildTmp = mojo.createSurefireBootDirectoryInBuild();
813         assertThat(buildTmp).isNotNull();
814         assertThat(buildTmp).isDirectory();
815         assertThat(buildTmp.getParentFile().getCanonicalFile().getParent()).isEqualTo(usrDir);
816         assertThat(buildTmp.getName()).isEqualTo(tmpDir);
817 
818         File tmp = mojo.getSurefireTempDir();
819         assertThat(tmp).isNotNull();
820         assertThat(tmp).isDirectory();
821         assertThat(IS_OS_WINDOWS ? new File(systemTmpDir, bootDir.getName()) : new File(targetDir, tmpDir))
822                 .isDirectory();
823     }
824 
825     @Test
826     public void shouldSmartlyResolveJUnit5ProviderWithJUnit4() throws Exception {
827         MavenProject mavenProject = new MavenProject();
828         mavenProject.setArtifact(new DefaultArtifact(
829                 "dummy", "pom", createFromVersion("1.0.0"), null, "jar", null, mock(ArtifactHandler.class)));
830         mojo.setProject(mavenProject);
831 
832         final VersionRange surefireVersion = createFromVersion("1");
833 
834         Artifact testClasspathJUnit = new DefaultArtifact(
835                 "junit", "junit", createFromVersion("4.12"), null, "jar", null, mock(ArtifactHandler.class));
836 
837         Artifact testClasspathHamcrest = new DefaultArtifact(
838                 "org.hamcrest",
839                 "hamcrest-core",
840                 createFromVersion("1.3"),
841                 null,
842                 "jar",
843                 null,
844                 mock(ArtifactHandler.class));
845 
846         setProjectDepedenciesToMojo(testClasspathJUnit, testClasspathHamcrest);
847 
848         Collection<Artifact> testArtifacts = new ArrayList<>();
849         testArtifacts.add(testClasspathJUnit);
850         testArtifacts.add(testClasspathHamcrest);
851 
852         File classesDirectory = new File("target/classes");
853 
854         File testClassesDirectory = new File("target/test-classes");
855 
856         TestClassPath testClasspathWrapper =
857                 new TestClassPath(testArtifacts, classesDirectory, testClassesDirectory, null);
858 
859         SurefireDependencyResolver dependencyResolver = mock(SurefireDependencyResolver.class);
860         mojo.setSurefireDependencyResolver(dependencyResolver);
861 
862         when(dependencyResolver.getProviderClasspathAsMap(any(), any(), anyString(), anyString()))
863                 .thenReturn(artifactMapByVersionlessId(createSurefireProviderResolutionResult(surefireVersion)));
864 
865         when(dependencyResolver.resolveArtifacts(any(), any(), any(Artifact.class)))
866                 .thenReturn(createExpectedJUnitPlatformLauncherResolutionResult());
867 
868         final Artifact pluginDep1 = new DefaultArtifact(
869                 "org.junit.vintage", "junit-vintage-engine", createFromVersion("5.4.0"), null, "jar", "", null);
870 
871         final Artifact pluginDep2 = new DefaultArtifact(
872                 "org.apiguardian", "apiguardian-api", createFromVersion("1.0.0"), null, "jar", "", null);
873 
874         final Artifact pluginDep3 = new DefaultArtifact(
875                 "org.junit.platform",
876                 "junit-platform-engine",
877                 createFromVersion("1.4.0"),
878                 null,
879                 "jar",
880                 null,
881                 mock(ArtifactHandler.class));
882 
883         final Artifact pluginDep4 = new DefaultArtifact(
884                 "junit", "junit", createFromVersion("4.12"), null, "jar", null, mock(ArtifactHandler.class));
885 
886         final Artifact pluginDep5 = new DefaultArtifact(
887                 "org.hamcrest",
888                 "hamcrest-core",
889                 createFromVersion("1.3"),
890                 null,
891                 "jar",
892                 null,
893                 mock(ArtifactHandler.class));
894 
895         final Artifact pluginDep6 = new DefaultArtifact(
896                 "org.opentest4j",
897                 "opentest4j",
898                 createFromVersion("1.1.1"),
899                 null,
900                 "jar",
901                 null,
902                 mock(ArtifactHandler.class));
903 
904         final Artifact pluginDep7 = new DefaultArtifact(
905                 "org.junit.platform",
906                 "junit-platform-commons",
907                 createFromVersion("1.4.0"),
908                 null,
909                 "jar",
910                 null,
911                 mock(ArtifactHandler.class));
912 
913         addPluginDependencies(pluginDep1, pluginDep2, pluginDep3, pluginDep4, pluginDep5, pluginDep6, pluginDep7);
914 
915         mojo.setLogger(mock(Logger.class));
916 
917         Set<Artifact> pluginDependencyArtifacts = new HashSet<>();
918         pluginDependencyArtifacts.add(pluginDep1);
919         pluginDependencyArtifacts.add(pluginDep2);
920         pluginDependencyArtifacts.add(pluginDep3);
921         pluginDependencyArtifacts.add(pluginDep4);
922         pluginDependencyArtifacts.add(pluginDep5);
923         pluginDependencyArtifacts.add(pluginDep6);
924         pluginDependencyArtifacts.add(pluginDep7);
925 
926         when(dependencyResolver.resolvePluginDependencies(any(), any(), any(), any()))
927                 .thenReturn(artifactMapByVersionlessId(pluginDependencyArtifacts));
928 
929         PluginDescriptor pluginDescriptor = mock(PluginDescriptor.class);
930         mojo.setPluginDescriptor(pluginDescriptor);
931         Plugin p = mock(Plugin.class);
932         when(pluginDescriptor.getPlugin()).thenReturn(p);
933 
934         Artifact junitPlatformArtifact = invokeMethod(mojo, "getJUnit5Artifact");
935         assertThat(junitPlatformArtifact.getGroupId()).isEqualTo("org.junit.platform");
936         assertThat(junitPlatformArtifact.getArtifactId()).isEqualTo("junit-platform-engine");
937         assertThat(junitPlatformArtifact.getVersion()).isEqualTo("1.4.0");
938 
939         AbstractSurefireMojo.JUnitPlatformProviderInfo prov =
940                 mojo.createJUnitPlatformProviderInfo(junitPlatformArtifact, testClasspathWrapper);
941 
942         assertThat(prov.isApplicable()).isTrue();
943 
944         Artifact expectedProvider = new DefaultArtifact(
945                 "org.apache.maven.surefire", "surefire-junit-platform", surefireVersion, null, "jar", "", null);
946         Artifact expectedCommonJava5 = new DefaultArtifact(
947                 "org.apache.maven.surefire", "common-java5", surefireVersion, null, "jar", "", null);
948         Artifact expectedLauncher = new DefaultArtifact(
949                 "org.junit.platform", "junit-platform-launcher", createFromVersion("1.4.0"), null, "jar", "", null);
950         Artifact expectedApiguardian = new DefaultArtifact(
951                 "org.apiguardian", "apiguardian-api", createFromVersion("1.0.0"), null, "jar", "", null);
952         Artifact expectedJUnit5Engine = new DefaultArtifact(
953                 "org.junit.platform", "junit-platform-engine", createFromVersion("1.4.0"), null, "jar", "", null);
954         Artifact expectedOpentest4j =
955                 new DefaultArtifact("org.opentest4j", "opentest4j", createFromVersion("1.1.1"), null, "jar", "", null);
956         Artifact expectedPlatformCommons = new DefaultArtifact(
957                 "org.junit.platform", "junit-platform-commons", createFromVersion("1.4.0"), null, "jar", "", null);
958         Artifact expectedEngine = new DefaultArtifact(
959                 "org.junit.vintage", "junit-vintage-engine", createFromVersion("5.4.0"), null, "jar", "", null);
960 
961         assertThat(prov.getProviderClasspath())
962                 .hasSize(8)
963                 .containsOnly(
964                         expectedProvider,
965                         expectedCommonJava5,
966                         expectedLauncher,
967                         expectedApiguardian,
968                         expectedJUnit5Engine,
969                         expectedOpentest4j,
970                         expectedPlatformCommons,
971                         expectedEngine);
972 
973         assertThat(testClasspathWrapper.getTestDependencies())
974                 .hasSize(2)
975                 .containsEntry("junit:junit", testClasspathJUnit)
976                 .containsEntry("org.hamcrest:hamcrest-core", testClasspathHamcrest);
977     }
978 
979     @Test
980     public void shouldSmartlyResolveJUnit5ProviderWithVintage() throws Exception {
981         MavenProject mavenProject = new MavenProject();
982         mavenProject.setArtifact(new DefaultArtifact(
983                 "dummy", "pom", createFromVersion("1.0.0"), null, "jar", null, mock(ArtifactHandler.class)));
984         mojo.setProject(mavenProject);
985 
986         VersionRange surefireVersion = createFromVersion("1");
987 
988         Artifact testClasspathSomeTestArtifact = new DefaultArtifact(
989                 "third.party", "artifact", createFromVersion("1.0"), null, "jar", null, mock(ArtifactHandler.class));
990 
991         Artifact testClasspathVintage = new DefaultArtifact(
992                 "org.junit.vintage",
993                 "junit-vintage-engine",
994                 createFromVersion("5.4.0"),
995                 null,
996                 "jar",
997                 null,
998                 mock(ArtifactHandler.class));
999 
1000         Artifact testClasspathApiguardian = new DefaultArtifact(
1001                 "org.apiguardian",
1002                 "apiguardian-api",
1003                 createFromVersion("1.0.0"),
1004                 null,
1005                 "jar",
1006                 null,
1007                 mock(ArtifactHandler.class));
1008 
1009         Artifact testClasspathPlatformEng = new DefaultArtifact(
1010                 "org.junit.platform",
1011                 "junit-platform-engine",
1012                 createFromVersion("1.4.0"),
1013                 null,
1014                 "jar",
1015                 null,
1016                 mock(ArtifactHandler.class));
1017 
1018         Artifact testClasspathJUnit4 = new DefaultArtifact(
1019                 "junit", "junit", createFromVersion("4.12"), null, "jar", null, mock(ArtifactHandler.class));
1020 
1021         Artifact testClasspathHamcrest = new DefaultArtifact(
1022                 "org.hamcrest",
1023                 "hamcrest-core",
1024                 createFromVersion("1.3"),
1025                 null,
1026                 "jar",
1027                 null,
1028                 mock(ArtifactHandler.class));
1029 
1030         Artifact testClasspathOpentest4j = new DefaultArtifact(
1031                 "org.opentest4j",
1032                 "opentest4j",
1033                 createFromVersion("1.1.1"),
1034                 null,
1035                 "jar",
1036                 null,
1037                 mock(ArtifactHandler.class));
1038 
1039         Artifact testClasspathCommons = new DefaultArtifact(
1040                 "org.junit.platform",
1041                 "junit-platform-commons",
1042                 createFromVersion("1.4.0"),
1043                 null,
1044                 "jar",
1045                 null,
1046                 mock(ArtifactHandler.class));
1047 
1048         Collection<Artifact> testArtifacts = asList(
1049                 testClasspathSomeTestArtifact,
1050                 testClasspathVintage,
1051                 testClasspathApiguardian,
1052                 testClasspathPlatformEng,
1053                 testClasspathJUnit4,
1054                 testClasspathHamcrest,
1055                 testClasspathOpentest4j,
1056                 testClasspathCommons);
1057 
1058         setProjectDepedenciesToMojo(testArtifacts.toArray(new Artifact[0]));
1059 
1060         File classesDirectory = new File("target/classes");
1061 
1062         File testClassesDirectory = new File("target/test-classes");
1063 
1064         TestClassPath testClasspathWrapper =
1065                 new TestClassPath(testArtifacts, classesDirectory, testClassesDirectory, null);
1066 
1067         SurefireDependencyResolver dependencyResolver = mock(SurefireDependencyResolver.class);
1068         mojo.setSurefireDependencyResolver(dependencyResolver);
1069 
1070         when(dependencyResolver.getProviderClasspathAsMap(any(), any(), anyString(), anyString()))
1071                 .thenReturn(artifactMapByVersionlessId(createSurefireProviderResolutionResult(surefireVersion)));
1072 
1073         when(dependencyResolver.resolveArtifacts(any(), any(), any(Artifact.class)))
1074                 .thenReturn(createExpectedJUnitPlatformLauncherResolutionResult());
1075 
1076         mojo.setLogger(mock(Logger.class));
1077 
1078         PluginDescriptor pluginDescriptor = mock(PluginDescriptor.class);
1079         mojo.setPluginDescriptor(pluginDescriptor);
1080         Plugin p = mock(Plugin.class);
1081         when(pluginDescriptor.getPlugin()).thenReturn(p);
1082         when(p.getDependencies()).thenReturn(Collections.emptyList());
1083 
1084         Artifact junitPlatformArtifact = invokeMethod(mojo, "getJUnit5Artifact");
1085         assertThat(junitPlatformArtifact.getGroupId()).isEqualTo("org.junit.platform");
1086         assertThat(junitPlatformArtifact.getArtifactId()).isEqualTo("junit-platform-commons");
1087         assertThat(junitPlatformArtifact.getVersion()).isEqualTo("1.4.0");
1088 
1089         AbstractSurefireMojo.JUnitPlatformProviderInfo prov =
1090                 mojo.createJUnitPlatformProviderInfo(junitPlatformArtifact, testClasspathWrapper);
1091 
1092         assertThat(prov.isApplicable()).isTrue();
1093 
1094         Artifact expectedProvider = new DefaultArtifact(
1095                 "org.apache.maven.surefire", "surefire-junit-platform", surefireVersion, null, "jar", "", null);
1096         Artifact expectedCommonJava5 = new DefaultArtifact(
1097                 "org.apache.maven.surefire", "common-java5", surefireVersion, null, "jar", "", null);
1098         Artifact expectedLauncher = new DefaultArtifact(
1099                 "org.junit.platform", "junit-platform-launcher", createFromVersion("1.4.0"), null, "jar", "", null);
1100         assertThat(prov.getProviderClasspath())
1101                 .hasSize(3)
1102                 .containsOnly(expectedProvider, expectedCommonJava5, expectedLauncher);
1103 
1104         assertThat(testClasspathWrapper.getTestDependencies())
1105                 .hasSize(8)
1106                 .containsEntry("third.party:artifact", testClasspathSomeTestArtifact)
1107                 .containsEntry("org.junit.vintage:junit-vintage-engine", testClasspathVintage)
1108                 .containsEntry("org.apiguardian:apiguardian-api", testClasspathApiguardian)
1109                 .containsEntry("org.junit.platform:junit-platform-engine", testClasspathPlatformEng)
1110                 .containsEntry("junit:junit", testClasspathJUnit4)
1111                 .containsEntry("org.hamcrest:hamcrest-core", testClasspathHamcrest)
1112                 .containsEntry("org.opentest4j:opentest4j", testClasspathOpentest4j)
1113                 .containsEntry("org.junit.platform:junit-platform-commons", testClasspathCommons);
1114     }
1115 
1116     @Test
1117     public void shouldSmartlyResolveJUnit5ProviderWithJUnit5Commons() throws Exception {
1118         MavenProject mavenProject = new MavenProject();
1119         mavenProject.setArtifact(new DefaultArtifact(
1120                 "dummy", "pom", createFromVersion("1.0.0"), null, "jar", null, mock(ArtifactHandler.class)));
1121         mojo.setProject(mavenProject);
1122 
1123         final VersionRange surefireVersion = createFromVersion("1");
1124 
1125         Artifact testClasspathSomeTestArtifact = new DefaultArtifact(
1126                 "third.party", "artifact", createFromVersion("1.0"), null, "jar", null, mock(ArtifactHandler.class));
1127 
1128         Artifact testClasspathCommons = new DefaultArtifact(
1129                 "org.junit.platform",
1130                 "junit-platform-commons",
1131                 createFromVersion("1.4.0"),
1132                 null,
1133                 "jar",
1134                 null,
1135                 mock(ArtifactHandler.class));
1136 
1137         Artifact testClasspathApiguardian = new DefaultArtifact(
1138                 "org.apiguardian",
1139                 "apiguardian-api",
1140                 createFromVersion("1.0.0"),
1141                 null,
1142                 "jar",
1143                 null,
1144                 mock(ArtifactHandler.class));
1145 
1146         Collection<Artifact> testArtifacts =
1147                 asList(testClasspathSomeTestArtifact, testClasspathApiguardian, testClasspathCommons);
1148 
1149         setProjectDepedenciesToMojo(testArtifacts.toArray(new Artifact[0]));
1150 
1151         File classesDirectory = new File("target/classes");
1152 
1153         File testClassesDirectory = new File("target/test-classes");
1154 
1155         TestClassPath testClasspathWrapper =
1156                 new TestClassPath(testArtifacts, classesDirectory, testClassesDirectory, null);
1157 
1158         SurefireDependencyResolver dependencyResolver = mock(SurefireDependencyResolver.class);
1159         mojo.setSurefireDependencyResolver(dependencyResolver);
1160 
1161         when(dependencyResolver.getProviderClasspathAsMap(any(), any(), anyString(), anyString()))
1162                 .thenReturn(artifactMapByVersionlessId(createSurefireProviderResolutionResult(surefireVersion)));
1163 
1164         when(dependencyResolver.resolveArtifacts(any(), any(), any(Artifact.class)))
1165                 .thenReturn(createExpectedJUnitPlatformLauncherResolutionResult());
1166 
1167         mojo.setLogger(mock(Logger.class));
1168 
1169         invokeMethod(mojo, "setupStuff");
1170 
1171         PluginDescriptor pluginDescriptor = mock(PluginDescriptor.class);
1172         mojo.setPluginDescriptor(pluginDescriptor);
1173         Plugin p = mock(Plugin.class);
1174         when(pluginDescriptor.getPlugin()).thenReturn(p);
1175         when(p.getDependencies()).thenReturn(Collections.emptyList());
1176 
1177         Artifact junitPlatformArtifact = invokeMethod(mojo, "getJUnit5Artifact");
1178         assertThat(junitPlatformArtifact.getGroupId()).isEqualTo("org.junit.platform");
1179         assertThat(junitPlatformArtifact.getArtifactId()).isEqualTo("junit-platform-commons");
1180         assertThat(junitPlatformArtifact.getVersion()).isEqualTo("1.4.0");
1181 
1182         AbstractSurefireMojo.JUnitPlatformProviderInfo prov =
1183                 mojo.createJUnitPlatformProviderInfo(junitPlatformArtifact, testClasspathWrapper);
1184 
1185         assertThat(prov.isApplicable()).isTrue();
1186 
1187         Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
1188 
1189         Artifact provider = new DefaultArtifact(
1190                 "org.apache.maven.surefire", "surefire-junit-platform", surefireVersion, null, "jar", "", null);
1191         Artifact java5 = new DefaultArtifact(
1192                 "org.apache.maven.surefire", "common-java5", surefireVersion, null, "jar", "", null);
1193         Artifact launcher = new DefaultArtifact(
1194                 "org.junit.platform", "junit-platform-launcher", createFromVersion("1.4.0"), null, "jar", "", null);
1195         Artifact engine = new DefaultArtifact(
1196                 "org.junit.platform", "junit-platform-engine", createFromVersion("1.4.0"), null, "jar", "", null);
1197         Artifact opentest4j =
1198                 new DefaultArtifact("org.opentest4j", "opentest4j", createFromVersion("1.1.1"), null, "jar", "", null);
1199         assertThat(resolvedProviderArtifacts).hasSize(5).containsOnly(provider, java5, launcher, engine, opentest4j);
1200 
1201         assertThat(testClasspathWrapper.getTestDependencies())
1202                 .hasSize(3)
1203                 .containsEntry("third.party:artifact", testClasspathSomeTestArtifact)
1204                 .containsEntry("org.junit.platform:junit-platform-commons", testClasspathCommons)
1205                 .containsEntry("org.apiguardian:apiguardian-api", testClasspathApiguardian);
1206     }
1207 
1208     @Test
1209     public void shouldSmartlyResolveJUnit5ProviderWithJUnit5Engine() throws Exception {
1210         MavenProject mavenProject = new MavenProject();
1211         mavenProject.setArtifact(new DefaultArtifact(
1212                 "dummy", "pom", createFromVersion("1.0.0"), null, "jar", null, mock(ArtifactHandler.class)));
1213         mojo.setProject(mavenProject);
1214 
1215         final VersionRange surefireVersion = createFromVersion("1");
1216 
1217         final Artifact testClasspathSomeTestArtifact = new DefaultArtifact(
1218                 "third.party", "artifact", createFromVersion("1.0"), null, "jar", null, mock(ArtifactHandler.class));
1219 
1220         final Artifact testClasspathJUnit5 = new DefaultArtifact(
1221                 "org.junit.platform",
1222                 "junit-platform-engine",
1223                 createFromVersion("1.4.0"),
1224                 null,
1225                 "jar",
1226                 null,
1227                 mock(ArtifactHandler.class));
1228 
1229         final Artifact testClasspathApiguardian = new DefaultArtifact(
1230                 "org.apiguardian",
1231                 "apiguardian-api",
1232                 createFromVersion("1.0.0"),
1233                 null,
1234                 "jar",
1235                 null,
1236                 mock(ArtifactHandler.class));
1237 
1238         final Artifact testClasspathCommons = new DefaultArtifact(
1239                 "org.junit.platform",
1240                 "junit-platform-commons",
1241                 createFromVersion("1.4.0"),
1242                 null,
1243                 "jar",
1244                 null,
1245                 mock(ArtifactHandler.class));
1246 
1247         final Artifact testClasspathOpentest4j = new DefaultArtifact(
1248                 "org.opentest4j",
1249                 "opentest4j",
1250                 createFromVersion("1.1.1"),
1251                 null,
1252                 "jar",
1253                 null,
1254                 mock(ArtifactHandler.class));
1255 
1256         Collection<Artifact> testArtifacts = asList(
1257                 testClasspathSomeTestArtifact,
1258                 testClasspathJUnit5,
1259                 testClasspathApiguardian,
1260                 testClasspathCommons,
1261                 testClasspathOpentest4j);
1262 
1263         setProjectDepedenciesToMojo(testArtifacts.toArray(new Artifact[0]));
1264 
1265         File classesDirectory = new File("target/classes");
1266 
1267         File testClassesDirectory = new File("target/test-classes");
1268 
1269         TestClassPath testClasspathWrapper =
1270                 new TestClassPath(testArtifacts, classesDirectory, testClassesDirectory, null);
1271 
1272         SurefireDependencyResolver dependencyResolver = mock(SurefireDependencyResolver.class);
1273         mojo.setSurefireDependencyResolver(dependencyResolver);
1274 
1275         when(dependencyResolver.getProviderClasspathAsMap(any(), any(), anyString(), anyString()))
1276                 .thenReturn(artifactMapByVersionlessId(createSurefireProviderResolutionResult(surefireVersion)));
1277 
1278         when(dependencyResolver.resolveArtifacts(any(), any(), any(Artifact.class)))
1279                 .thenReturn(createExpectedJUnitPlatformLauncherResolutionResult());
1280 
1281         mojo.setLogger(mock(Logger.class));
1282 
1283         invokeMethod(mojo, "setupStuff");
1284 
1285         Artifact junitPlatformArtifact = invokeMethod(mojo, "getJUnit5Artifact");
1286         assertThat(junitPlatformArtifact.getGroupId()).isEqualTo("org.junit.platform");
1287         assertThat(junitPlatformArtifact.getArtifactId()).isEqualTo("junit-platform-commons");
1288         assertThat(junitPlatformArtifact.getVersion()).isEqualTo("1.4.0");
1289 
1290         AbstractSurefireMojo.JUnitPlatformProviderInfo prov =
1291                 mojo.createJUnitPlatformProviderInfo(junitPlatformArtifact, testClasspathWrapper);
1292 
1293         assertThat(prov.isApplicable()).isTrue();
1294 
1295         Artifact surefireProvider = new DefaultArtifact(
1296                 "org.apache.maven.surefire", "surefire-junit-platform", surefireVersion, null, "jar", "", null);
1297 
1298         Artifact java5 = new DefaultArtifact(
1299                 "org.apache.maven.surefire", "common-java5", surefireVersion, null, "jar", "", null);
1300         Artifact launcher = new DefaultArtifact(
1301                 "org.junit.platform", "junit-platform-launcher", createFromVersion("1.4.0"), null, "jar", "", null);
1302 
1303         Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
1304 
1305         assertThat(resolvedProviderArtifacts).hasSize(3).containsOnly(surefireProvider, java5, launcher);
1306 
1307         assertThat(testClasspathWrapper.getTestDependencies())
1308                 .hasSize(5)
1309                 .containsEntry("third.party:artifact", testClasspathSomeTestArtifact)
1310                 .containsEntry("org.junit.platform:junit-platform-engine", testClasspathJUnit5)
1311                 .containsEntry("org.apiguardian:apiguardian-api", testClasspathApiguardian)
1312                 .containsEntry("org.junit.platform:junit-platform-commons", testClasspathCommons)
1313                 .containsEntry("org.opentest4j:opentest4j", testClasspathOpentest4j);
1314     }
1315 
1316     @Test
1317     public void shouldSmartlyResolveJUnit5ProviderWithJupiterApi() throws Exception {
1318         MavenProject mavenProject = new MavenProject();
1319         mavenProject.setArtifact(new DefaultArtifact(
1320                 "dummy", "pom", createFromVersion("1.0.0"), null, "jar", null, mock(ArtifactHandler.class)));
1321         mojo.setProject(mavenProject);
1322 
1323         final VersionRange surefireVersion = createFromVersion("1");
1324 
1325         final Artifact testClasspathSomeTestArtifact = new DefaultArtifact(
1326                 "third.party", "artifact", createFromVersion("1.0"), null, "jar", null, mock(ArtifactHandler.class));
1327 
1328         final Artifact testClasspathJupiterApi = new DefaultArtifact(
1329                 "org.junit.jupiter",
1330                 "junit-jupiter-api",
1331                 createFromVersion("5.4.0"),
1332                 null,
1333                 "jar",
1334                 null,
1335                 mock(ArtifactHandler.class));
1336 
1337         final Artifact testClasspathApiguardian = new DefaultArtifact(
1338                 "org.apiguardian",
1339                 "apiguardian-api",
1340                 createFromVersion("1.0.0"),
1341                 null,
1342                 "jar",
1343                 null,
1344                 mock(ArtifactHandler.class));
1345 
1346         final Artifact testClasspathCommons = new DefaultArtifact(
1347                 "org.junit.platform",
1348                 "junit-platform-commons",
1349                 createFromVersion("1.4.0"),
1350                 null,
1351                 "jar",
1352                 null,
1353                 mock(ArtifactHandler.class));
1354 
1355         final Artifact testClasspathOpentest4j = new DefaultArtifact(
1356                 "org.opentest4j",
1357                 "opentest4j",
1358                 createFromVersion("1.1.1"),
1359                 null,
1360                 "jar",
1361                 null,
1362                 mock(ArtifactHandler.class));
1363 
1364         Collection<Artifact> testArtifacts = asList(
1365                 testClasspathSomeTestArtifact,
1366                 testClasspathJupiterApi,
1367                 testClasspathApiguardian,
1368                 testClasspathCommons,
1369                 testClasspathOpentest4j);
1370 
1371         setProjectDepedenciesToMojo(testArtifacts.toArray(new Artifact[0]));
1372 
1373         File classesDirectory = new File("target/classes");
1374 
1375         File testClassesDirectory = new File("target/test-classes");
1376 
1377         TestClassPath testClasspathWrapper =
1378                 new TestClassPath(testArtifacts, classesDirectory, testClassesDirectory, null);
1379 
1380         SurefireDependencyResolver dependencyResolver = mock(SurefireDependencyResolver.class);
1381         mojo.setSurefireDependencyResolver(dependencyResolver);
1382 
1383         when(dependencyResolver.getProviderClasspathAsMap(any(), any(), anyString(), anyString()))
1384                 .thenReturn(artifactMapByVersionlessId(createSurefireProviderResolutionResult(surefireVersion)));
1385 
1386         Artifact jUnitPlatformLauncherArtifact = new DefaultArtifact(
1387                 "org.junit.platform",
1388                 "junit-platform-launcher",
1389                 createFromVersion("1.4.0"),
1390                 null,
1391                 "jar",
1392                 null,
1393                 mock(ArtifactHandler.class));
1394 
1395         when(dependencyResolver.resolveArtifacts(any(), any(), eq(jUnitPlatformLauncherArtifact)))
1396                 .thenReturn(createExpectedJUnitPlatformLauncherResolutionResult());
1397 
1398         Artifact jupiterEngineArtifact = new DefaultArtifact(
1399                 "org.junit.jupiter",
1400                 "junit-jupiter-engine",
1401                 createFromVersion("5.4.0"),
1402                 null,
1403                 "jar",
1404                 null,
1405                 mock(ArtifactHandler.class));
1406 
1407         when(dependencyResolver.resolveArtifacts(any(), any(), eq(jupiterEngineArtifact)))
1408                 .thenReturn(createJupiterEngineResolutionResult());
1409 
1410         mojo.setLogger(mock(Logger.class));
1411 
1412         PluginDescriptor pluginDescriptor = mock(PluginDescriptor.class);
1413         mojo.setPluginDescriptor(pluginDescriptor);
1414         Plugin p = mock(Plugin.class);
1415         when(pluginDescriptor.getPlugin()).thenReturn(p);
1416         when(p.getDependencies()).thenReturn(Collections.emptyList());
1417 
1418         Artifact junitPlatformArtifact = invokeMethod(mojo, "getJUnit5Artifact");
1419         assertThat(junitPlatformArtifact.getGroupId()).isEqualTo("org.junit.platform");
1420         assertThat(junitPlatformArtifact.getArtifactId()).isEqualTo("junit-platform-commons");
1421         assertThat(junitPlatformArtifact.getVersion()).isEqualTo("1.4.0");
1422 
1423         AbstractSurefireMojo.JUnitPlatformProviderInfo prov =
1424                 mojo.createJUnitPlatformProviderInfo(junitPlatformArtifact, testClasspathWrapper);
1425 
1426         assertThat(prov.isApplicable()).isTrue();
1427 
1428         final Artifact surefireProvider = new DefaultArtifact(
1429                 "org.apache.maven.surefire", "surefire-junit-platform", surefireVersion, null, "jar", "", null);
1430 
1431         Artifact java5 = new DefaultArtifact(
1432                 "org.apache.maven.surefire", "common-java5", surefireVersion, null, "jar", "", null);
1433         Artifact launcher = new DefaultArtifact(
1434                 "org.junit.platform", "junit-platform-launcher", createFromVersion("1.4.0"), null, "jar", "", null);
1435         Artifact jupiterEngine = new DefaultArtifact(
1436                 "org.junit.jupiter",
1437                 "junit-jupiter-engine", ///// <------
1438                 createFromVersion("5.4.0"),
1439                 null,
1440                 "jar",
1441                 "",
1442                 null);
1443         Artifact platformEngine = new DefaultArtifact(
1444                 "org.junit.platform", "junit-platform-engine", createFromVersion("1.4.0"), null, "jar", "", null);
1445 
1446         Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
1447 
1448         assertThat(resolvedProviderArtifacts)
1449                 .hasSize(5)
1450                 .containsOnly(surefireProvider, java5, launcher, jupiterEngine, platformEngine);
1451 
1452         assertThat(testClasspathWrapper.getTestDependencies())
1453                 .hasSize(5)
1454                 .containsEntry("third.party:artifact", testClasspathSomeTestArtifact)
1455                 .containsEntry("org.junit.jupiter:junit-jupiter-api", testClasspathJupiterApi)
1456                 .containsEntry("org.apiguardian:apiguardian-api", testClasspathApiguardian)
1457                 .containsEntry("org.junit.platform:junit-platform-commons", testClasspathCommons)
1458                 .containsEntry("org.opentest4j:opentest4j", testClasspathOpentest4j);
1459     }
1460 
1461     @Test
1462     public void shouldSmartlyResolveJUnit5ProviderWithJupiterEngine() throws Exception {
1463         MavenProject mavenProject = new MavenProject();
1464         mavenProject.setArtifact(new DefaultArtifact(
1465                 "dummy", "pom", createFromVersion("1.0.0"), null, "jar", null, mock(ArtifactHandler.class)));
1466         mojo.setProject(mavenProject);
1467 
1468         final VersionRange surefireVersion = createFromVersion("1");
1469 
1470         final Artifact testClasspathSomeTestArtifact = new DefaultArtifact(
1471                 "third.party", "artifact", createFromVersion("1.0"), null, "jar", null, mock(ArtifactHandler.class));
1472 
1473         final Artifact testClasspathJupiterEngine = new DefaultArtifact(
1474                 "org.junit.jupiter",
1475                 "junit-jupiter-engine",
1476                 createFromVersion("5.4.0"),
1477                 null,
1478                 "jar",
1479                 null,
1480                 mock(ArtifactHandler.class));
1481 
1482         final Artifact testClasspathPlatformEngine = new DefaultArtifact(
1483                 "org.junit.platform",
1484                 "junit-platform-engine",
1485                 createFromVersion("1.4.0"),
1486                 null,
1487                 "jar",
1488                 null,
1489                 mock(ArtifactHandler.class));
1490 
1491         final Artifact testClasspathJupiterApi = new DefaultArtifact(
1492                 "org.junit.jupiter",
1493                 "junit-jupiter-api",
1494                 createFromVersion("5.4.0"),
1495                 null,
1496                 "jar",
1497                 null,
1498                 mock(ArtifactHandler.class));
1499 
1500         final Artifact testClasspathApiguardian = new DefaultArtifact(
1501                 "org.apiguardian",
1502                 "apiguardian-api",
1503                 createFromVersion("1.0.0"),
1504                 null,
1505                 "jar",
1506                 null,
1507                 mock(ArtifactHandler.class));
1508 
1509         final Artifact testClasspathCommons = new DefaultArtifact(
1510                 "org.junit.platform",
1511                 "junit-platform-commons",
1512                 createFromVersion("1.4.0"),
1513                 null,
1514                 "jar",
1515                 null,
1516                 mock(ArtifactHandler.class));
1517 
1518         final Artifact testClasspathOpentest4j = new DefaultArtifact(
1519                 "org.opentest4j",
1520                 "opentest4j",
1521                 createFromVersion("1.1.1"),
1522                 null,
1523                 "jar",
1524                 null,
1525                 mock(ArtifactHandler.class));
1526 
1527         Collection<Artifact> testArtifacts = asList(
1528                 testClasspathSomeTestArtifact,
1529                 testClasspathJupiterEngine,
1530                 testClasspathPlatformEngine,
1531                 testClasspathJupiterApi,
1532                 testClasspathApiguardian,
1533                 testClasspathCommons,
1534                 testClasspathOpentest4j);
1535 
1536         setProjectDepedenciesToMojo(testArtifacts.toArray(new Artifact[0]));
1537 
1538         File classesDirectory = new File("target/classes");
1539 
1540         File testClassesDirectory = new File("target/test-classes");
1541 
1542         TestClassPath testClasspathWrapper =
1543                 new TestClassPath(testArtifacts, classesDirectory, testClassesDirectory, null);
1544 
1545         SurefireDependencyResolver dependencyResolver = mock(SurefireDependencyResolver.class);
1546         mojo.setSurefireDependencyResolver(dependencyResolver);
1547 
1548         when(dependencyResolver.getProviderClasspathAsMap(any(), any(), anyString(), anyString()))
1549                 .thenReturn(artifactMapByVersionlessId(createSurefireProviderResolutionResult(surefireVersion)));
1550 
1551         when(dependencyResolver.resolveArtifacts(any(), any(), any(Artifact.class)))
1552                 .thenReturn(createExpectedJUnitPlatformLauncherResolutionResult());
1553 
1554         mojo.setLogger(mock(Logger.class));
1555 
1556         Artifact junitPlatformArtifact = invokeMethod(mojo, "getJUnit5Artifact");
1557         assertThat(junitPlatformArtifact.getGroupId()).isEqualTo("org.junit.platform");
1558         assertThat(junitPlatformArtifact.getArtifactId()).isEqualTo("junit-platform-commons");
1559         assertThat(junitPlatformArtifact.getVersion()).isEqualTo("1.4.0");
1560 
1561         AbstractSurefireMojo.JUnitPlatformProviderInfo prov =
1562                 mojo.createJUnitPlatformProviderInfo(junitPlatformArtifact, testClasspathWrapper);
1563 
1564         assertThat(prov.isApplicable()).isTrue();
1565 
1566         Artifact surefireProvider = new DefaultArtifact(
1567                 "org.apache.maven.surefire", "surefire-junit-platform", surefireVersion, null, "jar", "", null);
1568         Artifact java5 = new DefaultArtifact(
1569                 "org.apache.maven.surefire", "common-java5", surefireVersion, null, "jar", "", null);
1570         Artifact launcher = new DefaultArtifact(
1571                 "org.junit.platform", "junit-platform-launcher", createFromVersion("1.4.0"), null, "jar", "", null);
1572 
1573         Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
1574 
1575         assertThat(resolvedProviderArtifacts).hasSize(3).containsOnly(surefireProvider, java5, launcher);
1576 
1577         assertThat(testClasspathWrapper.getTestDependencies())
1578                 .hasSize(7)
1579                 .containsEntry("third.party:artifact", testClasspathSomeTestArtifact)
1580                 .containsEntry("org.junit.jupiter:junit-jupiter-engine", testClasspathJupiterEngine)
1581                 .containsEntry("org.junit.platform:junit-platform-engine", testClasspathPlatformEngine)
1582                 .containsEntry("org.junit.jupiter:junit-jupiter-api", testClasspathJupiterApi)
1583                 .containsEntry("org.apiguardian:apiguardian-api", testClasspathApiguardian)
1584                 .containsEntry("org.junit.platform:junit-platform-commons", testClasspathCommons)
1585                 .containsEntry("org.opentest4j:opentest4j", testClasspathOpentest4j);
1586     }
1587 
1588     @Test
1589     public void shouldSmartlyResolveJUnit5ProviderWithJupiterEngineInPluginDependencies() throws Exception {
1590         final VersionRange surefireVersion = createFromVersion("1");
1591 
1592         final Artifact plugin = new DefaultArtifact(
1593                 "org.apache.maven.surefire",
1594                 "maven-surefire-plugin",
1595                 surefireVersion,
1596                 null,
1597                 "jar",
1598                 null,
1599                 mock(ArtifactHandler.class));
1600 
1601         final Artifact forkedBooter = new DefaultArtifact(
1602                 "org.apache.maven.surefire",
1603                 "surefire-booter",
1604                 surefireVersion,
1605                 null,
1606                 "jar",
1607                 null,
1608                 mock(ArtifactHandler.class));
1609 
1610         final Artifact pluginDepJupiterEngine = new DefaultArtifact(
1611                 "org.junit.jupiter", "junit-jupiter-engine", createFromVersion("5.4.0"), null, "jar", "", null);
1612 
1613         final Artifact pluginDepPlatformEngine = new DefaultArtifact(
1614                 "org.junit.platform",
1615                 "junit-platform-engine",
1616                 createFromVersion("1.4.0"),
1617                 null,
1618                 "jar",
1619                 null,
1620                 mock(ArtifactHandler.class));
1621 
1622         final Artifact pluginDepJupiterApi = new DefaultArtifact(
1623                 "org.junit.jupiter",
1624                 "junit-jupiter-api",
1625                 createFromVersion("5.4.0"),
1626                 null,
1627                 "jar",
1628                 null,
1629                 mock(ArtifactHandler.class));
1630 
1631         final Artifact pluginDepApiguardian = new DefaultArtifact(
1632                 "org.apiguardian",
1633                 "apiguardian-api",
1634                 createFromVersion("1.0.0"),
1635                 null,
1636                 "jar",
1637                 null,
1638                 mock(ArtifactHandler.class));
1639 
1640         final Artifact pluginDepCommons = new DefaultArtifact(
1641                 "org.junit.platform",
1642                 "junit-platform-commons",
1643                 createFromVersion("1.4.0"),
1644                 null,
1645                 "jar",
1646                 null,
1647                 mock(ArtifactHandler.class));
1648 
1649         final Artifact pluginDepOpentest4j = new DefaultArtifact(
1650                 "org.opentest4j",
1651                 "opentest4j",
1652                 createFromVersion("1.1.1"),
1653                 null,
1654                 "jar",
1655                 null,
1656                 mock(ArtifactHandler.class));
1657 
1658         addPluginDependencies(
1659                 plugin,
1660                 forkedBooter,
1661                 pluginDepJupiterEngine,
1662                 pluginDepPlatformEngine,
1663                 pluginDepJupiterApi,
1664                 pluginDepApiguardian,
1665                 pluginDepCommons,
1666                 pluginDepOpentest4j);
1667 
1668         MavenProject mavenProject = new MavenProject();
1669         mavenProject.setArtifact(new DefaultArtifact(
1670                 "dummy", "pom", createFromVersion("1.0.0"), null, "jar", null, mock(ArtifactHandler.class)));
1671         mojo.setProject(mavenProject);
1672 
1673         final Artifact testClasspathSomeTestArtifact = new DefaultArtifact(
1674                 "third.party", "artifact", createFromVersion("1.0"), null, "jar", null, mock(ArtifactHandler.class));
1675 
1676         final Artifact testClasspathJupiterApi = new DefaultArtifact(
1677                 "org.junit.jupiter",
1678                 "junit-jupiter-api",
1679                 createFromVersion("5.3.0"),
1680                 null,
1681                 "jar",
1682                 null,
1683                 mock(ArtifactHandler.class));
1684 
1685         final Artifact testClasspathApiguardian = new DefaultArtifact(
1686                 "org.apiguardian",
1687                 "apiguardian-api",
1688                 createFromVersion("1.0.0"),
1689                 null,
1690                 "jar",
1691                 null,
1692                 mock(ArtifactHandler.class));
1693 
1694         final Artifact testClasspathCommons = new DefaultArtifact(
1695                 "org.junit.platform",
1696                 "junit-platform-commons",
1697                 createFromVersion("1.4.0"),
1698                 null,
1699                 "jar",
1700                 null,
1701                 mock(ArtifactHandler.class));
1702 
1703         final Artifact testClasspathOpentest4j = new DefaultArtifact(
1704                 "org.opentest4j",
1705                 "opentest4j",
1706                 createFromVersion("1.1.1"),
1707                 null,
1708                 "jar",
1709                 null,
1710                 mock(ArtifactHandler.class));
1711 
1712         Collection<Artifact> testArtifacts = asList(
1713                 testClasspathSomeTestArtifact,
1714                 testClasspathJupiterApi,
1715                 testClasspathApiguardian,
1716                 testClasspathCommons,
1717                 testClasspathOpentest4j);
1718 
1719         setProjectDepedenciesToMojo(testArtifacts.toArray(new Artifact[0]));
1720 
1721         File classesDirectory = new File("target/classes");
1722 
1723         File testClassesDirectory = new File("target/test-classes");
1724 
1725         TestClassPath testClasspathWrapper =
1726                 new TestClassPath(testArtifacts, classesDirectory, testClassesDirectory, null);
1727 
1728         SurefireDependencyResolver dependencyResolver = mock(SurefireDependencyResolver.class);
1729         mojo.setSurefireDependencyResolver(dependencyResolver);
1730 
1731         when(dependencyResolver.getProviderClasspathAsMap(any(), any(), anyString(), anyString()))
1732                 .thenReturn(artifactMapByVersionlessId(createSurefireProviderResolutionResult(surefireVersion)));
1733 
1734         when(dependencyResolver.resolveArtifacts(any(), any(), any(Artifact.class)))
1735                 .thenReturn(createExpectedJUnitPlatformLauncherResolutionResult());
1736 
1737         mojo.setLogger(mock(Logger.class));
1738 
1739         Set<Artifact> pluginDepJupiterEngineArtifacts = new HashSet<>();
1740         pluginDepJupiterEngineArtifacts.add(pluginDepJupiterEngine);
1741         pluginDepJupiterEngineArtifacts.add(pluginDepPlatformEngine);
1742         pluginDepJupiterEngineArtifacts.add(pluginDepJupiterApi);
1743         pluginDepJupiterEngineArtifacts.add(pluginDepApiguardian);
1744         pluginDepJupiterEngineArtifacts.add(pluginDepCommons);
1745         pluginDepJupiterEngineArtifacts.add(pluginDepOpentest4j);
1746 
1747         when(dependencyResolver.resolvePluginDependencies(any(), any(), any(), any()))
1748                 .thenReturn(artifactMapByVersionlessId(pluginDepJupiterEngineArtifacts));
1749 
1750         Artifact junitPlatformArtifact = invokeMethod(mojo, "getJUnit5Artifact");
1751         assertThat(junitPlatformArtifact.getGroupId()).isEqualTo("org.junit.platform");
1752         assertThat(junitPlatformArtifact.getArtifactId()).isEqualTo("junit-platform-engine");
1753         assertThat(junitPlatformArtifact.getVersion()).isEqualTo("1.4.0");
1754 
1755         PluginDescriptor pluginDescriptor = mock(PluginDescriptor.class);
1756         mojo.setPluginDescriptor(pluginDescriptor);
1757         Plugin p = mock(Plugin.class);
1758         when(pluginDescriptor.getPlugin()).thenReturn(p);
1759         List<Dependency> directPluginDependencies = toDependencies(pluginDepJupiterEngine);
1760         when(p.getDependencies()).thenReturn(directPluginDependencies);
1761 
1762         AbstractSurefireMojo.JUnitPlatformProviderInfo prov =
1763                 mojo.createJUnitPlatformProviderInfo(junitPlatformArtifact, testClasspathWrapper);
1764 
1765         assertThat(prov.isApplicable()).isTrue();
1766 
1767         Artifact surefireProvider = new DefaultArtifact(
1768                 "org.apache.maven.surefire", "surefire-junit-platform", surefireVersion, null, "jar", "", null);
1769         Artifact java5 = new DefaultArtifact(
1770                 "org.apache.maven.surefire", "common-java5", surefireVersion, null, "jar", "", null);
1771         Artifact launcher = new DefaultArtifact(
1772                 "org.junit.platform", "junit-platform-launcher", createFromVersion("1.4.0"), null, "jar", "", null);
1773         Artifact jupiterEngine = new DefaultArtifact(
1774                 "org.junit.jupiter", "junit-jupiter-engine", createFromVersion("5.4.0"), null, "jar", "", null);
1775         Artifact platformEngine = new DefaultArtifact(
1776                 "org.junit.platform", "junit-platform-engine", createFromVersion("1.4.0"), null, "jar", "", null);
1777 
1778         Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
1779 
1780         assertThat(resolvedProviderArtifacts)
1781                 .hasSize(5)
1782                 .containsOnly(surefireProvider, java5, launcher, jupiterEngine, platformEngine);
1783 
1784         assertThat(testClasspathWrapper.getTestDependencies())
1785                 .hasSize(5)
1786                 .containsEntry("third.party:artifact", testClasspathSomeTestArtifact)
1787                 .containsEntry("org.junit.jupiter:junit-jupiter-api", testClasspathJupiterApi)
1788                 .containsEntry("org.apiguardian:apiguardian-api", testClasspathApiguardian)
1789                 .containsEntry("org.junit.platform:junit-platform-commons", testClasspathCommons)
1790                 .containsEntry("org.opentest4j:opentest4j", testClasspathOpentest4j);
1791     }
1792 
1793     @Test
1794     public void shouldConvertJunitEngineParameters() throws Exception {
1795         Properties properties = new Properties();
1796         setInternalState(mojo, "properties", properties);
1797 
1798         invokeMethod(mojo, "convertJunitEngineParameters");
1799         assertThat(properties).isEmpty();
1800 
1801         mojo.setIncludeJUnit5Engines(new String[0]);
1802         mojo.setExcludeJUnit5Engines(new String[0]);
1803         invokeMethod(mojo, "convertJunitEngineParameters");
1804         assertThat(properties).isEmpty();
1805 
1806         mojo.setIncludeJUnit5Engines(new String[] {"e1", "e2"});
1807         invokeMethod(mojo, "convertJunitEngineParameters");
1808         assertThat(properties).containsEntry("includejunit5engines", "e1,e2");
1809 
1810         mojo.setExcludeJUnit5Engines(new String[] {"e1", "e2"});
1811         invokeMethod(mojo, "convertJunitEngineParameters");
1812         assertThat(properties).containsEntry("excludejunit5engines", "e1,e2");
1813     }
1814 
1815     private static Set<Artifact> createJUnitPlatformLauncherResolutionResult(
1816             Artifact junit5Engine, Artifact apiguardian, Artifact commons, Artifact opentest4j) {
1817         Set<Artifact> resolvedLauncherArtifacts = new HashSet<>();
1818         Artifact launcher = new DefaultArtifact(
1819                 "org.junit.platform", "junit-platform-launcher", commons.getVersionRange(), null, "jar", "", null);
1820         resolvedLauncherArtifacts.add(launcher);
1821         resolvedLauncherArtifacts.add(apiguardian);
1822         resolvedLauncherArtifacts.add(junit5Engine);
1823         resolvedLauncherArtifacts.add(commons);
1824         resolvedLauncherArtifacts.add(opentest4j);
1825         resolvedLauncherArtifacts.remove(null);
1826         return resolvedLauncherArtifacts;
1827     }
1828 
1829     private static Set<Artifact> createJupiterEngineResolutionResult() {
1830         Set<Artifact> resolvedLauncherArtifacts = new HashSet<>();
1831         resolvedLauncherArtifacts.add(new DefaultArtifact(
1832                 "org.junit.jupiter", "junit-jupiter-engine", createFromVersion("5.4.0"), null, "jar", "", null));
1833         resolvedLauncherArtifacts.add(new DefaultArtifact(
1834                 "org.junit.jupiter", "junit-jupiter-api", createFromVersion("5.4.0"), null, "jar", "", null));
1835         resolvedLauncherArtifacts.add(new DefaultArtifact(
1836                 "org.junit.platform", "junit-platform-engine", createFromVersion("1.4.0"), null, "jar", "", null));
1837         resolvedLauncherArtifacts.add(new DefaultArtifact(
1838                 "org.apiguardian", "apiguardian-api", createFromVersion("1.0.0"), null, "jar", "", null));
1839         resolvedLauncherArtifacts.add(
1840                 new DefaultArtifact("org.opentest4j", "opentest4j", createFromVersion("1.1.1"), null, "jar", "", null));
1841         resolvedLauncherArtifacts.add(new DefaultArtifact(
1842                 "org.junit.platform", "junit-platform-commons", createFromVersion("1.4.0"), null, "jar", "", null));
1843         return resolvedLauncherArtifacts;
1844     }
1845 
1846     private static Set<Artifact> createExpectedJUnitPlatformLauncherResolutionResult() {
1847         Artifact engine = new DefaultArtifact(
1848                 "org.junit.platform", "junit-platform-engine", createFromVersion("1.4.0"), null, "jar", "", null);
1849         Artifact commons = new DefaultArtifact(
1850                 "org.junit.platform", "junit-platform-commons", createFromVersion("1.4.0"), null, "jar", "", null);
1851         Artifact apiguardian = new DefaultArtifact(
1852                 "org.apiguardian", "apiguardian-api", createFromVersion("1.0.0"), null, "jar", "", null);
1853         Artifact opentest4j =
1854                 new DefaultArtifact("org.opentest4j", "opentest4j", createFromVersion("1.1.1"), null, "jar", "", null);
1855         return createJUnitPlatformLauncherResolutionResult(engine, apiguardian, commons, opentest4j);
1856     }
1857 
1858     private static Set<Artifact> createSurefireProviderResolutionResult(VersionRange surefireVersion) {
1859 
1860         Artifact provider = new DefaultArtifact(
1861                 "org.apache.maven.surefire", "surefire-junit-platform", surefireVersion, null, "jar", "", null);
1862         Artifact java5 = new DefaultArtifact(
1863                 "org.apache.maven.surefire", "common-java5", surefireVersion, null, "jar", "", null);
1864         Artifact launcher = new DefaultArtifact(
1865                 "org.junit.platform", "junit-platform-launcher", createFromVersion("1.3.2"), null, "jar", "", null);
1866         Artifact apiguardian = new DefaultArtifact(
1867                 "org.apiguardian", "apiguardian-api", createFromVersion("1.0.0"), null, "jar", "", null);
1868         Artifact engine = new DefaultArtifact(
1869                 "org.junit.platform", "junit-platform-engine", createFromVersion("1.3.2"), null, "jar", "", null);
1870         Artifact commons = new DefaultArtifact(
1871                 "org.junit.platform", "junit-platform-commons", createFromVersion("1.3.2"), null, "jar", "", null);
1872         Artifact opentest4j =
1873                 new DefaultArtifact("org.opentest4j", "opentest4j", createFromVersion("1.1.1"), null, "jar", "", null);
1874 
1875         Set<Artifact> providerArtifacts = new HashSet<>();
1876         providerArtifacts.add(provider);
1877         providerArtifacts.add(java5);
1878         providerArtifacts.add(launcher);
1879         providerArtifacts.add(apiguardian);
1880         providerArtifacts.add(engine);
1881         providerArtifacts.add(commons);
1882         providerArtifacts.add(opentest4j);
1883 
1884         return providerArtifacts;
1885     }
1886 
1887     @Test
1888     public void shouldVerifyConfigParameters() throws Exception {
1889 
1890         Mojo mojo = new Mojo() {
1891             @Override
1892             public File getTestClassesDirectory() {
1893                 return new File(System.getProperty("user.dir"), "target/test-classes");
1894             }
1895 
1896             @Override
1897             protected String getEnableProcessChecker() {
1898                 return "fake";
1899             }
1900         };
1901 
1902         MojoFailureException m = assertThrows(MojoFailureException.class, mojo::verifyParameters);
1903         assertThat(m.getMessage())
1904                 .isEqualTo("Unexpected value 'fake' in the configuration parameter 'enableProcessChecker'.");
1905     }
1906 
1907     private void setProjectDepedenciesToMojo(Artifact... deps) {
1908         for (Artifact dep : deps) {
1909             mojo.getProjectArtifactMap().put(dep.getGroupId() + ":" + dep.getArtifactId(), dep);
1910         }
1911     }
1912 
1913     private void addPluginDependencies(Artifact... deps) {
1914         for (Artifact dep : deps) {
1915             mojo.getPluginArtifactMap().put(dep.getGroupId() + ":" + dep.getArtifactId(), dep);
1916         }
1917     }
1918 
1919     /**
1920      *
1921      */
1922     public static class Mojo extends AbstractSurefireMojo implements SurefireReportParameters {
1923         private File mainBuildPath;
1924 
1925         private File testClassesDirectory;
1926 
1927         private boolean useModulePath;
1928 
1929         private int failOnFlakeCount;
1930 
1931         private String[] includeJUnit5Engines;
1932 
1933         private String[] excludeJUnit5Engines;
1934 
1935         private List<Artifact> projectTestArtifacts;
1936 
1937         private File includesFile;
1938 
1939         private File excludesFile;
1940 
1941         private List<String> includes;
1942 
1943         private List<String> excludes;
1944 
1945         private String test;
1946 
1947         private boolean testFailureIgnore;
1948 
1949         private JUnitPlatformProviderInfo createJUnitPlatformProviderInfo(
1950                 Artifact junitPlatformArtifact, TestClassPath testClasspathWrapper) {
1951             return new JUnitPlatformProviderInfo(
1952                     null,
1953                     junitPlatformArtifact,
1954                     testClasspathWrapper,
1955                     null,
1956                     getBooterArtifact(),
1957                     getSurefireDependencyResolver(),
1958                     mock(MavenSession.class),
1959                     mock(MavenProject.class),
1960                     getPluginDescriptor(),
1961                     getPluginArtifactMap(),
1962                     getConsoleLogger(),
1963                     null);
1964         }
1965 
1966         void setProjectTestArtifacts(List<Artifact> projectTestArtifacts) {
1967             this.projectTestArtifacts = projectTestArtifacts;
1968         }
1969 
1970         @Override
1971         List<Artifact> getProjectTestArtifacts() {
1972             return projectTestArtifacts;
1973         }
1974 
1975         @Override
1976         protected void logDebugOrCliShowErrors(String s) {
1977             // do nothing
1978         }
1979 
1980         @Override
1981         protected String getPluginName() {
1982             return null;
1983         }
1984 
1985         @Override
1986         protected int getRerunFailingTestsCount() {
1987             return 0;
1988         }
1989 
1990         @Override
1991         public boolean isSkipTests() {
1992             return false;
1993         }
1994 
1995         @Override
1996         public void setSkipTests(boolean skipTests) {}
1997 
1998         @Override
1999         public boolean isSkipExec() {
2000             return false;
2001         }
2002 
2003         @Override
2004         public void setSkipExec(boolean skipExec) {}
2005 
2006         @Override
2007         public boolean isSkip() {
2008             return false;
2009         }
2010 
2011         @Override
2012         public void setSkip(boolean skip) {}
2013 
2014         @Override
2015         public boolean isTestFailureIgnore() {
2016             return testFailureIgnore;
2017         }
2018 
2019         @Override
2020         public void setTestFailureIgnore(boolean testFailureIgnore) {
2021             this.testFailureIgnore = testFailureIgnore;
2022         }
2023 
2024         @Override
2025         public File getBasedir() {
2026             return null;
2027         }
2028 
2029         @Override
2030         public void setBasedir(File basedir) {}
2031 
2032         @Override
2033         public File getTestClassesDirectory() {
2034             return testClassesDirectory;
2035         }
2036 
2037         @Override
2038         public void setTestClassesDirectory(File testClassesDirectory) {
2039             this.testClassesDirectory = testClassesDirectory;
2040         }
2041 
2042         @Override
2043         public File getMainBuildPath() {
2044             return mainBuildPath;
2045         }
2046 
2047         @Override
2048         public void setMainBuildPath(File mainBuildPath) {
2049             this.mainBuildPath = mainBuildPath;
2050         }
2051 
2052         @Override
2053         public File getReportsDirectory() {
2054             return null;
2055         }
2056 
2057         @Override
2058         public void setReportsDirectory(File reportsDirectory) {}
2059 
2060         @Override
2061         public String getTest() {
2062             return test;
2063         }
2064 
2065         @Override
2066         public void setTest(String test) {
2067             this.test = test;
2068         }
2069 
2070         @Override
2071         public List<String> getIncludes() {
2072             return includes;
2073         }
2074 
2075         @Override
2076         public void setIncludes(List<String> includes) {
2077             this.includes = includes;
2078         }
2079 
2080         void setIncludesFile(File includesFile) {
2081             this.includesFile = includesFile;
2082         }
2083 
2084         @Override
2085         public File getIncludesFile() {
2086             return includesFile;
2087         }
2088 
2089         @Override
2090         public List<String> getExcludes() {
2091             return excludes;
2092         }
2093 
2094         @Override
2095         public void setExcludes(List<String> excludes) {
2096             this.excludes = excludes;
2097         }
2098 
2099         @Override
2100         public boolean isPrintSummary() {
2101             return false;
2102         }
2103 
2104         @Override
2105         public void setPrintSummary(boolean printSummary) {}
2106 
2107         @Override
2108         public String getReportFormat() {
2109             return null;
2110         }
2111 
2112         @Override
2113         public void setReportFormat(String reportFormat) {}
2114 
2115         @Override
2116         public boolean isUseFile() {
2117             return false;
2118         }
2119 
2120         @Override
2121         public void setUseFile(boolean useFile) {}
2122 
2123         @Override
2124         public String getDebugForkedProcess() {
2125             return null;
2126         }
2127 
2128         @Override
2129         public void setDebugForkedProcess(String debugForkedProcess) {}
2130 
2131         @Override
2132         public int getForkedProcessTimeoutInSeconds() {
2133             return 0;
2134         }
2135 
2136         @Override
2137         public void setForkedProcessTimeoutInSeconds(int forkedProcessTimeoutInSeconds) {}
2138 
2139         @Override
2140         public int getForkedProcessExitTimeoutInSeconds() {
2141             return 0;
2142         }
2143 
2144         @Override
2145         public void setForkedProcessExitTimeoutInSeconds(int forkedProcessTerminationTimeoutInSeconds) {}
2146 
2147         @Override
2148         public double getParallelTestsTimeoutInSeconds() {
2149             return 0;
2150         }
2151 
2152         @Override
2153         public void setParallelTestsTimeoutInSeconds(double parallelTestsTimeoutInSeconds) {}
2154 
2155         @Override
2156         public double getParallelTestsTimeoutForcedInSeconds() {
2157             return 0;
2158         }
2159 
2160         @Override
2161         public void setParallelTestsTimeoutForcedInSeconds(double parallelTestsTimeoutForcedInSeconds) {}
2162 
2163         @Override
2164         public boolean isUseSystemClassLoader() {
2165             return false;
2166         }
2167 
2168         @Override
2169         public void setUseSystemClassLoader(boolean useSystemClassLoader) {}
2170 
2171         @Override
2172         public boolean isUseManifestOnlyJar() {
2173             return false;
2174         }
2175 
2176         @Override
2177         public void setUseManifestOnlyJar(boolean useManifestOnlyJar) {}
2178 
2179         @Override
2180         public String getEncoding() {
2181             return null;
2182         }
2183 
2184         @Override
2185         public void setEncoding(String encoding) {}
2186 
2187         @Override
2188         public boolean getFailIfNoSpecifiedTests() {
2189             return false;
2190         }
2191 
2192         @Override
2193         public void setFailIfNoSpecifiedTests(boolean failIfNoSpecifiedTests) {}
2194 
2195         @Override
2196         public int getSkipAfterFailureCount() {
2197             return 0;
2198         }
2199 
2200         @Override
2201         public String getShutdown() {
2202             return null;
2203         }
2204 
2205         void setExcludesFile(File excludesFile) {
2206             this.excludesFile = excludesFile;
2207         }
2208 
2209         @Override
2210         public File getExcludesFile() {
2211             return excludesFile;
2212         }
2213 
2214         @Override
2215         protected String[] getExcludedEnvironmentVariables() {
2216             return new String[0];
2217         }
2218 
2219         @Override
2220         public String getRunOrder() {
2221             return null;
2222         }
2223 
2224         @Override
2225         public void setRunOrder(String runOrder) {}
2226 
2227         @Override
2228         public Long getRunOrderRandomSeed() {
2229             return null;
2230         }
2231 
2232         @Override
2233         public void setRunOrderRandomSeed(Long runOrderRandomSeed) {}
2234 
2235         @Override
2236         public String getRunOrderStatisticsFileChecksum() {
2237             return null;
2238         }
2239 
2240         @Override
2241         public void setRunOrderStatisticsFileChecksum(String runOrderStatisticsFileChecksum) {}
2242 
2243         @Override
2244         protected void handleSummary(RunResult summary, Exception firstForkException) {}
2245 
2246         @Override
2247         protected boolean isSkipExecution() {
2248             return false;
2249         }
2250 
2251         @Override
2252         protected String[] getDefaultIncludes() {
2253             return new String[0];
2254         }
2255 
2256         @Override
2257         protected String getReportSchemaLocation() {
2258             return null;
2259         }
2260 
2261         @Override
2262         protected boolean useModulePath() {
2263             return useModulePath;
2264         }
2265 
2266         @Override
2267         protected void setUseModulePath(boolean useModulePath) {
2268             this.useModulePath = useModulePath;
2269         }
2270 
2271         @Override
2272         protected String getEnableProcessChecker() {
2273             return null;
2274         }
2275 
2276         @Override
2277         protected ForkNodeFactory getForkNode() {
2278             return null;
2279         }
2280 
2281         @Override
2282         protected Artifact getMojoArtifact() {
2283             return new DefaultArtifact(
2284                     "org.apache.maven.surefire",
2285                     "maven-surefire-plugin",
2286                     createFromVersion("1"),
2287                     null,
2288                     "jar",
2289                     null,
2290                     mock(ArtifactHandler.class));
2291         }
2292 
2293         @Override
2294         public File getSystemPropertiesFile() {
2295             return null;
2296         }
2297 
2298         @Override
2299         public void setSystemPropertiesFile(File systemPropertiesFile) {}
2300 
2301         public void setToolchain(Toolchain toolchain) {
2302             setInternalState(this, "toolchain", toolchain);
2303         }
2304 
2305         public void setJvm(String jvm) {
2306             setInternalState(this, "jvm", jvm);
2307         }
2308 
2309         @Override
2310         public int getFailOnFlakeCount() {
2311             return failOnFlakeCount;
2312         }
2313 
2314         @Override
2315         public void setFailOnFlakeCount(int failOnFlakeCount) {
2316             this.failOnFlakeCount = failOnFlakeCount;
2317         }
2318 
2319         @Override
2320         public String[] getIncludeJUnit5Engines() {
2321             return includeJUnit5Engines;
2322         }
2323 
2324         @Override
2325         public void setIncludeJUnit5Engines(String[] includeJUnit5Engines) {
2326             this.includeJUnit5Engines = includeJUnit5Engines;
2327         }
2328 
2329         @Override
2330         public String[] getExcludeJUnit5Engines() {
2331             return excludeJUnit5Engines;
2332         }
2333 
2334         @Override
2335         public void setExcludeJUnit5Engines(String[] excludeJUnit5Engines) {
2336             this.excludeJUnit5Engines = excludeJUnit5Engines;
2337         }
2338     }
2339 
2340     @Test
2341     public void shouldNotPerformMethodFilteringOnIncludes() throws Exception {
2342         Mojo plugin = new Mojo();
2343 
2344         File includesExcludes = SureFireFileManager.createTempFile("surefire", "includes");
2345         FileUtils.write(includesExcludes, "AnotherTest#method", UTF_8);
2346         plugin.setIncludesFile(includesExcludes);
2347 
2348         List<String> includes = new LinkedList<>();
2349         includes.add("AnotherTest#method ");
2350         plugin.setIncludes(includes);
2351 
2352         VersionRange version = VersionRange.createFromVersion("1.0");
2353         ArtifactHandler handler = new DefaultArtifactHandler();
2354         Artifact testDeps = new DefaultArtifact("g", "a", version, "compile", "jar", null, handler);
2355         File artifactFile = SureFireFileManager.createTempFile("surefire", ".jar");
2356         artifactFile.deleteOnExit();
2357         testDeps.setFile(artifactFile);
2358         plugin.setProjectTestArtifacts(singletonList(testDeps));
2359         plugin.setDependenciesToScan(new String[] {"g:a"});
2360 
2361         Exception e = assertThrows(Exception.class, plugin::scanDependencies);
2362         assertThat(e.getMessage())
2363                 .isEqualTo("Method filter prohibited in includes|excludes parameter: AnotherTest#method ");
2364     }
2365 
2366     @Test
2367     public void shouldFilterTestsOnIncludesFile() throws Exception {
2368         Mojo plugin = new Mojo();
2369 
2370         plugin.setLogger(mock(Logger.class));
2371 
2372         File includes = SureFireFileManager.createTempFile("surefire", "includes");
2373         FileUtils.write(includes, "AnotherTest#method", UTF_8);
2374         plugin.setIncludesFile(includes);
2375 
2376         VersionRange version = VersionRange.createFromVersion("1.0");
2377         ArtifactHandler handler = new DefaultArtifactHandler();
2378         Artifact testDeps = new DefaultArtifact("g", "a", version, "compile", "test-jar", null, handler);
2379         File artifactFile = SureFireFileManager.createTempFile("surefire", "classes");
2380         String classDir = artifactFile.getCanonicalPath();
2381         assertThat(artifactFile.delete()).isTrue();
2382         File classes = new File(classDir);
2383         assertThat(classes.mkdir()).isTrue();
2384         testDeps.setFile(classes);
2385         assertThat(new File(classes, "AnotherTest.class").createNewFile()).isTrue();
2386         plugin.setProjectTestArtifacts(singletonList(testDeps));
2387         plugin.setDependenciesToScan(new String[] {"g:a"});
2388 
2389         DefaultScanResult result = plugin.scanDependencies();
2390         assertThat(result.getClasses()).hasSize(1);
2391         assertThat(result.getClasses().iterator().next()).isEqualTo("AnotherTest");
2392     }
2393 
2394     @Test
2395     public void shouldFilterTestsOnExcludesFile() throws Exception {
2396         Mojo plugin = new Mojo();
2397 
2398         plugin.setLogger(mock(Logger.class));
2399 
2400         File excludes = SureFireFileManager.createTempFile("surefire", "-excludes");
2401         FileUtils.write(excludes, "AnotherTest", UTF_8);
2402         plugin.setExcludesFile(excludes);
2403 
2404         VersionRange version = VersionRange.createFromVersion("1.0");
2405         ArtifactHandler handler = new DefaultArtifactHandler();
2406         Artifact testDeps = new DefaultArtifact("g", "a", version, "compile", "test-jar", null, handler);
2407         File artifactFile = SureFireFileManager.createTempFile("surefire", "-classes");
2408         String classDir = artifactFile.getCanonicalPath();
2409         assertThat(artifactFile.delete()).isTrue();
2410         File classes = new File(classDir);
2411         assertThat(classes.mkdir()).isTrue();
2412         testDeps.setFile(classes);
2413         assertThat(new File(classes, "AnotherTest.class").createNewFile()).isTrue();
2414         plugin.setProjectTestArtifacts(singletonList(testDeps));
2415         plugin.setDependenciesToScan(new String[] {"g:a"});
2416 
2417         DefaultScanResult result = plugin.scanDependencies();
2418         assertThat(result.getClasses()).isEmpty();
2419     }
2420 
2421     @Test
2422     public void shouldFilterTestsOnExcludes() throws Exception {
2423         Mojo plugin = new Mojo();
2424 
2425         plugin.setLogger(mock(Logger.class));
2426 
2427         plugin.setExcludes(singletonList("AnotherTest"));
2428 
2429         VersionRange version = VersionRange.createFromVersion("1.0");
2430         ArtifactHandler handler = new DefaultArtifactHandler();
2431         Artifact testDeps = new DefaultArtifact("g", "a", version, "compile", "jar", null, handler);
2432         File artifactFile = SureFireFileManager.createTempFile("surefire", "-classes");
2433         String classDir = artifactFile.getCanonicalPath();
2434         assertThat(artifactFile.delete()).isTrue();
2435         File classes = new File(classDir);
2436         assertThat(classes.mkdir()).isTrue();
2437         testDeps.setFile(classes);
2438         assertThat(new File(classes, "AnotherTest.class").createNewFile()).isTrue();
2439         plugin.setProjectTestArtifacts(singletonList(testDeps));
2440         plugin.setDependenciesToScan(new String[] {"g:a"});
2441 
2442         DefaultScanResult result = plugin.scanDependencies();
2443         assertThat(result.getClasses()).isEmpty();
2444     }
2445 
2446     @Test
2447     public void shouldUseOnlySpecificTests() throws Exception {
2448         Mojo plugin = new Mojo();
2449 
2450         plugin.setLogger(mock(Logger.class));
2451 
2452         File includes = SureFireFileManager.createTempFile("surefire", "-includes");
2453         FileUtils.write(includes, "AnotherTest", UTF_8);
2454         plugin.setIncludesFile(includes);
2455         plugin.setTest("DifferentTest");
2456 
2457         VersionRange version = VersionRange.createFromVersion("1.0");
2458         ArtifactHandler handler = new DefaultArtifactHandler();
2459         Artifact testDeps = new DefaultArtifact("g", "a", version, "compile", "test-jar", null, handler);
2460         File artifactFile = SureFireFileManager.createTempFile("surefire", "-classes");
2461         String classDir = artifactFile.getCanonicalPath();
2462         assertThat(artifactFile.delete()).isTrue();
2463         File classes = new File(classDir);
2464         assertThat(classes.mkdir()).isTrue();
2465         testDeps.setFile(classes);
2466         assertThat(new File(classes, "AnotherTest.class").createNewFile()).isTrue();
2467         plugin.setProjectTestArtifacts(singletonList(testDeps));
2468         plugin.setDependenciesToScan(new String[] {"g:a"});
2469 
2470         DefaultScanResult result = plugin.scanDependencies();
2471         assertThat(result.getClasses()).isEmpty();
2472     }
2473 
2474     @Test
2475     public void testSetupProperties() {
2476         Mojo plugin = new Mojo() {
2477 
2478             @Override
2479             Properties getUserProperties() {
2480                 Properties properties = new Properties();
2481                 properties.put("userProperties1", "source4");
2482                 return properties;
2483             }
2484 
2485             @Override
2486             public File getBasedir() {
2487                 return new File("target");
2488             }
2489 
2490             @Override
2491             public String getLocalRepositoryPath() {
2492                 return "local/repository/path";
2493             }
2494 
2495             @Override
2496             public File getSystemPropertiesFile() {
2497                 Properties systemProperties = new Properties();
2498                 systemProperties.put("systemProperties2", "source2");
2499                 systemProperties.put("systemProperties3", "source2");
2500                 systemProperties.put("userProperties1", "source2");
2501                 try {
2502                     File propertiesFile = tempFolder.newFile();
2503                     try (OutputStream outputStream = Files.newOutputStream(propertiesFile.toPath())) {
2504                         systemProperties.store(outputStream, "comments");
2505                     }
2506                     return propertiesFile;
2507                 } catch (IOException e) {
2508                     throw new UncheckedIOException(e);
2509                 }
2510             }
2511         };
2512 
2513         plugin.setLogger(mock(Logger.class));
2514         /* expected order of precedence:
2515          * 1. systemProperties
2516          * 2. getSystemPropertiesFile()
2517          * 3. systemPropertyVariables
2518          * 4. getUserProperties()
2519          */
2520         plugin.forkCount = "1";
2521         plugin.promoteUserPropertiesToSystemProperties = true;
2522         Properties systemProperties = new Properties();
2523         systemProperties.put("systemProperties1", "source1");
2524         systemProperties.put("systemProperties2", "source1");
2525         systemProperties.put("systemProperties3", "source1");
2526         systemProperties.put("userProperties1", "source1");
2527         plugin.systemProperties = systemProperties;
2528         Map<String, String> systemPropertyVariables = new HashMap<>();
2529         systemPropertyVariables.put("systemProperties3", "source3");
2530         systemPropertyVariables.put("userProperties1", "source3");
2531         plugin.systemPropertyVariables = systemPropertyVariables;
2532         SurefireProperties properties = plugin.setupProperties();
2533         assertThat(properties)
2534                 .containsOnly(
2535                         Assertions.entry("systemProperties1", "source1"),
2536                         Assertions.entry("systemProperties2", "source2"),
2537                         Assertions.entry("systemProperties3", "source3"),
2538                         Assertions.entry("userProperties1", "source4"),
2539                         Assertions.entry("localRepository", "local/repository/path"),
2540                         Assertions.entry("basedir", new File("target").getAbsolutePath()));
2541 
2542         // and without user properties
2543         plugin.promoteUserPropertiesToSystemProperties = false;
2544         properties = plugin.setupProperties();
2545         assertThat(properties)
2546                 .containsOnly(
2547                         Assertions.entry("systemProperties1", "source1"),
2548                         Assertions.entry("systemProperties2", "source2"),
2549                         Assertions.entry("systemProperties3", "source3"),
2550                         Assertions.entry("userProperties1", "source3"),
2551                         Assertions.entry("localRepository", "local/repository/path"),
2552                         Assertions.entry("basedir", new File("target").getAbsolutePath()));
2553     }
2554 
2555     private static File mockFile(String absolutePath) {
2556         File f = mock(File.class);
2557         when(f.getAbsolutePath()).thenReturn(absolutePath);
2558         return f;
2559     }
2560 
2561     private static Dependency toDependency(Artifact artifact) {
2562         Dependency dependency = new Dependency();
2563         dependency.setGroupId(artifact.getGroupId());
2564         dependency.setArtifactId(artifact.getArtifactId());
2565         dependency.setVersion(artifact.getBaseVersion());
2566         dependency.setType("jar");
2567         return dependency;
2568     }
2569 
2570     private static List<Dependency> toDependencies(Artifact... artifacts) {
2571         List<Dependency> dependencies = new ArrayList<>();
2572         for (Artifact artifact : artifacts) {
2573             dependencies.add(toDependency(artifact));
2574         }
2575         return dependencies;
2576     }
2577 }