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.plugins.invoker;
20  
21  import java.io.File;
22  import java.nio.file.Files;
23  import java.util.Arrays;
24  import java.util.Collection;
25  import java.util.Collections;
26  import java.util.Properties;
27  
28  import org.apache.maven.shared.invoker.InvocationRequest;
29  import org.apache.maven.shared.invoker.InvocationRequest.ReactorFailureBehavior;
30  import org.junit.Test;
31  import org.junit.runner.RunWith;
32  import org.mockito.Mock;
33  import org.mockito.junit.MockitoJUnitRunner;
34  
35  import static org.assertj.core.api.Assertions.assertThat;
36  import static org.assertj.core.api.Assertions.assertThatCode;
37  import static org.mockito.ArgumentMatchers.anyList;
38  import static org.mockito.ArgumentMatchers.eq;
39  import static org.mockito.Mockito.clearInvocations;
40  import static org.mockito.Mockito.never;
41  import static org.mockito.Mockito.verify;
42  import static org.mockito.Mockito.verifyNoInteractions;
43  import static org.mockito.Mockito.verifyNoMoreInteractions;
44  import static org.mockito.Mockito.when;
45  
46  /**
47   * Tests the invoker properties facade.
48   *
49   * @author Benjamin Bentmann
50   */
51  @RunWith(MockitoJUnitRunner.class)
52  public class InvokerPropertiesTest {
53  
54      @Mock
55      private InvocationRequest request;
56  
57      @Test
58      public void testConstructorNullSafe() {
59          InvokerProperties facade = new InvokerProperties(null);
60          assertThat(facade.getProperties()).isNotNull();
61      }
62  
63      @Test
64      public void testGetInvokerProperty() {
65          Properties props = new Properties();
66          InvokerProperties facade = new InvokerProperties(props);
67  
68          assertThat(facade.get("undefined-key", 0)).isEmpty();
69  
70          props.setProperty("key", "value");
71          assertThat(facade.get("key", 1)).hasValue("value");
72  
73          props.setProperty("key.1", "another-value");
74          assertThat(facade.get("key", 1)).hasValue("another-value");
75          assertThat(facade.get("key", 2)).hasValue("value");
76      }
77  
78      @Test
79      public void testGetJobName() {
80          Properties props = new Properties();
81          final String jobName = "Build Job name";
82          props.put("invoker.name", jobName);
83          InvokerProperties facade = new InvokerProperties(props);
84  
85          assertThat(facade.getJobName()).isEqualTo(jobName);
86      }
87  
88      @Test
89      public void testIsExpectedResult() {
90          Properties props = new Properties();
91          InvokerProperties facade = new InvokerProperties(props);
92  
93          assertThat(facade.isExpectedResult(0, 0)).isTrue();
94          assertThat(facade.isExpectedResult(1, 0)).isFalse();
95  
96          props.setProperty("invoker.buildResult", "success");
97          assertThat(facade.isExpectedResult(0, 0)).isTrue();
98          assertThat(facade.isExpectedResult(1, 0)).isFalse();
99  
100         props.setProperty("invoker.buildResult", "failure");
101         assertThat(facade.isExpectedResult(0, 0)).isFalse();
102         assertThat(facade.isExpectedResult(1, 0)).isTrue();
103     }
104 
105     @Test
106     public void testConfigureRequestEmptyProperties() {
107 
108         InvokerProperties facade = new InvokerProperties(null);
109 
110         facade.configureInvocation(request, 0);
111         verifyNoInteractions(request);
112     }
113 
114     @Test
115     public void testConfigureRequestGoals() {
116         Properties props = new Properties();
117         InvokerProperties facade = new InvokerProperties(props);
118 
119         props.setProperty("invoker.goals", "verify");
120         facade.configureInvocation(request, 0);
121         verify(request).setGoals(Collections.singletonList("verify"));
122         verifyNoMoreInteractions(request);
123         clearInvocations(request);
124 
125         props.setProperty("invoker.goals", "   ");
126         facade.configureInvocation(request, 0);
127         verify(request, never()).setGoals(anyList());
128         verifyNoMoreInteractions(request);
129         clearInvocations(request);
130 
131         props.setProperty("invoker.goals", "");
132         facade.configureInvocation(request, 0);
133         verify(request, never()).setGoals(anyList());
134         verifyNoMoreInteractions(request);
135         clearInvocations(request);
136 
137         props.setProperty("invoker.goals", "  clean , test   verify ");
138         facade.configureInvocation(request, 0);
139         verify(request).setGoals(Arrays.asList("clean", "test", "verify"));
140         verifyNoMoreInteractions(request);
141         clearInvocations(request);
142 
143         props.clear();
144 
145         facade.setDefaultGoals(Arrays.asList("clean", "test"));
146         facade.configureInvocation(request, 0);
147         verify(request).setGoals(Arrays.asList("clean", "test"));
148         verifyNoMoreInteractions(request);
149     }
150 
151     @Test
152     public void testConfigureRequestProfiles() {
153         Properties props = new Properties();
154         InvokerProperties facade = new InvokerProperties(props);
155 
156         props.setProperty("invoker.profiles", "verify");
157         facade.configureInvocation(request, 0);
158         verify(request).setProfiles(Collections.singletonList("verify"));
159         verifyNoMoreInteractions(request);
160         clearInvocations(request);
161 
162         props.setProperty("invoker.profiles", "   ");
163         facade.configureInvocation(request, 0);
164         verify(request, never()).setProfiles(anyList());
165         verifyNoMoreInteractions(request);
166         clearInvocations(request);
167 
168         props.setProperty("invoker.profiles", "");
169         facade.configureInvocation(request, 0);
170         verify(request, never()).setProfiles(anyList());
171         verifyNoMoreInteractions(request);
172         clearInvocations(request);
173 
174         props.setProperty("invoker.profiles", "  clean , test   verify  ,");
175         facade.configureInvocation(request, 0);
176         verify(request).setProfiles(Arrays.asList("clean", "test", "verify"));
177         verifyNoMoreInteractions(request);
178         clearInvocations(request);
179 
180         props.clear();
181         facade.setDefaultProfiles(Arrays.asList("profile1", "profile2"));
182         facade.configureInvocation(request, 0);
183         verify(request).setProfiles(Arrays.asList("profile1", "profile2"));
184         verifyNoMoreInteractions(request);
185     }
186 
187     @Test
188     public void testConfigureRequestProject() throws Exception {
189         Properties props = new Properties();
190         InvokerProperties facade = new InvokerProperties(props);
191 
192         File tempPom = Files.createTempFile("maven-invoker-plugin-test", ".pom").toFile();
193         try {
194             File tempDir = tempPom.getParentFile();
195             when(request.getBaseDirectory()).thenReturn(tempDir);
196 
197             props.setProperty("invoker.project", tempPom.getName());
198             facade.configureInvocation(request, 0);
199             verify(request).getBaseDirectory();
200             verify(request).setBaseDirectory(tempDir);
201             verify(request).setPomFile(tempPom);
202             verifyNoMoreInteractions(request);
203             clearInvocations(request);
204 
205             props.setProperty("invoker.project", "");
206             facade.configureInvocation(request, 0);
207             verifyNoInteractions(request);
208         } finally {
209             tempPom.delete();
210         }
211     }
212 
213     @Test
214     public void testConfigureRequestMavenExecutable() {
215         Properties props = new Properties();
216 
217         InvokerProperties facade = new InvokerProperties(props);
218         File aDefExecutable = new File("defExecutable");
219         facade.setDefaultMavenExecutable(aDefExecutable.toString());
220 
221         props.setProperty("invoker.mavenExecutable", "aPropExecutable");
222         facade.configureInvocation(request, 0);
223         verify(request).setMavenExecutable(new File("aPropExecutable"));
224         verifyNoMoreInteractions(request);
225         clearInvocations(request);
226 
227         props.clear();
228 
229         facade.configureInvocation(request, 0);
230         verify(request).setMavenExecutable(aDefExecutable);
231         verifyNoMoreInteractions(request);
232     }
233 
234     @Test
235     public void testConfigureRequestMavenOpts() {
236         Properties props = new Properties();
237 
238         InvokerProperties facade = new InvokerProperties(props);
239         facade.setDefaultMavenOpts("-XxxDef");
240 
241         props.setProperty("invoker.mavenOpts", "-Xmx512m");
242         facade.configureInvocation(request, 0);
243         verify(request).setMavenOpts("-Xmx512m");
244         verifyNoMoreInteractions(request);
245         clearInvocations(request);
246 
247         props.clear();
248 
249         facade.configureInvocation(request, 0);
250         verify(request).setMavenOpts("-XxxDef");
251         verifyNoMoreInteractions(request);
252     }
253 
254     @Test
255     public void testConfigureRequestFailureBehavior() {
256         Properties props = new Properties();
257         InvokerProperties facade = new InvokerProperties(props);
258 
259         props.setProperty("invoker.failureBehavior", ReactorFailureBehavior.FailNever.getLongOption());
260         facade.configureInvocation(request, 0);
261         verify(request).setReactorFailureBehavior(eq(ReactorFailureBehavior.FailNever));
262 
263         verifyNoMoreInteractions(request);
264     }
265 
266     @Test
267     public void testConfigureRequestFailureBehaviorUnKnownName() {
268         Properties props = new Properties();
269         InvokerProperties facade = new InvokerProperties(props);
270 
271         props.setProperty("invoker.failureBehavior", "xxxUnKnown");
272 
273         assertThatCode(() -> facade.configureInvocation(request, 0))
274                 .isExactlyInstanceOf(IllegalArgumentException.class)
275                 .hasMessage("The string 'xxxUnKnown' can not be converted to enumeration.");
276 
277         verifyNoInteractions(request);
278     }
279 
280     @Test
281     public void testConfigureRequestRecursion() {
282         Properties props = new Properties();
283         InvokerProperties facade = new InvokerProperties(props);
284 
285         props.setProperty("invoker.nonRecursive", "true");
286         facade.configureInvocation(request, 0);
287         verify(request).setRecursive(false);
288         verifyNoMoreInteractions(request);
289         clearInvocations(request);
290 
291         props.setProperty("invoker.nonRecursive", "false");
292         facade.configureInvocation(request, 0);
293         verify(request).setRecursive(true);
294         verifyNoMoreInteractions(request);
295     }
296 
297     @Test
298     public void testConfigureRequestOffline() {
299         Properties props = new Properties();
300         InvokerProperties facade = new InvokerProperties(props);
301 
302         props.setProperty("invoker.offline", "true");
303         facade.configureInvocation(request, 0);
304         verify(request).setOffline(true);
305         verifyNoMoreInteractions(request);
306         clearInvocations(request);
307 
308         props.setProperty("invoker.offline", "false");
309         facade.configureInvocation(request, 0);
310         verify(request).setOffline(false);
311         verifyNoMoreInteractions(request);
312     }
313 
314     @Test
315     public void testConfigureRequestDebug() {
316         Properties props = new Properties();
317         InvokerProperties facade = new InvokerProperties(props);
318 
319         props.setProperty("invoker.debug", "true");
320         facade.configureInvocation(request, 0);
321         verify(request).setDebug(true);
322         verifyNoMoreInteractions(request);
323         clearInvocations(request);
324 
325         props.setProperty("invoker.debug", "false");
326         facade.configureInvocation(request, 0);
327         verify(request).setDebug(false);
328         verifyNoMoreInteractions(request);
329 
330         props.clear();
331 
332         facade.setDefaultDebug(true);
333         facade.configureInvocation(request, 0);
334         verify(request).setDebug(true);
335         verifyNoMoreInteractions(request);
336         clearInvocations(request);
337 
338         facade.setDefaultDebug(false);
339         facade.configureInvocation(request, 0);
340         verify(request).setDebug(false);
341         verifyNoMoreInteractions(request);
342         clearInvocations(request);
343     }
344 
345     @Test
346     public void testConfigureRequestQuiet() {
347         Properties props = new Properties();
348         InvokerProperties facade = new InvokerProperties(props);
349 
350         props.setProperty("invoker.quiet", "true");
351         facade.configureInvocation(request, 0);
352         verify(request).setQuiet(true);
353         verifyNoMoreInteractions(request);
354         clearInvocations(request);
355 
356         props.setProperty("invoker.quiet", "false");
357         facade.configureInvocation(request, 0);
358         verify(request).setQuiet(false);
359         verifyNoMoreInteractions(request);
360 
361         props.clear();
362 
363         facade.setDefaultQuiet(true);
364         facade.configureInvocation(request, 0);
365         verify(request).setQuiet(true);
366         verifyNoMoreInteractions(request);
367         clearInvocations(request);
368 
369         facade.setDefaultQuiet(false);
370         facade.configureInvocation(request, 0);
371         verify(request).setQuiet(false);
372         verifyNoMoreInteractions(request);
373         clearInvocations(request);
374     }
375 
376     @Test
377     public void testConfigureRequestTimeoutInSeconds() {
378         Properties props = new Properties();
379         InvokerProperties facade = new InvokerProperties(props);
380 
381         props.setProperty("invoker.timeoutInSeconds", "5");
382         facade.configureInvocation(request, 0);
383         verify(request).setTimeoutInSeconds(5);
384         verifyNoMoreInteractions(request);
385         clearInvocations(request);
386 
387         props.clear();
388 
389         facade.setDefaultTimeoutInSeconds(3);
390         facade.configureInvocation(request, 0);
391         verify(request).setTimeoutInSeconds(3);
392         verifyNoMoreInteractions(request);
393     }
394 
395     @Test
396     public void testConfigureEnvironmentVariables() {
397         Properties props = new Properties();
398         InvokerProperties facade = new InvokerProperties(props);
399 
400         props.setProperty("invoker.abcdef", "abcdf");
401         props.setProperty("invoker.environmentVariables.KEY1.1", "value1.1");
402         props.setProperty("invoker.environmentVariables.KEY1", "value1");
403         props.setProperty("invoker.environmentVariables.KEY2", "value2");
404         props.setProperty("invoker.environmentVariables.KEY2.1", "value2.1");
405         props.setProperty("invoker.environmentVariables.KEY3", "value3");
406         facade.configureInvocation(request, 0);
407         verify(request).addShellEnvironment("KEY1", "value1");
408         verify(request).addShellEnvironment("KEY2", "value2");
409         verify(request).addShellEnvironment("KEY3", "value3");
410         verifyNoMoreInteractions(request);
411     }
412 
413     @Test
414     public void testConfigureEnvironmentVariablesWithIndex() {
415         Properties props = new Properties();
416         InvokerProperties facade = new InvokerProperties(props);
417 
418         props.setProperty("invoker.abcdef", "abcdf");
419         props.setProperty("invoker.environmentVariables.KEY1.1", "value1.1");
420         props.setProperty("invoker.environmentVariables.KEY1", "value1");
421         props.setProperty("invoker.environmentVariables.KEY2", "value2");
422         props.setProperty("invoker.environmentVariables.KEY2.1", "value2.1");
423         props.setProperty("invoker.environmentVariables.KEY3", "value3");
424         facade.configureInvocation(request, 1);
425         verify(request).addShellEnvironment("KEY1", "value1.1");
426         verify(request).addShellEnvironment("KEY2", "value2.1");
427         verify(request).addShellEnvironment("KEY3", "value3");
428         verifyNoMoreInteractions(request);
429     }
430 
431     @Test
432     public void testConfigureUpdateSnapshots() {
433         Properties props = new Properties();
434         InvokerProperties facade = new InvokerProperties(props);
435 
436         props.setProperty("invoker.updateSnapshots", "true");
437         facade.configureInvocation(request, 1);
438         verify(request).setUpdateSnapshots(true);
439         clearInvocations(request);
440         props.clear();
441 
442         props.setProperty("invoker.updateSnapshots", "false");
443         facade.configureInvocation(request, 1);
444         verify(request).setUpdateSnapshots(false);
445 
446         verifyNoMoreInteractions(request);
447     }
448 
449     @Test
450     public void testConfigureUpdateSnapshotsDefault() {
451         Properties props = new Properties();
452         InvokerProperties facade = new InvokerProperties(props);
453 
454         facade.setDefaultUpdateSnapshots(true);
455         facade.configureInvocation(request, 1);
456         verify(request).setUpdateSnapshots(true);
457         clearInvocations(request);
458 
459         facade.setDefaultUpdateSnapshots(false);
460         facade.configureInvocation(request, 1);
461         verify(request).setUpdateSnapshots(false);
462 
463         verifyNoMoreInteractions(request);
464     }
465 
466     @Test
467     public void testIsInvocationDefined() {
468         Properties props = new Properties();
469         InvokerProperties facade = new InvokerProperties(props);
470 
471         assertThat(facade.isInvocationDefined(1)).isFalse();
472 
473         props.setProperty("invoker.goals", "install");
474         assertThat(facade.isInvocationDefined(1)).isFalse();
475 
476         props.setProperty("invoker.goals.2", "install");
477         assertThat(facade.isInvocationDefined(1)).isFalse();
478         assertThat(facade.isInvocationDefined(2)).isTrue();
479         assertThat(facade.isInvocationDefined(3)).isFalse();
480 
481         props.setProperty("invoker.goals.3", "install");
482         assertThat(facade.isInvocationDefined(1)).isFalse();
483         assertThat(facade.isInvocationDefined(2)).isTrue();
484         assertThat(facade.isInvocationDefined(3)).isTrue();
485         assertThat(facade.isInvocationDefined(4)).isFalse();
486     }
487 
488     @Test
489     public void testIsSelectedDefined() {
490         Properties props = new Properties();
491         InvokerProperties facade = new InvokerProperties(props);
492 
493         assertThat(facade.isSelectorDefined(1)).isFalse();
494 
495         props.setProperty("invoker.java.version", "1.6+");
496         props.setProperty("invoker.maven.version", "3.0+");
497         props.setProperty("invoker.os.family", "windows");
498         assertThat(facade.isSelectorDefined(1)).isFalse();
499 
500         props.setProperty("selector.2.java.version", "1.6+");
501         props.setProperty("selector.3.maven.version", "3.0+");
502         props.setProperty("selector.4.os.family", "windows");
503         assertThat(facade.isSelectorDefined(1)).isFalse();
504         assertThat(facade.isSelectorDefined(2)).isTrue();
505         assertThat(facade.isSelectorDefined(3)).isTrue();
506         assertThat(facade.isSelectorDefined(4)).isTrue();
507         assertThat(facade.isSelectorDefined(5)).isFalse();
508     }
509 
510     @Test
511     public void testGetToolchainsForEmptyProperties() {
512 
513         Properties props = new Properties();
514         InvokerProperties facade = new InvokerProperties(props);
515 
516         Collection<InvokerToolchain> toolchains = facade.getToolchains();
517         assertThat(toolchains).isEmpty();
518 
519         toolchains = facade.getToolchains(1);
520         assertThat(toolchains).isEmpty();
521     }
522 
523     @Test
524     public void testGetToolchains() {
525         Properties props = new Properties();
526         props.put("invoker.toolchain.jdk.version", "11");
527         InvokerProperties facade = new InvokerProperties(props);
528 
529         Collection<InvokerToolchain> toolchains = facade.getToolchains();
530         assertThat(toolchains).hasSize(1);
531         InvokerToolchain toolchain = toolchains.iterator().next();
532         assertThat(toolchain.getType()).isEqualTo("jdk");
533         assertThat(toolchain.getProvides()).containsExactlyEntriesOf(Collections.singletonMap("version", "11"));
534     }
535 
536     @Test
537     public void testGetToolchainsWithIndex() {
538         Properties props = new Properties();
539         props.put("selector.1.invoker.toolchain.jdk.version", "11");
540         InvokerProperties facade = new InvokerProperties(props);
541 
542         Collection<InvokerToolchain> toolchains = facade.getToolchains(1);
543         assertThat(toolchains).hasSize(1);
544         InvokerToolchain toolchain = toolchains.iterator().next();
545         assertThat(toolchain.getType()).isEqualTo("jdk");
546         assertThat(toolchain.getProvides()).containsExactlyEntriesOf(Collections.singletonMap("version", "11"));
547     }
548 }