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.enforcer.rules;
20  
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.HashSet;
24  import java.util.List;
25  import java.util.Set;
26  
27  import org.apache.maven.artifact.factory.ArtifactFactory;
28  import org.apache.maven.enforcer.rule.api.EnforcerLogger;
29  import org.apache.maven.enforcer.rule.api.EnforcerRuleError;
30  import org.apache.maven.enforcer.rules.utils.EnforcerRuleUtils;
31  import org.apache.maven.enforcer.rules.utils.ExpressionEvaluator;
32  import org.apache.maven.enforcer.rules.utils.PluginWrapper;
33  import org.apache.maven.execution.MavenSession;
34  import org.apache.maven.lifecycle.DefaultLifecycles;
35  import org.apache.maven.model.Plugin;
36  import org.apache.maven.plugin.MojoExecutionException;
37  import org.apache.maven.plugin.PluginManager;
38  import org.apache.maven.project.MavenProject;
39  import org.apache.maven.rtinfo.RuntimeInformation;
40  import org.codehaus.plexus.PlexusContainer;
41  import org.eclipse.aether.RepositorySystem;
42  import org.junit.jupiter.api.BeforeEach;
43  import org.junit.jupiter.api.Test;
44  import org.junit.jupiter.api.extension.ExtendWith;
45  import org.mockito.InjectMocks;
46  import org.mockito.Mock;
47  import org.mockito.Mockito;
48  import org.mockito.junit.jupiter.MockitoExtension;
49  
50  import static org.junit.jupiter.api.Assertions.assertEquals;
51  import static org.junit.jupiter.api.Assertions.assertFalse;
52  import static org.junit.jupiter.api.Assertions.assertNotNull;
53  import static org.junit.jupiter.api.Assertions.assertTrue;
54  import static org.junit.jupiter.api.Assertions.fail;
55  import static org.mockito.ArgumentMatchers.anyString;
56  import static org.mockito.ArgumentMatchers.isNull;
57  import static org.mockito.Mockito.when;
58  
59  /**
60   * The Class TestRequirePluginVersions.
61   *
62   * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
63   */
64  @ExtendWith(MockitoExtension.class)
65  class TestRequirePluginVersions {
66  
67      @Mock
68      private PluginManager pluginManager;
69  
70      @Mock
71      private ArtifactFactory factory;
72  
73      @Mock
74      private RepositorySystem repositorySystem;
75  
76      @Mock
77      private MavenSession session;
78  
79      @Mock
80      private EnforcerRuleUtils utils;
81  
82      @Mock
83      private RuntimeInformation runtimeInformation;
84  
85      @Mock
86      private DefaultLifecycles defaultLifeCycles;
87  
88      @Mock
89      private MavenProject project;
90  
91      @Mock
92      private ExpressionEvaluator evaluator;
93  
94      @Mock
95      private PlexusContainer container;
96  
97      @InjectMocks
98      private RequirePluginVersions rule;
99  
100     @BeforeEach
101     void setup() {
102         rule.setLog(Mockito.mock(EnforcerLogger.class));
103     }
104 
105     /**
106      * Test has version specified.
107      */
108     @Test
109     void testHasVersionSpecified() throws Exception {
110 
111         when(evaluator.evaluate(anyString())).thenAnswer(i -> i.getArgument(0));
112         when(evaluator.evaluate(isNull())).thenReturn(null);
113 
114         Plugin source = new Plugin();
115         source.setArtifactId("foo");
116         source.setGroupId("group");
117 
118         // setup the plugins. I'm setting up the foo group
119         // with a few bogus entries and then a real one.
120         // to test that the list is exhaustively
121         // searched for versions before giving up.
122         // banLatest/Release will fail if it is found
123         // anywhere in the list.
124         List<Plugin> plugins = new ArrayList<>();
125         plugins.add(EnforcerTestUtils.newPlugin("group", "a-artifact", "1.0"));
126         plugins.add(EnforcerTestUtils.newPlugin("group", "foo", null));
127         plugins.add(EnforcerTestUtils.newPlugin("group", "foo", ""));
128         plugins.add(EnforcerTestUtils.newPlugin("group", "b-artifact", "1.0"));
129         plugins.add(EnforcerTestUtils.newPlugin("group", "foo", "1.0"));
130         plugins.add(EnforcerTestUtils.newPlugin("group", "c-artifact", "LATEST"));
131         plugins.add(EnforcerTestUtils.newPlugin("group", "c-artifact", "1.0"));
132         plugins.add(EnforcerTestUtils.newPlugin("group", "d-artifact", "RELEASE"));
133         plugins.add(EnforcerTestUtils.newPlugin("group", "d-artifact", "1.0"));
134         plugins.add(EnforcerTestUtils.newPlugin("group", "e-artifact", "1.0"));
135         plugins.add(EnforcerTestUtils.newPlugin("group", "e-artifact", "RELEASE"));
136         plugins.add(EnforcerTestUtils.newPlugin("group", "f-artifact", "1.0"));
137         plugins.add(EnforcerTestUtils.newPlugin("group", "f-artifact", "LATEST"));
138         plugins.add(EnforcerTestUtils.newPlugin("group", "f-artifact", "1.0-SNAPSHOT"));
139         plugins.add(EnforcerTestUtils.newPlugin("group", "g-artifact", "1.0-12345678.123456-1"));
140 
141         List<PluginWrapper> pluginWrappers = PluginWrapper.addAll(plugins, false);
142 
143         rule.setBanLatest(false);
144         rule.setBanRelease(false);
145         rule.setBanSnapshots(false);
146 
147         assertTrue(rule.hasValidVersionSpecified(source, pluginWrappers));
148 
149         // check that LATEST is allowed
150         source.setArtifactId("c-artifact");
151         assertTrue(rule.hasValidVersionSpecified(source, pluginWrappers));
152 
153         // check that LATEST is banned
154         rule.setBanLatest(true);
155         assertFalse(rule.hasValidVersionSpecified(source, pluginWrappers));
156 
157         // check that LATEST is exhaustively checked
158         rule.setBanSnapshots(false);
159         source.setArtifactId("f-artifact");
160         assertFalse(rule.hasValidVersionSpecified(source, pluginWrappers));
161 
162         rule.setBanLatest(false);
163         rule.setBanSnapshots(true);
164         assertFalse(rule.hasValidVersionSpecified(source, pluginWrappers));
165 
166         // check that TIMESTAMP is allowed
167         rule.setBanTimestamps(false);
168         source.setArtifactId("g-artifact");
169         assertTrue(rule.hasValidVersionSpecified(source, pluginWrappers));
170 
171         // check that RELEASE is allowed
172         source.setArtifactId("d-artifact");
173         assertTrue(rule.hasValidVersionSpecified(source, pluginWrappers));
174 
175         // check that RELEASE is banned
176         rule.setBanRelease(true);
177         assertFalse(rule.hasValidVersionSpecified(source, pluginWrappers));
178 
179         // check that RELEASE is exhaustively checked
180         source.setArtifactId("e-artifact");
181         assertFalse(rule.hasValidVersionSpecified(source, pluginWrappers));
182     }
183 
184     /**
185      * Test has version specified with properties.
186      */
187     @Test
188     void testHasVersionSpecifiedWithProperties() throws Exception {
189 
190         when(evaluator.evaluate(anyString())).thenAnswer(i -> ((String) i.getArgument(0)).replaceAll("\\$\\{|}", ""));
191 
192         Plugin source = new Plugin();
193         source.setGroupId("group");
194 
195         // setup the plugins.
196         List<Plugin> plugins = new ArrayList<>();
197         plugins.add(EnforcerTestUtils.newPlugin("group", "a-artifact", "1.0-${SNAPSHOT}"));
198         plugins.add(EnforcerTestUtils.newPlugin("group", "b-artifact", "${1.0}"));
199         plugins.add(EnforcerTestUtils.newPlugin("group", "c-artifact", "${LATEST}"));
200         plugins.add(EnforcerTestUtils.newPlugin("group", "d-artifact", "${RELEASE}"));
201         plugins.add(EnforcerTestUtils.newPlugin("group", "e-artifact", "${}"));
202         plugins.add(EnforcerTestUtils.newPlugin("group", "f-artifact", "${   }"));
203 
204         List<PluginWrapper> pluginWrappers = PluginWrapper.addAll(plugins, false);
205 
206         rule.setBanLatest(false);
207         rule.setBanRelease(false);
208         rule.setBanSnapshots(false);
209 
210         source.setArtifactId("a-artifact");
211         assertTrue(rule.hasValidVersionSpecified(source, pluginWrappers));
212 
213         source.setArtifactId("b-artifact");
214         assertTrue(rule.hasValidVersionSpecified(source, pluginWrappers));
215 
216         source.setArtifactId("c-artifact");
217         assertTrue(rule.hasValidVersionSpecified(source, pluginWrappers));
218 
219         source.setArtifactId("d-artifact");
220         assertTrue(rule.hasValidVersionSpecified(source, pluginWrappers));
221 
222         // this one checks empty property values
223         source.setArtifactId("e-artifact");
224         assertFalse(rule.hasValidVersionSpecified(source, pluginWrappers));
225 
226         // this one checks empty property values
227         source.setArtifactId("f-artifact");
228         assertFalse(rule.hasValidVersionSpecified(source, pluginWrappers));
229 
230         rule.setBanLatest(true);
231         source.setArtifactId("c-artifact");
232         assertFalse(rule.hasValidVersionSpecified(source, pluginWrappers));
233 
234         rule.setBanRelease(true);
235         source.setArtifactId("d-artifact");
236         assertFalse(rule.hasValidVersionSpecified(source, pluginWrappers));
237 
238         rule.setBanSnapshots(true);
239         source.setArtifactId("a-artifact");
240         assertFalse(rule.hasValidVersionSpecified(source, pluginWrappers));
241 
242         // release versions should pass everything
243         source.setArtifactId("b-artifact");
244         assertTrue(rule.hasValidVersionSpecified(source, pluginWrappers));
245     }
246 
247     /**
248      * Test get additional plugins null.
249      *
250      * @throws MojoExecutionException the mojo execution exception
251      */
252     @Test
253     void testGetAdditionalPluginsNull() throws Exception {
254         rule.addAdditionalPlugins(null, null);
255     }
256 
257     /**
258      * Test get additional plugins invalid format.
259      */
260     @Test
261     void testGetAdditionalPluginsInvalidFormat() {
262 
263         List<String> additional = new ArrayList<>();
264 
265         // invalid format (not enough sections)
266         additional.add("group");
267 
268         Set<Plugin> plugins = new HashSet<>();
269         try {
270             rule.addAdditionalPlugins(plugins, additional);
271             fail("Expected Exception because the format is invalid");
272         } catch (EnforcerRuleError e) {
273         }
274 
275         // invalid format (too many sections)
276         additional.clear();
277         additional.add("group:i:i");
278         try {
279             rule.addAdditionalPlugins(plugins, additional);
280             fail("Expected Exception because the format is invalid");
281         } catch (EnforcerRuleError e) {
282         }
283     }
284 
285     /**
286      * Test get additional plugins empty set.
287      *
288      * @throws MojoExecutionException the mojo execution exception
289      */
290     @Test
291     void testGetAdditionalPluginsEmptySet() throws Exception {
292 
293         Set<Plugin> plugins = new HashSet<>();
294         plugins.add(EnforcerTestUtils.newPlugin("group", "a-artifact", "1.0"));
295         plugins.add(EnforcerTestUtils.newPlugin("group", "foo", null));
296         plugins.add(EnforcerTestUtils.newPlugin("group", "foo2", ""));
297 
298         List<String> additional = new ArrayList<>();
299         additional.add("group:a-artifact");
300         additional.add("group:another-artifact");
301 
302         // make sure a null set can be handled
303         Set<Plugin> results = rule.addAdditionalPlugins(null, additional);
304 
305         assertNotNull(results);
306         assertContainsPlugin("group", "a-artifact", results);
307         assertContainsPlugin("group", "another-artifact", results);
308     }
309 
310     /**
311      * Test get additional plugins.
312      *
313      * @throws MojoExecutionException the mojo execution exception
314      */
315     @Test
316     void testGetAdditionalPlugins() throws Exception {
317 
318         Set<Plugin> plugins = new HashSet<>();
319         plugins.add(EnforcerTestUtils.newPlugin("group", "a-artifact", "1.0"));
320         plugins.add(EnforcerTestUtils.newPlugin("group", "foo", null));
321         plugins.add(EnforcerTestUtils.newPlugin("group", "foo2", ""));
322 
323         List<String> additional = new ArrayList<>();
324         additional.add("group:a-artifact");
325         additional.add("group:another-artifact");
326 
327         Set<Plugin> results = rule.addAdditionalPlugins(plugins, additional);
328 
329         // make sure only one new plugin has been added
330         assertNotNull(results);
331         assertEquals(4, results.size());
332         assertContainsPlugin("group", "a-artifact", results);
333         assertContainsPlugin("group", "another-artifact", results);
334     }
335 
336     /**
337      * Test remove Unchecked plugins.
338      *
339      * @throws MojoExecutionException the mojo execution exception
340      */
341     @Test
342     void testGetUncheckedPlugins() throws Exception {
343 
344         Set<Plugin> plugins = new HashSet<>();
345         plugins.add(EnforcerTestUtils.newPlugin("group", "a-artifact", "1.0"));
346         plugins.add(EnforcerTestUtils.newPlugin("group", "foo", null));
347         plugins.add(EnforcerTestUtils.newPlugin("group", "foo2", ""));
348 
349         List<String> unchecked = new ArrayList<>();
350         // intentionally inserting spaces to make sure they are handled correctly.
351         unchecked.add("group : a-artifact");
352 
353         Collection<Plugin> results = rule.removeUncheckedPlugins(unchecked, plugins);
354 
355         // make sure only one new plugin has been added
356         assertNotNull(results);
357         assertEquals(2, results.size());
358         assertContainsPlugin("group", "foo", results);
359         assertContainsPlugin("group", "foo2", results);
360         assertNotContainPlugin("group", "a-artifact", results);
361     }
362 
363     /**
364      * Test combining values from both lists
365      */
366     @Test
367     void testCombinePlugins() {
368 
369         Set<String> plugins = new HashSet<>();
370         plugins.add("group:a-artifact");
371         plugins.add("group:foo");
372         plugins.add("group:foo2");
373 
374         Collection<String> results = rule.combineUncheckedPlugins(plugins, "group2:a,group3:b");
375 
376         // make sure only one new plugin has been added
377         assertNotNull(results);
378         assertEquals(5, results.size());
379         assertTrue(results.contains("group:foo"));
380         assertTrue(results.contains("group:foo2"));
381         assertTrue(results.contains("group:a-artifact"));
382         assertTrue(results.contains("group2:a"));
383         assertTrue(results.contains("group3:b"));
384     }
385 
386     /**
387      * Test combining with an empty list
388      */
389     @Test
390     void testCombinePlugins1() {
391 
392         Set<String> plugins = new HashSet<>();
393         Collection<String> results = rule.combineUncheckedPlugins(plugins, "group2:a,group3:b");
394 
395         // make sure only one new plugin has been added
396         assertNotNull(results);
397         assertEquals(2, results.size());
398         assertTrue(results.contains("group2:a"));
399         assertTrue(results.contains("group3:b"));
400     }
401 
402     /**
403      * Test combining with a null list
404      */
405     @Test
406     void testCombinePlugins2() {
407 
408         Collection<String> results = rule.combineUncheckedPlugins(null, "group2:a,group3:b");
409 
410         // make sure only one new plugin has been added
411         assertNotNull(results);
412         assertEquals(2, results.size());
413         assertTrue(results.contains("group2:a"));
414         assertTrue(results.contains("group3:b"));
415     }
416 
417     /**
418      * Test combining with an empty string
419      */
420     @Test
421     void testCombinePlugins3() {
422 
423         Set<String> plugins = new HashSet<>();
424         plugins.add("group:a-artifact");
425         plugins.add("group:foo");
426         plugins.add("group:foo2");
427 
428         Collection<String> results = rule.combineUncheckedPlugins(plugins, "");
429         assertNotNull(results);
430         assertEquals(3, results.size());
431         assertTrue(results.contains("group:foo"));
432         assertTrue(results.contains("group:foo2"));
433         assertTrue(results.contains("group:a-artifact"));
434     }
435 
436     /**
437      * Test combining with a null string
438      */
439     @Test
440     void testCombinePlugins4() {
441 
442         Set<String> plugins = new HashSet<>();
443         plugins.add("group:a-artifact");
444         plugins.add("group:foo");
445         plugins.add("group:foo2");
446 
447         Collection<String> results = rule.combineUncheckedPlugins(plugins, null);
448         assertNotNull(results);
449         assertEquals(3, results.size());
450         assertTrue(results.contains("group:foo"));
451         assertTrue(results.contains("group:foo2"));
452         assertTrue(results.contains("group:a-artifact"));
453     }
454 
455     /**
456      * Test combining with an invalid plugin string
457      */
458     @Test
459     void testCombinePlugins5() {
460 
461         Set<String> plugins = new HashSet<>();
462         plugins.add("group:a-artifact");
463         plugins.add("group:foo");
464         plugins.add("group:foo2");
465 
466         Collection<String> results = rule.combineUncheckedPlugins(plugins, "a");
467         assertNotNull(results);
468         assertEquals(4, results.size());
469         assertTrue(results.contains("group:foo"));
470         assertTrue(results.contains("group:foo2"));
471         // this should be here, the checking of a valid plugin string happens in another method.
472         assertTrue(results.contains("a"));
473     }
474 
475     /**
476      * Assert contains plugin.
477      *
478      * @param group    the group
479      * @param artifact the artifact
480      * @param theSet   the the set
481      */
482     private void assertContainsPlugin(String group, String artifact, Collection<Plugin> theSet) {
483         Plugin p = new Plugin();
484         p.setGroupId(group);
485         p.setArtifactId(artifact);
486         assertTrue(theSet.contains(p));
487     }
488 
489     /**
490      * Assert doesn't contain plugin.
491      *
492      * @param group    the group
493      * @param artifact the artifact
494      * @param theSet   the the set
495      */
496     private void assertNotContainPlugin(String group, String artifact, Collection<Plugin> theSet) {
497         Plugin p = new Plugin();
498         p.setGroupId(group);
499         p.setArtifactId(artifact);
500         assertFalse(theSet.contains(p));
501     }
502 
503     /**
504      * Test id.
505      */
506     @Test
507     void testId() {
508         rule.getCacheId();
509     }
510 }