1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin.surefire;
20
21 import java.io.File;
22 import java.nio.file.Path;
23 import java.nio.file.Paths;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.maven.execution.MavenSession;
29 import org.apache.maven.plugin.MojoFailureException;
30 import org.apache.maven.surefire.shared.io.FilenameUtils;
31 import org.apache.maven.toolchain.Toolchain;
32 import org.apache.maven.toolchain.ToolchainManager;
33 import org.apache.maven.toolchain.java.DefaultJavaToolChain;
34 import org.codehaus.plexus.logging.Logger;
35 import org.junit.Ignore;
36 import org.junit.Rule;
37 import org.junit.Test;
38 import org.junit.rules.ExpectedException;
39 import org.junit.runner.RunWith;
40 import org.mockito.ArgumentCaptor;
41 import org.powermock.core.classloader.annotations.PowerMockIgnore;
42 import org.powermock.core.classloader.annotations.PrepareForTest;
43 import org.powermock.modules.junit4.PowerMockRunner;
44
45 import static java.io.File.separatorChar;
46 import static java.util.Collections.singletonList;
47 import static java.util.Collections.singletonMap;
48 import static org.apache.maven.surefire.booter.SystemUtils.toJdkHomeFromJre;
49 import static org.assertj.core.api.Assertions.assertThat;
50 import static org.hamcrest.CoreMatchers.startsWith;
51 import static org.mockito.Mockito.times;
52 import static org.mockito.Mockito.verify;
53 import static org.powermock.api.mockito.PowerMockito.mock;
54 import static org.powermock.api.mockito.PowerMockito.when;
55 import static org.powermock.reflect.Whitebox.invokeMethod;
56
57
58
59
60 @RunWith(PowerMockRunner.class)
61 @PrepareForTest({AbstractSurefireMojo.class})
62 @PowerMockIgnore({"org.jacoco.agent.rt.*", "com.vladium.emma.rt.*"})
63 public class AbstractSurefireMojoToolchainsTest {
64 @Rule
65 public final ExpectedException e = ExpectedException.none();
66
67
68
69
70
71 @Test
72 public void shouldCallMethodWhenSpecSet() throws Exception {
73 AbstractSurefireMojoTest.Mojo mojo = new AbstractSurefireMojoTest.Mojo();
74 Toolchain expectedMethod = mock(Toolchain.class);
75 MockToolchainManager toolchainManager = new MockToolchainManager(expectedMethod, null);
76 mojo.setToolchainManager(toolchainManager);
77 mojo.setJdkToolchain(singletonMap("version", "1.8"));
78 Toolchain actual = invokeMethod(mojo, "getToolchain");
79 assertThat(actual).isSameAs(expectedMethod);
80 }
81
82
83
84
85
86
87 @Test
88 public void shouldFallthroughToBuildContextWhenNoSpecSet() throws Exception {
89 AbstractSurefireMojoTest.Mojo mojo = new AbstractSurefireMojoTest.Mojo();
90 Toolchain expectedFromContext = mock(Toolchain.class);
91 Toolchain expectedFromSpec = mock(Toolchain.class);
92 mojo.setToolchainManager(new MockToolchainManager(expectedFromSpec, expectedFromContext));
93 Toolchain actual = invokeMethod(mojo, "getToolchain");
94 assertThat(actual).isSameAs(expectedFromContext);
95 }
96
97
98 @Test(expected = MojoFailureException.class)
99 @Ignore
100 public void shouldThrowToolchain() throws Exception {
101 invokeMethod(AbstractSurefireMojo.class, "getToolchain");
102 }
103
104
105 @Test
106 @Ignore
107 public void shouldGetToolchain() throws Exception {
108 Toolchain expected = mock(Toolchain.class);
109 Toolchain actual = invokeMethod(AbstractSurefireMojo.class, "getToolchain");
110
111 assertThat(actual).isSameAs(expected);
112 }
113
114
115
116
117
118 @Test
119 public void shouldChangeJavaHomeFromToolchain() throws Exception {
120 AbstractSurefireMojoTest.Mojo mojo = new AbstractSurefireMojoTest.Mojo();
121 DefaultJavaToolChain toolchain = mock(DefaultJavaToolChain.class);
122 when(toolchain.findTool("java")).thenReturn("/path/from/toolchain");
123 when(toolchain.getJavaHome()).thenReturn("/some/path");
124 mojo.setToolchain(toolchain);
125
126 assertThat(mojo.getEnvironmentVariables()).isEmpty();
127 JdkAttributes effectiveJvm = invokeMethod(mojo, "getEffectiveJvm");
128 assertThat(mojo.getEnvironmentVariables()).containsEntry("JAVA_HOME", "/some/path");
129 assertThat(effectiveJvm.getJvmExecutable().getPath())
130 .contains("/path/from/toolchain".replace('/', separatorChar));
131 }
132
133 @Test
134 public void shouldNotChangeJavaHomeFromToolchainIfAlreadySet() throws Exception {
135 AbstractSurefireMojoTest.Mojo mojo = new AbstractSurefireMojoTest.Mojo();
136 mojo.setEnvironmentVariables(singletonMap("JAVA_HOME", "/already/set/path"));
137
138 DefaultJavaToolChain toolchain = mock(DefaultJavaToolChain.class);
139 when(toolchain.findTool("java")).thenReturn("/path/from/toolchain");
140 when(toolchain.getJavaHome()).thenReturn("/some/path");
141 mojo.setToolchain(toolchain);
142
143 JdkAttributes effectiveJvm = invokeMethod(mojo, "getEffectiveJvm");
144 assertThat(mojo.getEnvironmentVariables()).containsEntry("JAVA_HOME", "/already/set/path");
145 assertThat(effectiveJvm.getJvmExecutable().getPath())
146 .contains("/path/from/toolchain".replace('/', separatorChar));
147 }
148
149
150
151
152
153 @Test
154 public void shouldChangeJavaHomeFromJvm() throws Exception {
155 AbstractSurefireMojoTest.Mojo mojo = new AbstractSurefireMojoTest.Mojo();
156
157 File currentJdkHome = toJdkHomeFromJre();
158 String javaExecutablePath = FilenameUtils.concat(currentJdkHome.getAbsolutePath(), "bin/java");
159
160 mojo.setJvm(javaExecutablePath);
161
162 assertThat(mojo.getEnvironmentVariables()).isEmpty();
163 JdkAttributes effectiveJvm = invokeMethod(mojo, "getEffectiveJvm");
164 assertThat(mojo.getEnvironmentVariables()).containsEntry("JAVA_HOME", currentJdkHome.getAbsolutePath());
165 assertThat(effectiveJvm.getJvmExecutable().getPath()).contains(javaExecutablePath);
166 }
167
168
169
170
171
172 @Test
173 public void shouldNotChangeJavaHomeFromJvmIfAlreadySet() throws Exception {
174 AbstractSurefireMojoTest.Mojo mojo = new AbstractSurefireMojoTest.Mojo();
175 mojo.setEnvironmentVariables(singletonMap("JAVA_HOME", "/already/set/path"));
176
177 File currentJdkHome = toJdkHomeFromJre();
178 String javaExecutablePath = FilenameUtils.concat(currentJdkHome.getAbsolutePath(), "bin/java");
179
180 mojo.setJvm(javaExecutablePath);
181
182 JdkAttributes effectiveJvm = invokeMethod(mojo, "getEffectiveJvm");
183 assertThat(mojo.getEnvironmentVariables()).containsEntry("JAVA_HOME", "/already/set/path");
184 assertThat(effectiveJvm.getJvmExecutable().getPath()).contains(javaExecutablePath);
185 }
186
187 @Test
188 public void withoutJvmAndToolchain() throws Exception {
189 AbstractSurefireMojoTest.Mojo mojo = new AbstractSurefireMojoTest.Mojo();
190 Logger logger = mock(Logger.class);
191 mojo.setLogger(logger);
192 ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
193 JdkAttributes effectiveJvm = invokeMethod(mojo, "getEffectiveJvm");
194
195 assertThat(mojo.getJvm()).isNull();
196
197 assertThat(mojo.getEnvironmentVariables()).isEmpty();
198
199 assertThat(effectiveJvm).isNotNull();
200
201 assertThat(effectiveJvm.getJvmExecutable()).isNotNull();
202
203 Path javaHome = Paths.get(System.getProperty("java.home")).normalize();
204 boolean isLocalJvm =
205 effectiveJvm.getJvmExecutable().toPath().normalize().startsWith(javaHome);
206 assertThat(isLocalJvm).isTrue();
207
208 verify(logger, times(1)).debug(argument.capture());
209
210 assertThat(argument.getValue()).startsWith("Using JVM: " + System.getProperty("java.home"));
211 }
212
213 @Test
214 public void shouldFailWithWrongJvmExecPath() throws Exception {
215 AbstractSurefireMojoTest.Mojo mojo = new AbstractSurefireMojoTest.Mojo();
216 mojo.setLogger(mock(Logger.class));
217 mojo.setJvm(System.getProperty("user.dir"));
218
219 e.expect(MojoFailureException.class);
220 e.expectMessage(startsWith("Given path does not end with java executor"));
221
222 invokeMethod(mojo, "getEffectiveJvm");
223 }
224
225
226
227
228 public static final class MockToolchainManager implements ToolchainManager {
229
230 private final Toolchain specToolchain;
231 private final Toolchain buildContextToolchain;
232
233 public MockToolchainManager(Toolchain specToolchain, Toolchain buildContextToolchain) {
234 this.specToolchain = specToolchain;
235 this.buildContextToolchain = buildContextToolchain;
236 }
237
238 @Override
239 public Toolchain getToolchainFromBuildContext(String type, MavenSession context) {
240 return buildContextToolchain;
241 }
242
243 @Override
244 public List<Toolchain> getToolchains(MavenSession session, String type, Map<String, String> requirements) {
245 return specToolchain == null ? Collections.<Toolchain>emptyList() : singletonList(specToolchain);
246 }
247 }
248 }