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.plugins.assembly.utils;
20  
21  import java.util.ArrayList;
22  import java.util.Arrays;
23  import java.util.Collections;
24  import java.util.HashSet;
25  import java.util.List;
26  import java.util.Set;
27  
28  import org.apache.maven.artifact.Artifact;
29  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
30  import org.apache.maven.plugins.assembly.InvalidAssemblerConfigurationException;
31  import org.apache.maven.project.MavenProject;
32  import org.hamcrest.Matchers;
33  import org.junit.Test;
34  import org.junit.runner.RunWith;
35  import org.mockito.junit.MockitoJUnitRunner;
36  import org.slf4j.LoggerFactory;
37  
38  import static org.hamcrest.MatcherAssert.assertThat;
39  import static org.junit.Assert.assertEquals;
40  import static org.junit.Assert.assertTrue;
41  import static org.junit.Assert.fail;
42  import static org.mockito.Mockito.*;
43  
44  @RunWith(MockitoJUnitRunner.class)
45  public class FilterUtilsTest {
46  
47      @Test
48      public void testFilterArtifacts_ShouldThrowExceptionUsingStrictModeWithUnmatchedInclude() {
49          final Artifact artifact = mock(Artifact.class);
50          when(artifact.getGroupId()).thenReturn("group");
51          lenient().when(artifact.getArtifactId()).thenReturn("artifact");
52          lenient().when(artifact.getBaseVersion()).thenReturn("version");
53          lenient().when(artifact.getType()).thenReturn("jar");
54  
55          final List<String> includes = new ArrayList<>();
56  
57          includes.add("other.group:other-artifact:type:version");
58  
59          final List<String> excludes = Collections.emptyList();
60  
61          final Set<Artifact> artifacts = new HashSet<>();
62          artifacts.add(artifact);
63  
64          try {
65              FilterUtils.filterArtifacts(
66                      artifacts, includes, excludes, true, false, LoggerFactory.getLogger(getClass()));
67  
68              fail("Should fail because of unmatched include.");
69          } catch (final InvalidAssemblerConfigurationException e) {
70              // expected.
71          }
72      }
73  
74      @Test
75      public void testFilterArtifacts_ShouldNotRemoveArtifactDirectlyIncluded() throws Exception {
76          verifyArtifactInclusion("group", "artifact", "group:artifact", null, null, null);
77          verifyArtifactInclusion("group", "artifact", "group:artifact:jar", null, null, null);
78      }
79  
80      @Test
81      public void testFilterArtifacts_ShouldNotRemoveArtifactTransitivelyIncluded() throws Exception {
82          verifyArtifactInclusion(
83                  "group",
84                  "artifact",
85                  "group:dependentArtifact",
86                  null,
87                  Arrays.asList("current:project:jar:1.0", "group:dependentArtifact:jar:version"),
88                  null);
89      }
90  
91      @Test
92      public void testFilterArtifacts_ShouldRemoveArtifactTransitivelyExcluded() throws Exception {
93          verifyArtifactExclusion(
94                  "group",
95                  "artifact",
96                  null,
97                  "group:dependentArtifact",
98                  Arrays.asList("current:project:jar:1.0", "group:dependentArtifact:jar:version"),
99                  null);
100     }
101 
102     @Test
103     public void testFilterArtifacts_ShouldRemoveArtifactDirectlyExcluded() throws Exception {
104         verifyArtifactExclusion("group", "artifact", null, "group:artifact", null, null);
105         verifyArtifactExclusion("group", "artifact", null, "group:artifact:jar", null, null);
106     }
107 
108     @Test
109     public void testFilterArtifacts_ShouldNotRemoveArtifactNotIncludedAndNotExcluded() throws Exception {
110         verifyArtifactInclusion("group", "artifact", null, null, null, null);
111         verifyArtifactInclusion("group", "artifact", null, null, null, null);
112     }
113 
114     @Test
115     public void testFilterArtifacts_ShouldRemoveArtifactExcludedByAdditionalFilter() throws Exception {
116         final ArtifactFilter filter = new ArtifactFilter() {
117 
118             public boolean include(final Artifact artifact) {
119                 return false;
120             }
121         };
122 
123         verifyArtifactExclusion("group", "artifact", "fail:fail", null, null, filter);
124     }
125 
126     @Test
127     public void testFilterProjects_ShouldNotRemoveProjectDirectlyIncluded() {
128         verifyProjectInclusion("group", "artifact", "group:artifact", null, null);
129         verifyProjectInclusion("group", "artifact", "group:artifact:jar", null, null);
130     }
131 
132     @Test
133     public void testFilterProjects_ShouldNotRemoveProjectTransitivelyIncluded() {
134         verifyProjectInclusion(
135                 "group",
136                 "artifact",
137                 "group:dependentArtifact",
138                 null,
139                 Arrays.asList("current:project:jar:1.0", "group:dependentArtifact:jar:version"));
140     }
141 
142     @Test
143     public void testFilterProjects_ShouldRemoveProjectTransitivelyExcluded() {
144         verifyProjectExclusion(
145                 "group",
146                 "artifact",
147                 null,
148                 "group:dependentArtifact",
149                 Arrays.asList("current:project:jar:1.0", "group:dependentArtifact:jar:version"));
150     }
151 
152     @Test
153     public void testFilterProjects_ShouldRemoveProjectDirectlyExcluded() {
154         verifyProjectExclusion("group", "artifact", null, "group:artifact", null);
155         verifyProjectExclusion("group", "artifact", null, "group:artifact:jar", null);
156     }
157 
158     @Test
159     public void testFilterProjects_ShouldNotRemoveProjectNotIncludedAndNotExcluded() {
160         verifyProjectInclusion("group", "artifact", null, null, null);
161         verifyProjectInclusion("group", "artifact", null, null, null);
162     }
163 
164     @Test
165     public void testTransitiveScopes() {
166         assertThat(
167                 FilterUtils.newScopeFilter("compile").getIncluded(),
168                 Matchers.containsInAnyOrder("compile", "provided", "system"));
169 
170         assertThat(FilterUtils.newScopeFilter("provided").getIncluded(), Matchers.containsInAnyOrder("provided"));
171 
172         assertThat(FilterUtils.newScopeFilter("system").getIncluded(), Matchers.containsInAnyOrder("system"));
173 
174         assertThat(
175                 FilterUtils.newScopeFilter("runtime").getIncluded(), Matchers.containsInAnyOrder("compile", "runtime"));
176 
177         assertThat(
178                 FilterUtils.newScopeFilter("test").getIncluded(),
179                 Matchers.containsInAnyOrder("compile", "provided", "runtime", "system", "test"));
180     }
181 
182     private void verifyArtifactInclusion(
183             final String groupId,
184             final String artifactId,
185             final String inclusionPattern,
186             final String exclusionPattern,
187             final List<String> depTrail,
188             final ArtifactFilter additionalFilter)
189             throws InvalidAssemblerConfigurationException {
190         verifyArtifactFiltering(
191                 groupId, artifactId, inclusionPattern, exclusionPattern, depTrail, true, additionalFilter);
192     }
193 
194     private void verifyArtifactExclusion(
195             final String groupId,
196             final String artifactId,
197             final String inclusionPattern,
198             final String exclusionPattern,
199             final List<String> depTrail,
200             final ArtifactFilter additionalFilter)
201             throws InvalidAssemblerConfigurationException {
202         verifyArtifactFiltering(
203                 groupId, artifactId, inclusionPattern, exclusionPattern, depTrail, false, additionalFilter);
204     }
205 
206     private void verifyArtifactFiltering(
207             final String groupId,
208             final String artifactId,
209             final String inclusionPattern,
210             final String exclusionPattern,
211             final List<String> depTrail,
212             final boolean verifyInclusion,
213             final ArtifactFilter additionalFilter)
214             throws InvalidAssemblerConfigurationException {
215         Artifact artifact = mock(Artifact.class);
216 
217         // this is always enabled, for verification purposes.
218         when(artifact.getDependencyConflictId()).thenReturn(groupId + ":" + artifactId + ":jar");
219         when(artifact.getGroupId()).thenReturn(groupId);
220         when(artifact.getArtifactId()).thenReturn(artifactId);
221         lenient().when(artifact.getBaseVersion()).thenReturn("version");
222         when(artifact.getType()).thenReturn("jar");
223 
224         if (depTrail != null) {
225             when(artifact.getDependencyTrail()).thenReturn(depTrail);
226         }
227 
228         List<String> inclusions;
229         if (inclusionPattern != null) {
230             inclusions = Collections.singletonList(inclusionPattern);
231         } else {
232             inclusions = Collections.emptyList();
233         }
234 
235         List<String> exclusions;
236         if (exclusionPattern != null) {
237             exclusions = Collections.singletonList(exclusionPattern);
238         } else {
239             exclusions = Collections.emptyList();
240         }
241 
242         final Set<Artifact> artifacts = new HashSet<>(Collections.singleton(artifact));
243 
244         FilterUtils.filterArtifacts(
245                 artifacts,
246                 inclusions,
247                 exclusions,
248                 false,
249                 depTrail != null,
250                 LoggerFactory.getLogger(getClass()),
251                 additionalFilter);
252 
253         if (verifyInclusion) {
254             assertEquals(1, artifacts.size());
255             assertEquals(
256                     artifact.getDependencyConflictId(),
257                     artifacts.iterator().next().getDependencyConflictId());
258         } else {
259             // just make sure this trips, to meet the mock's expectations.
260             artifact.getDependencyConflictId();
261 
262             assertTrue(artifacts.isEmpty());
263         }
264     }
265 
266     private void verifyProjectInclusion(
267             final String groupId,
268             final String artifactId,
269             final String inclusionPattern,
270             final String exclusionPattern,
271             final List<String> depTrail) {
272         verifyProjectFiltering(groupId, artifactId, inclusionPattern, exclusionPattern, depTrail, true);
273     }
274 
275     private void verifyProjectExclusion(
276             final String groupId,
277             final String artifactId,
278             final String inclusionPattern,
279             final String exclusionPattern,
280             final List<String> depTrail) {
281         verifyProjectFiltering(groupId, artifactId, inclusionPattern, exclusionPattern, depTrail, false);
282     }
283 
284     private void verifyProjectFiltering(
285             final String groupId,
286             final String artifactId,
287             final String inclusionPattern,
288             final String exclusionPattern,
289             final List<String> depTrail,
290             final boolean verifyInclusion) {
291         final Artifact artifact = mock(Artifact.class);
292 
293         // this is always enabled, for verification purposes.
294         when(artifact.getGroupId()).thenReturn(groupId);
295         when(artifact.getArtifactId()).thenReturn(artifactId);
296         lenient().when(artifact.getBaseVersion()).thenReturn("version");
297         lenient().when(artifact.getType()).thenReturn("jar");
298 
299         if (depTrail != null) {
300             when(artifact.getDependencyTrail()).thenReturn(depTrail);
301         }
302 
303         MavenProject project = mock(MavenProject.class);
304         when(project.getId()).thenReturn("group:artifact:jar:1.0");
305         when(project.getArtifact()).thenReturn(artifact);
306 
307         final Set<MavenProject> projects = new HashSet<>();
308         projects.add(project);
309 
310         List<String> inclusions;
311         if (inclusionPattern != null) {
312             inclusions = Collections.singletonList(inclusionPattern);
313         } else {
314             inclusions = Collections.emptyList();
315         }
316 
317         List<String> exclusions;
318         if (exclusionPattern != null) {
319             exclusions = Collections.singletonList(exclusionPattern);
320         } else {
321             exclusions = Collections.emptyList();
322         }
323 
324         Set<MavenProject> result = FilterUtils.filterProjects(
325                 projects, inclusions, exclusions, depTrail != null, LoggerFactory.getLogger(getClass()));
326 
327         if (verifyInclusion) {
328             assertEquals(1, result.size());
329             assertEquals(project.getId(), result.iterator().next().getId());
330         } else {
331             assertTrue(result.isEmpty());
332         }
333     }
334 }