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