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.Arrays;
22  import java.util.Collections;
23  import java.util.List;
24  
25  import org.apache.maven.enforcer.rule.api.EnforcerLogger;
26  import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
27  import org.apache.maven.execution.MavenSession;
28  import org.apache.maven.execution.ProjectDependencyGraph;
29  import org.apache.maven.model.Dependency;
30  import org.apache.maven.project.MavenProject;
31  import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
32  import org.junit.jupiter.api.BeforeEach;
33  import org.junit.jupiter.api.Test;
34  
35  import static org.assertj.core.api.Assertions.assertThat;
36  import static org.junit.jupiter.api.Assertions.assertThrows;
37  import static org.mockito.Mockito.mock;
38  import static org.mockito.Mockito.when;
39  
40  /**
41   * Check reactorModuleConvergence rule.
42   *
43   * @author <a href="mailto:khmarbaise@apache.org">Karl Heinz Marbaise</a>
44   */
45  class ReactorModuleConvergenceTest {
46      private MavenSession session;
47  
48      private ReactorModuleConvergence rule;
49  
50      @BeforeEach
51      public void before() throws ExpressionEvaluationException {
52          session = mock(MavenSession.class);
53          rule = new ReactorModuleConvergence(session);
54          rule.setLog(mock(EnforcerLogger.class));
55      }
56  
57      private void setupSortedProjects(List<MavenProject> projectList) {
58          ProjectDependencyGraph pdg = mock(ProjectDependencyGraph.class);
59          when(session.getProjectDependencyGraph()).thenReturn(pdg);
60          when(pdg.getSortedProjects()).thenReturn(projectList);
61      }
62  
63      @Test
64      void shouldNotFailWithNoProject() throws EnforcerRuleException {
65          setupSortedProjects(Collections.emptyList());
66  
67          rule.execute();
68      }
69  
70      @Test
71      void shouldNotFailWithAValidProject() throws EnforcerRuleException {
72          MavenProject mp1 = createProjectParent();
73          MavenProject mp2 = createProjectChild1(mp1);
74          MavenProject mp3 = createProjectChild2(mp1);
75  
76          List<MavenProject> theList = Arrays.asList(mp1, mp2, mp3);
77          setupSortedProjects(theList);
78  
79          rule.execute();
80      }
81  
82      @Test
83      void shouldFailWithWrongVersionInOneChild() {
84          assertThrows(EnforcerRuleException.class, () -> {
85              MavenProject mp1 = createProjectParent();
86              MavenProject mp2 = createProjectChild1(mp1);
87              MavenProject mp3 = createProjectChild2WithWrongVersion(mp1);
88  
89              List<MavenProject> theList = Arrays.asList(mp1, mp2, mp3);
90              setupSortedProjects(theList);
91  
92              rule.execute();
93  
94              // intentionally no assertTrue() cause we expect getting an exception.
95          });
96  
97          // intentionally no assertTrue() cause we expect getting an exception.
98      }
99  
100     @Test
101     void shouldFailWithWrongParent() {
102         assertThrows(EnforcerRuleException.class, () -> {
103             MavenProject mp1 = createProjectParent();
104 
105             MavenProject wrongParentVerison = mock(MavenProject.class);
106             when(wrongParentVerison.getGroupId()).thenReturn("org.apache.enforcer");
107             when(wrongParentVerison.getArtifactId()).thenReturn("m1");
108             when(wrongParentVerison.getVersion()).thenReturn("1.1-SNAPSHOT");
109             when(wrongParentVerison.getId()).thenReturn("org.apache.enforcer:m1:jar:1.1-SNAPSHOT");
110             when(wrongParentVerison.getDependencies()).thenReturn(Collections.emptyList());
111 
112             MavenProject mp2 = createProjectChild2(wrongParentVerison);
113             MavenProject mp3 = createProjectChild2(mp1);
114 
115             List<MavenProject> theList = Arrays.asList(mp1, mp2, mp3);
116             setupSortedProjects(theList);
117 
118             rule.execute();
119 
120             // intentionally no assertTrue() cause we expect getting an exception.
121         });
122 
123         // intentionally no assertTrue() cause we expect getting an exception.
124     }
125 
126     @Test
127     void shouldNotFailWithACompanyParent() throws EnforcerRuleException {
128         MavenProject companyParent = createCompanyParent();
129         MavenProject mp1 = createProjectParent(companyParent);
130 
131         MavenProject mp2 = createProjectChild1(mp1);
132         MavenProject mp3 = createProjectChild2(mp1);
133 
134         List<MavenProject> theList = Arrays.asList(mp1, mp2, mp3);
135         setupSortedProjects(theList);
136 
137         rule.execute();
138     }
139 
140     @Test
141     void shouldFailWithMissingParentsInReactory() {
142         assertThrows(EnforcerRuleException.class, () -> {
143             MavenProject mp1 = createProjectParent();
144             MavenProject mp2 = createProjectChild1(mp1);
145             MavenProject mp3 = createProjectChild2(null);
146 
147             List<MavenProject> theList = Arrays.asList(mp1, mp2, mp3);
148             setupSortedProjects(theList);
149 
150             rule.execute();
151         });
152     }
153 
154     @Test
155     void shouldFailWithAParentWhichIsNotPartOfTheReactory() {
156         assertThrows(EnforcerRuleException.class, () -> {
157             MavenProject mp1 = createProjectParent();
158 
159             MavenProject wrongParentVerison = mock(MavenProject.class);
160             when(wrongParentVerison.getGroupId()).thenReturn("org.apache");
161             when(wrongParentVerison.getArtifactId()).thenReturn("m1");
162             when(wrongParentVerison.getVersion()).thenReturn("1.0-SNAPSHOT");
163             when(wrongParentVerison.getId()).thenReturn("org.apache.enforcer:m1:jar:1.0-SNAPSHOT");
164             when(wrongParentVerison.getDependencies()).thenReturn(Collections.emptyList());
165 
166             MavenProject mp2 = createProjectChild2(wrongParentVerison);
167             MavenProject mp3 = createProjectChild2(mp1);
168 
169             List<MavenProject> theList = Arrays.asList(mp1, mp2, mp3);
170             setupSortedProjects(theList);
171 
172             rule.execute();
173 
174             // intentionally no assertTrue() cause we expect getting an exception.
175         });
176 
177         // intentionally no assertTrue() cause we expect getting an exception.
178     }
179 
180     @Test
181     void shouldNotFailWithDependencyInReactory() throws EnforcerRuleException {
182         MavenProject mp1 = createProjectParent();
183         MavenProject mp2 = createProjectChild1(mp1);
184 
185         Dependency goodDependency = createDependency("org.junit", "junit", "2.0");
186         List<Dependency> depListMP2 = Arrays.asList(goodDependency);
187         when(mp2.getDependencies()).thenReturn(depListMP2);
188 
189         MavenProject mp3 = createProjectChild2(mp1);
190         Dependency dep1_MP3 = createDependency("org.apache.commons", "commons-io", "1.0.4");
191         List<Dependency> depListMP3 = Arrays.asList(dep1_MP3);
192         when(mp3.getDependencies()).thenReturn(depListMP3);
193 
194         List<MavenProject> theList = Arrays.asList(mp1, mp2, mp3);
195         setupSortedProjects(theList);
196 
197         rule.execute();
198     }
199 
200     @Test
201     void shouldFailWithWrongDependencyInReactor() {
202         assertThrows(EnforcerRuleException.class, () -> {
203             MavenProject mp1 = createProjectParent();
204             MavenProject mp2 = createProjectChild1(mp1);
205 
206             Dependency goodDependency = createDependency("org.junit", "junit", "2.0");
207 
208             Dependency wrongDepFromReactor = createDependency("org.apache.enforcer", "m2", "1.1-SNAPSHOT");
209             List<Dependency> depList = Arrays.asList(goodDependency, wrongDepFromReactor);
210             when(mp2.getDependencies()).thenReturn(depList);
211 
212             MavenProject mp3 = createProjectChild2(mp1);
213 
214             List<MavenProject> theList = Arrays.asList(mp1, mp2, mp3);
215             setupSortedProjects(theList);
216 
217             rule.execute();
218 
219             // intentionally no assertTrue() cause we expect getting an exception.
220         });
221 
222         // intentionally no assertTrue() cause we expect getting an exception.
223     }
224 
225     @Test
226     void cacheIdShouldBeSet() {
227         assertThat(rule.getCacheId()).isNotEmpty();
228     }
229 
230     /**
231      * This small setup is equivalent to the following situation:
232      *
233      * <pre>
234      *  &lt;parent&gt;
235      *    &lt;groupId&gt;...&lt;/groupId&gt;
236      *    &lt;artifactId&gt;...&lt;/artifactId&gt;
237      *    &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
238      *  &lt;/parent&gt;
239      *
240      *  &lt;version&gt;1.1-SNAPSHOT&lt;/version&gt;
241      * </pre>
242      *
243      * @param parent
244      * @return Create MavenProject mock.
245      */
246     private MavenProject createProjectChild2WithWrongVersion(MavenProject parent) {
247         MavenProject mp2 = mock(MavenProject.class);
248         when(mp2.getParent()).thenReturn(parent);
249         when(mp2.getGroupId()).thenReturn("org.apache.enforcer");
250         when(mp2.getArtifactId()).thenReturn("m1");
251         when(mp2.getVersion()).thenReturn("1.1-SNAPSHOT");
252         when(mp2.getId()).thenReturn("org.apache.enforcer:m1:jar:1.1-SNAPSHOT");
253         when(mp2.getDependencies()).thenReturn(Collections.emptyList());
254         return mp2;
255     }
256 
257     private MavenProject createProjectChild2(MavenProject parent) {
258         MavenProject mp3 = mock(MavenProject.class);
259         when(mp3.getParent()).thenReturn(parent);
260         when(mp3.getGroupId()).thenReturn("org.apache.enforcer");
261         when(mp3.getArtifactId()).thenReturn("m2");
262         when(mp3.getVersion()).thenReturn("1.0-SNAPSHOT");
263         when(mp3.getId()).thenReturn("org.apache.enforcer:m2:jar:1.0-SNAPSHOT");
264         when(mp3.getDependencies()).thenReturn(Collections.emptyList());
265         return mp3;
266     }
267 
268     private MavenProject createProjectChild1(MavenProject parent) {
269         MavenProject mp2 = mock(MavenProject.class);
270         when(mp2.getParent()).thenReturn(parent);
271         when(mp2.getGroupId()).thenReturn("org.apache.enforcer");
272         when(mp2.getArtifactId()).thenReturn("m1");
273         when(mp2.getVersion()).thenReturn("1.0-SNAPSHOT");
274         when(mp2.getId()).thenReturn("org.apache.enforcer:m1:jar:1.0-SNAPSHOT");
275         when(mp2.getDependencies()).thenReturn(Collections.emptyList());
276         return mp2;
277     }
278 
279     private MavenProject createCompanyParent() {
280         MavenProject nonReactorParent = mock(MavenProject.class);
281         when(nonReactorParent.getGroupId()).thenReturn("org.apache.enforcer.parent");
282         when(nonReactorParent.getArtifactId()).thenReturn("parent");
283         when(nonReactorParent.getVersion()).thenReturn("1.1");
284         when(nonReactorParent.getId()).thenReturn("org.apache.enforcer.parent:parent:jar:1.1");
285         when(nonReactorParent.getDependencies()).thenReturn(Collections.emptyList());
286         return nonReactorParent;
287     }
288 
289     private MavenProject createProjectParent(MavenProject nonReactorParent) {
290         MavenProject m = createProjectParent();
291         when(m.isExecutionRoot()).thenReturn(true);
292         when(m.getParent()).thenReturn(nonReactorParent);
293         return m;
294     }
295 
296     private MavenProject createProjectParent() {
297         MavenProject mp1 = mock(MavenProject.class);
298         when(mp1.isExecutionRoot()).thenReturn(true);
299         when(mp1.getParent()).thenReturn(null);
300         when(mp1.getGroupId()).thenReturn("org.apache.enforcer");
301         when(mp1.getArtifactId()).thenReturn("parent");
302         when(mp1.getVersion()).thenReturn("1.0-SNAPSHOT");
303         when(mp1.getId()).thenReturn("org.apache.enforcer:parent:pom:1.0-SNAPSHOT");
304         when(mp1.getDependencies()).thenReturn(Collections.emptyList());
305         return mp1;
306     }
307 
308     private Dependency createDependency(String groupId, String artifactId, String version) {
309         Dependency dep = mock(Dependency.class);
310         when(dep.getGroupId()).thenReturn(groupId);
311         when(dep.getArtifactId()).thenReturn(artifactId);
312         when(dep.getVersion()).thenReturn(version);
313         return dep;
314     }
315 }