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 javax.inject.Inject;
22
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Collections;
26 import java.util.List;
27
28 import org.apache.maven.api.di.Provides;
29 import org.apache.maven.api.plugin.testing.InjectMojo;
30 import org.apache.maven.api.plugin.testing.MojoParameter;
31 import org.apache.maven.api.plugin.testing.MojoTest;
32 import org.apache.maven.execution.MavenSession;
33 import org.apache.maven.model.Dependency;
34 import org.apache.maven.model.DependencyManagement;
35 import org.apache.maven.model.Exclusion;
36 import org.apache.maven.model.InputLocation;
37 import org.apache.maven.model.InputSource;
38 import org.apache.maven.plugin.MojoExecutionException;
39 import org.apache.maven.plugin.logging.Log;
40 import org.apache.maven.plugins.dependency.utils.ResolverUtil;
41 import org.apache.maven.project.MavenProject;
42 import org.eclipse.aether.DefaultRepositorySystemSession;
43 import org.eclipse.aether.artifact.DefaultArtifact;
44 import org.junit.jupiter.api.BeforeEach;
45 import org.junit.jupiter.api.Test;
46 import org.junit.jupiter.api.extension.ExtendWith;
47 import org.mockito.Mock;
48 import org.mockito.junit.jupiter.MockitoExtension;
49
50 import static org.assertj.core.api.Assertions.assertThatCode;
51 import static org.assertj.core.api.Assertions.assertThatThrownBy;
52 import static org.mockito.ArgumentMatchers.any;
53 import static org.mockito.ArgumentMatchers.anyString;
54 import static org.mockito.Mockito.lenient;
55 import static org.mockito.Mockito.mock;
56 import static org.mockito.Mockito.never;
57 import static org.mockito.Mockito.times;
58 import static org.mockito.Mockito.verify;
59 import static org.mockito.Mockito.when;
60
61 @ExtendWith(MockitoExtension.class)
62 @MojoTest
63 class AnalyzeExclusionsMojoTest {
64
65 @Inject
66 private MavenProject project;
67
68 @Inject
69 private MavenSession mavenSession;
70
71 @Inject
72 private Log testLog;
73
74 @Mock
75 private ResolverUtil resolverUtil;
76
77 @Provides
78 private ResolverUtil resolverUtilProvides() {
79 return resolverUtil;
80 }
81
82 @BeforeEach
83 void setUp() {
84 when(project.getGroupId()).thenReturn("testGroupId");
85 when(project.getArtifactId()).thenReturn("testArtifactId");
86 when(project.getVersion()).thenReturn("1.0.0");
87
88 DependencyManagement dependencyManagement = mock(DependencyManagement.class);
89 when(dependencyManagement.getDependencies()).thenReturn(Collections.emptyList());
90 when(project.getDependencyManagement()).thenReturn(dependencyManagement);
91
92 lenient().when(mavenSession.getRepositorySession()).thenReturn(new DefaultRepositorySystemSession());
93 }
94
95 @Test
96 @InjectMojo(goal = "analyze-exclusions")
97 @MojoParameter(name = "exclusionFail", value = "true")
98 void testShallThrowExceptionWhenFailOnWarning(AnalyzeExclusionsMojo mojo) {
99 List<Dependency> dependencies = new ArrayList<>();
100 Dependency withInvalidExclusion = dependency("a", "b");
101 withInvalidExclusion.addExclusion(exclusion("invalid", "invalid"));
102 dependencies.add(withInvalidExclusion);
103 when(project.getDependencies()).thenReturn(dependencies);
104
105 assertThatThrownBy(mojo::execute)
106 .isInstanceOf(MojoExecutionException.class)
107 .hasMessageContaining("Invalid exclusions found");
108
109 verify(testLog, times(3)).error(anyString());
110 }
111
112 @Test
113 @InjectMojo(goal = "analyze-exclusions")
114 @MojoParameter(name = "exclusionFail", value = "false")
115 void testShallLogWarningWhenFailOnWarningIsFalse(AnalyzeExclusionsMojo mojo) throws Exception {
116 List<Dependency> dependencies = new ArrayList<>();
117 Dependency withInvalidExclusion = dependency("a", "b");
118 withInvalidExclusion.addExclusion(exclusion("invalid", "invalid"));
119 dependencies.add(withInvalidExclusion);
120 when(project.getDependencies()).thenReturn(dependencies);
121
122 mojo.execute();
123
124 verify(testLog, times(3)).warn(anyString());
125 }
126
127 @Test
128 @InjectMojo(goal = "analyze-exclusions")
129 void testShallExitWithoutAnalyzeWhenNoDependencyHasExclusion(AnalyzeExclusionsMojo mojo) throws Exception {
130 List<Dependency> dependencies = new ArrayList<>();
131 dependencies.add(dependency("a", "c"));
132 when(project.getDependencies()).thenReturn(dependencies);
133
134 mojo.execute();
135 verify(testLog).debug("No dependencies defined with exclusions - exiting");
136 }
137
138 @Test
139 @InjectMojo(goal = "analyze-exclusions")
140 void testShallNotReportInvalidExclusionForWildcardGroupIdAndArtifactId(AnalyzeExclusionsMojo mojo)
141 throws Exception {
142 Dependency dependencyWithWildcardExclusion = dependency("a", "b");
143 dependencyWithWildcardExclusion.addExclusion(exclusion("*", "*"));
144 when(project.getDependencies()).thenReturn(Collections.singletonList(dependencyWithWildcardExclusion));
145
146 when(resolverUtil.collectDependencies(any()))
147 .thenReturn(Collections.singletonList(new org.eclipse.aether.graph.Dependency(
148 new DefaultArtifact("whatever", "ok", "jar", "1.0"), "")));
149
150 mojo.execute();
151 verify(testLog, never()).warn(anyString());
152 }
153
154 @Test
155 @InjectMojo(goal = "analyze-exclusions")
156 void testCanResolveMultipleArtifactsWithEqualGroupIdAndArtifactId(AnalyzeExclusionsMojo mojo) {
157 Dependency dependency1 = dependency("a", "b");
158 Dependency dependency2 = dependency("a", "b", "compile", "native");
159 dependency1.addExclusion(exclusion("c", "d"));
160 dependency2.addExclusion(exclusion("c", "d"));
161 when(project.getDependencies()).thenReturn(Arrays.asList(dependency1, dependency2));
162
163 assertThatCode(mojo::execute).doesNotThrowAnyException();
164 }
165
166 @Test
167 @InjectMojo(goal = "analyze-exclusions")
168 void testShallNotLogWhenExclusionIsValid(AnalyzeExclusionsMojo mojo) throws Exception {
169 List<Dependency> dependencies = new ArrayList<>();
170 Dependency dependency = dependency("a", "b");
171 dependency.addExclusion(exclusion("ok", "ok"));
172 dependencies.add(dependency);
173 when(project.getDependencies()).thenReturn(dependencies);
174
175 when(resolverUtil.collectDependencies(any()))
176 .thenReturn(Collections.singletonList(
177 new org.eclipse.aether.graph.Dependency(new DefaultArtifact("ok", "ok", "jar", "1.0"), "")));
178
179 assertThatCode(mojo::execute).doesNotThrowAnyException();
180
181 verify(testLog, never()).warn(anyString());
182 }
183
184 @Test
185 @InjectMojo(goal = "analyze-exclusions")
186 void testThatLogContainProjectName(AnalyzeExclusionsMojo mojo) throws Exception {
187 List<Dependency> dependencies = new ArrayList<>();
188 Dependency withInvalidExclusion = dependency("a", "b");
189 withInvalidExclusion.addExclusion(exclusion("invalid", "invalid"));
190 dependencies.add(withInvalidExclusion);
191 when(project.getDependencies()).thenReturn(dependencies);
192
193 when(project.getName()).thenReturn("projectName");
194
195 mojo.execute();
196
197 verify(testLog).warn("projectName defines following unnecessary excludes");
198 }
199
200 private Dependency dependency(String groupId, String artifactId) {
201 Dependency dependency = new Dependency();
202 dependency.setGroupId(groupId);
203 dependency.setArtifactId(artifactId);
204 dependency.setVersion("1.0");
205 dependency.setScope("compile");
206 dependency.setType("jar");
207 dependency.setClassifier("");
208 dependency.setLocation("", new InputLocation(1, 1));
209 return dependency;
210 }
211
212 private Dependency dependency(String groupId, String artifactId, String scope, String classifier) {
213 Dependency dependency = new Dependency();
214 dependency.setGroupId(groupId);
215 dependency.setArtifactId(artifactId);
216 dependency.setVersion("1.0");
217 dependency.setScope(scope);
218 dependency.setType("jar");
219 dependency.setClassifier(classifier);
220 dependency.setLocation("", new InputLocation(1, 1));
221 return dependency;
222 }
223
224 private Exclusion exclusion(String groupId, String artifactId) {
225 Exclusion exclusion = new Exclusion();
226 exclusion.setGroupId(groupId);
227 exclusion.setArtifactId(artifactId);
228 InputSource inputSource = new InputSource();
229 inputSource.setModelId("testGroupId:testArtifactId:1.0.0");
230 exclusion.setLocation("", new InputLocation(1, 1, inputSource));
231 return exclusion;
232 }
233 }