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