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 }