1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.dependency.exclusion;
20
21 import java.io.File;
22 import java.io.PrintWriter;
23 import java.io.StringWriter;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.HashSet;
28 import java.util.List;
29
30 import org.apache.maven.RepositoryUtils;
31 import org.apache.maven.artifact.Artifact;
32 import org.apache.maven.execution.MavenSession;
33 import org.apache.maven.model.Dependency;
34 import org.apache.maven.model.Exclusion;
35 import org.apache.maven.model.InputLocation;
36 import org.apache.maven.model.InputSource;
37 import org.apache.maven.plugin.MojoExecutionException;
38 import org.apache.maven.plugin.logging.Log;
39 import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase;
40 import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub;
41 import org.apache.maven.plugins.dependency.utils.ResolverUtil;
42 import org.apache.maven.project.MavenProject;
43
44 import static org.assertj.core.api.Assertions.assertThat;
45 import static org.assertj.core.api.Assertions.assertThatCode;
46 import static org.assertj.core.api.Assertions.assertThatThrownBy;
47 import static org.mockito.ArgumentMatchers.any;
48 import static org.mockito.Mockito.mock;
49 import static org.mockito.Mockito.when;
50
51 public class AnalyzeExclusionsMojoTest extends AbstractDependencyMojoTestCase {
52
53 private AnalyzeExclusionsMojo mojo;
54
55 private MavenProject project;
56
57 private TestLog testLog;
58
59 private ResolverUtil resolverUtil;
60
61 @Override
62 protected String getTestDirectoryName() {
63 return "analyze-exclusions";
64 }
65
66 @Override
67 protected boolean shouldCreateFiles() {
68 return true;
69 }
70
71 @Override
72 protected boolean shouldUseFlattenedPath() {
73 return false;
74 }
75
76 @Override
77 protected void setUp() throws Exception {
78
79 super.setUp();
80
81 project = new DependencyProjectStub();
82 project.setName("projectName");
83 project.setGroupId("testGroupId");
84 project.setArtifactId("testArtifactId");
85 project.setVersion("1.0.0");
86
87 getContainer().addComponent(project, MavenProject.class.getName());
88
89 MavenSession session = newMavenSession(project);
90 getContainer().addComponent(session, MavenSession.class.getName());
91
92 resolverUtil = mock(ResolverUtil.class);
93 getContainer().addComponent(resolverUtil, ResolverUtil.class.getName());
94
95 File testPom = new File(getBasedir(), "target/test-classes/unit/analyze-exclusions/plugin-config.xml");
96 mojo = (AnalyzeExclusionsMojo) lookupMojo("analyze-exclusions", testPom);
97 assertNotNull(mojo);
98
99 testLog = new TestLog();
100 mojo.setLog(testLog);
101 }
102
103 public void testShallThrowExceptionWhenFailOnWarning() throws Exception {
104 List<Dependency> dependencies = new ArrayList<>();
105 Dependency withInvalidExclusion = dependency("a", "b");
106 withInvalidExclusion.addExclusion(exclusion("invalid", "invalid"));
107 dependencies.add(withInvalidExclusion);
108 project.setDependencies(dependencies);
109 Artifact artifact = stubFactory.createArtifact("a", "b", "1.0");
110 project.setArtifacts(new HashSet<>(Collections.singletonList(artifact)));
111 setVariableValueToObject(mojo, "exclusionFail", true);
112
113 assertThatThrownBy(() -> mojo.execute())
114 .isInstanceOf(MojoExecutionException.class)
115 .hasMessageContaining("Invalid exclusions found");
116
117 assertThat(testLog.getContent()).startsWith("[error]");
118 }
119
120 public void testShallLogWarningWhenFailOnWarningIsFalse() throws Exception {
121 List<Dependency> dependencies = new ArrayList<>();
122 Dependency withInvalidExclusion = dependency("a", "b");
123 withInvalidExclusion.addExclusion(exclusion("invalid", "invalid"));
124 dependencies.add(withInvalidExclusion);
125 project.setDependencies(dependencies);
126 Artifact artifact = stubFactory.createArtifact("a", "b", "1.0");
127 project.setArtifacts(new HashSet<>(Collections.singletonList(artifact)));
128 setVariableValueToObject(mojo, "exclusionFail", false);
129
130 mojo.execute();
131
132 assertThat(testLog.getContent()).startsWith("[warn]");
133 }
134
135 public void testShallExitWithoutAnalyzeWhenNoDependencyHasExclusion() throws Exception {
136 List<Dependency> dependencies = new ArrayList<>();
137 dependencies.add(dependency("a", "c"));
138 project.setDependencies(dependencies);
139 mojo.execute();
140 assertThat(testLog.getContent()).startsWith("[debug] No dependencies defined with exclusions - exiting");
141 }
142
143 public void testShallNotReportInvalidExclusionForWildcardGroupIdAndArtifactId() throws Exception {
144 Dependency dependencyWithWildcardExclusion = dependency("a", "b");
145 dependencyWithWildcardExclusion.addExclusion(exclusion("*", "*"));
146 project.setDependencies(Collections.singletonList(dependencyWithWildcardExclusion));
147 Artifact artifact = stubFactory.createArtifact("a", "b", "1.0");
148 project.setArtifacts(new HashSet<>(Collections.singletonList(artifact)));
149
150 when(resolverUtil.collectDependencies(any()))
151 .thenReturn(Collections.singletonList(new org.eclipse.aether.graph.Dependency(
152 RepositoryUtils.toArtifact(stubFactory.createArtifact("whatever", "ok", "1.0")), "")));
153
154 mojo.execute();
155
156 assertThat(testLog.getContent()).doesNotContain("[warn] a:b:", "[warn] - *:*");
157 }
158
159 public void testCanResolveMultipleArtifactsWithEqualGroupIdAndArtifactId() throws Exception {
160 Dependency dependency1 = dependency("a", "b");
161 Dependency dependency2 = dependency("a", "b", "compile", "native");
162 dependency1.addExclusion(exclusion("c", "d"));
163 dependency2.addExclusion(exclusion("c", "d"));
164 project.setDependencies(Arrays.asList(dependency1, dependency2));
165 Artifact artifact1 = stubFactory.createArtifact("a", "b", "1.0");
166 Artifact artifact2 = stubFactory.createArtifact("a", "b", "1.0", "compile", "jar", "native");
167 project.setArtifacts(new HashSet<>(Arrays.asList(artifact1, artifact2)));
168
169 assertThatCode(() -> mojo.execute()).doesNotThrowAnyException();
170 }
171
172 public void testShallNotLogWhenExclusionIsValid() throws Exception {
173 List<Dependency> dependencies = new ArrayList<>();
174 Dependency dependency = dependency("a", "b");
175 dependency.addExclusion(exclusion("ok", "ok"));
176 dependencies.add(dependency);
177 project.setDependencies(dependencies);
178 Artifact artifact = stubFactory.createArtifact("a", "b", "1.0");
179
180 project.setArtifacts(new HashSet<>(Collections.singletonList(artifact)));
181 setVariableValueToObject(mojo, "exclusionFail", true);
182
183 when(resolverUtil.collectDependencies(any()))
184 .thenReturn(Collections.singletonList(new org.eclipse.aether.graph.Dependency(
185 RepositoryUtils.toArtifact(stubFactory.createArtifact("ok", "ok", "1.0")), "")));
186
187 assertThatCode(() -> mojo.execute()).doesNotThrowAnyException();
188 }
189
190 public void testThatLogContainProjectName() throws Exception {
191 List<Dependency> dependencies = new ArrayList<>();
192 Dependency withInvalidExclusion = dependency("a", "b");
193 withInvalidExclusion.addExclusion(exclusion("invalid", "invalid"));
194 dependencies.add(withInvalidExclusion);
195 project.setDependencies(dependencies);
196 Artifact artifact = stubFactory.createArtifact("a", "b", "1.0");
197 project.setArtifacts(new HashSet<>(Collections.singletonList(artifact)));
198
199 mojo.execute();
200
201 assertThat(testLog.getContent()).contains("[warn] projectName defines following unnecessary excludes");
202 }
203
204 private Dependency dependency(String groupId, String artifactId) {
205 Dependency dependency = new Dependency();
206 dependency.setGroupId(groupId);
207 dependency.setArtifactId(artifactId);
208 dependency.setVersion("1.0");
209 dependency.setScope("compile");
210 dependency.setType("jar");
211 dependency.setClassifier("");
212 dependency.setLocation("", new InputLocation(1, 1));
213 return dependency;
214 }
215
216 private Dependency dependency(String groupId, String artifactId, String scope, String classifier) {
217 Dependency dependency = new Dependency();
218 dependency.setGroupId(groupId);
219 dependency.setArtifactId(artifactId);
220 dependency.setVersion("1.0");
221 dependency.setScope(scope);
222 dependency.setType("jar");
223 dependency.setClassifier(classifier);
224 dependency.setLocation("", new InputLocation(1, 1));
225 return dependency;
226 }
227
228 private Exclusion exclusion(String groupId, String artifactId) {
229 Exclusion exclusion = new Exclusion();
230 exclusion.setGroupId(groupId);
231 exclusion.setArtifactId(artifactId);
232 InputSource inputSource = new InputSource();
233 inputSource.setModelId("testGroupId:testArtifactId:1.0.0");
234 exclusion.setLocation("", new InputLocation(1, 1, inputSource));
235 return exclusion;
236 }
237
238 static class TestLog implements Log {
239 StringBuilder sb = new StringBuilder();
240
241
242
243
244 @Override
245 public void debug(CharSequence content) {
246 print("debug", content);
247 }
248
249
250
251
252 @Override
253 public void debug(CharSequence content, Throwable error) {
254 print("debug", content, error);
255 }
256
257
258
259
260 @Override
261 public void debug(Throwable error) {
262 print("debug", error);
263 }
264
265
266
267
268 @Override
269 public void info(CharSequence content) {
270 print("info", content);
271 }
272
273
274
275
276 @Override
277 public void info(CharSequence content, Throwable error) {
278 print("info", content, error);
279 }
280
281
282
283
284 @Override
285 public void info(Throwable error) {
286 print("info", error);
287 }
288
289
290
291
292 @Override
293 public void warn(CharSequence content) {
294 print("warn", content);
295 }
296
297
298
299
300 @Override
301 public void warn(CharSequence content, Throwable error) {
302 print("warn", content, error);
303 }
304
305
306
307
308 @Override
309 public void warn(Throwable error) {
310 print("warn", error);
311 }
312
313
314
315
316 @Override
317 public void error(CharSequence content) {
318 print("error", content);
319 }
320
321
322
323
324 @Override
325 public void error(CharSequence content, Throwable error) {
326 StringWriter sWriter = new StringWriter();
327 PrintWriter pWriter = new PrintWriter(sWriter);
328
329 error.printStackTrace(pWriter);
330
331 System.err.println(
332 "[error] " + content.toString() + System.lineSeparator() + System.lineSeparator() + sWriter);
333 }
334
335
336
337
338 @Override
339 public void error(Throwable error) {
340 StringWriter sWriter = new StringWriter();
341 PrintWriter pWriter = new PrintWriter(sWriter);
342
343 error.printStackTrace(pWriter);
344
345 System.err.println("[error] " + sWriter);
346 }
347
348
349
350
351 @Override
352 public boolean isDebugEnabled() {
353 return false;
354 }
355
356
357
358
359 @Override
360 public boolean isInfoEnabled() {
361 return true;
362 }
363
364
365
366
367 @Override
368 public boolean isWarnEnabled() {
369 return true;
370 }
371
372
373
374
375 @Override
376 public boolean isErrorEnabled() {
377 return true;
378 }
379
380 private void print(String prefix, CharSequence content) {
381 sb.append("[")
382 .append(prefix)
383 .append("] ")
384 .append(content.toString())
385 .append(System.lineSeparator());
386 }
387
388 private void print(String prefix, Throwable error) {
389 StringWriter sWriter = new StringWriter();
390 PrintWriter pWriter = new PrintWriter(sWriter);
391
392 error.printStackTrace(pWriter);
393
394 sb.append("[").append(prefix).append("] ").append(sWriter).append(System.lineSeparator());
395 }
396
397 private void print(String prefix, CharSequence content, Throwable error) {
398 StringWriter sWriter = new StringWriter();
399 PrintWriter pWriter = new PrintWriter(sWriter);
400
401 error.printStackTrace(pWriter);
402
403 sb.append("[")
404 .append(prefix)
405 .append("] ")
406 .append(content.toString())
407 .append(System.lineSeparator())
408 .append(System.lineSeparator());
409 sb.append(sWriter).append(System.lineSeparator());
410 }
411
412 protected String getContent() {
413 return sb.toString();
414 }
415 }
416 }