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.archive.task;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.util.Arrays;
24  import java.util.Collections;
25  import java.util.HashSet;
26  import java.util.Properties;
27  import java.util.Set;
28  
29  import org.apache.maven.artifact.Artifact;
30  import org.apache.maven.artifact.handler.ArtifactHandler;
31  import org.apache.maven.execution.MavenSession;
32  import org.apache.maven.model.Model;
33  import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
34  import org.apache.maven.plugins.assembly.InvalidAssemblerConfigurationException;
35  import org.apache.maven.plugins.assembly.archive.ArchiveCreationException;
36  import org.apache.maven.plugins.assembly.archive.DefaultAssemblyArchiverTest;
37  import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
38  import org.apache.maven.plugins.assembly.model.DependencySet;
39  import org.apache.maven.plugins.assembly.model.UnpackOptions;
40  import org.apache.maven.project.MavenProject;
41  import org.apache.maven.project.ProjectBuilder;
42  import org.apache.maven.project.ProjectBuildingException;
43  import org.apache.maven.project.ProjectBuildingRequest;
44  import org.apache.maven.project.ProjectBuildingResult;
45  import org.codehaus.plexus.archiver.ArchivedFileSet;
46  import org.codehaus.plexus.archiver.Archiver;
47  import org.codehaus.plexus.archiver.ArchiverException;
48  import org.codehaus.plexus.archiver.FileSet;
49  import org.junit.Rule;
50  import org.junit.Test;
51  import org.junit.rules.TemporaryFolder;
52  import org.junit.runner.RunWith;
53  import org.mockito.ArgumentCaptor;
54  import org.mockito.junit.MockitoJUnitRunner;
55  
56  import static org.hamcrest.MatcherAssert.assertThat;
57  import static org.hamcrest.Matchers.is;
58  import static org.junit.Assert.assertEquals;
59  import static org.junit.Assert.assertNotNull;
60  import static org.junit.Assert.assertSame;
61  import static org.mockito.ArgumentMatchers.any;
62  import static org.mockito.ArgumentMatchers.isNull;
63  import static org.mockito.Mockito.atLeastOnce;
64  import static org.mockito.Mockito.mock;
65  import static org.mockito.Mockito.times;
66  import static org.mockito.Mockito.verify;
67  import static org.mockito.Mockito.when;
68  
69  @RunWith(MockitoJUnitRunner.class)
70  public class AddDependencySetsTaskTest {
71      @Rule
72      public TemporaryFolder temporaryFolder = new TemporaryFolder();
73  
74      @Test
75      public void testAddDependencySet_ShouldInterpolateDefaultOutputFileNameMapping() throws Exception {
76          final String outDir = "tmp/";
77          final String mainAid = "main";
78          final String mainGid = "org.maingrp";
79          final String mainVer = "9";
80          final String depAid = "dep";
81          final String depGid = "org.depgrp";
82          final String depVer = "1";
83          final String depExt = "war";
84  
85          final DependencySet ds = new DependencySet();
86          ds.setOutputDirectory(outDir);
87          ds.setDirectoryMode(Integer.toString(10, 8));
88          ds.setFileMode(Integer.toString(10, 8));
89  
90          final Model mainModel = new Model();
91          mainModel.setArtifactId(mainAid);
92          mainModel.setGroupId(mainGid);
93          mainModel.setVersion(mainVer);
94  
95          final MavenProject mainProject = new MavenProject(mainModel);
96  
97          Artifact mainArtifact = mock(Artifact.class);
98          mainProject.setArtifact(mainArtifact);
99  
100         final Model depModel = new Model();
101         depModel.setArtifactId(depAid);
102         depModel.setGroupId(depGid);
103         depModel.setVersion(depVer);
104         depModel.setPackaging(depExt);
105 
106         final MavenProject depProject = new MavenProject(depModel);
107 
108         Artifact depArtifact = mock(Artifact.class);
109         ArtifactHandler artifactHandler = mock(ArtifactHandler.class);
110         when(artifactHandler.getExtension()).thenReturn(depExt);
111         when(depArtifact.getArtifactHandler()).thenReturn(artifactHandler);
112         final File newFile = temporaryFolder.newFile();
113         when(depArtifact.getFile()).thenReturn(newFile);
114         when(depArtifact.getGroupId()).thenReturn("GROUPID");
115 
116         depProject.setArtifact(depArtifact);
117 
118         ProjectBuildingResult pbr = mock(ProjectBuildingResult.class);
119         when(pbr.getProject()).thenReturn(depProject);
120 
121         final ProjectBuilder projectBuilder = mock(ProjectBuilder.class);
122         when(projectBuilder.build(any(Artifact.class), any(ProjectBuildingRequest.class)))
123                 .thenReturn(pbr);
124 
125         final MavenSession session = mock(MavenSession.class);
126         when(session.getProjectBuildingRequest()).thenReturn(mock(ProjectBuildingRequest.class));
127         when(session.getExecutionProperties()).thenReturn(new Properties());
128 
129         final AssemblerConfigurationSource configSource = mock(AssemblerConfigurationSource.class);
130         when(configSource.getFinalName()).thenReturn(mainAid + "-" + mainVer);
131         when(configSource.getProject()).thenReturn(mainProject);
132         when(configSource.getMavenSession()).thenReturn(session);
133 
134         final Archiver archiver = mock(Archiver.class);
135         when(archiver.getDestFile()).thenReturn(new File("junk"));
136         when(archiver.getOverrideDirectoryMode()).thenReturn(0222);
137         when(archiver.getOverrideFileMode()).thenReturn(0222);
138 
139         DefaultAssemblyArchiverTest.setupInterpolators(configSource, mainProject);
140 
141         final AddDependencySetsTask task = new AddDependencySetsTask(
142                 Collections.singletonList(ds), Collections.singleton(depArtifact), depProject, projectBuilder);
143 
144         task.addDependencySet(ds, archiver, configSource);
145 
146         // result of easymock migration, should be assert of expected result instead of verifying methodcalls
147         verify(configSource).getFinalName();
148         verify(configSource, atLeastOnce()).getMavenSession();
149         verify(configSource, atLeastOnce()).getProject();
150 
151         verify(archiver, atLeastOnce()).getDestFile();
152         verify(archiver).addFile(newFile, outDir + depAid + "-" + depVer + "." + depExt, 10);
153         verify(archiver).getOverrideDirectoryMode();
154         verify(archiver).getOverrideFileMode();
155         verify(archiver).setDirectoryMode(10);
156         verify(archiver).setDirectoryMode(146);
157         verify(archiver).setFileMode(10);
158         verify(archiver).setFileMode(146);
159 
160         verify(session).getProjectBuildingRequest();
161         verify(session, times(2)).getExecutionProperties();
162 
163         verify(projectBuilder).build(any(Artifact.class), any(ProjectBuildingRequest.class));
164     }
165 
166     @Test
167     public void testAddDependencySet_ShouldNotAddDependenciesWhenProjectHasNone() throws Exception {
168         final MavenProject project = new MavenProject(new Model());
169 
170         final DependencySet ds = new DependencySet();
171         ds.setOutputDirectory("/out");
172 
173         final AddDependencySetsTask task =
174                 new AddDependencySetsTask(Collections.singletonList(ds), null, project, null);
175 
176         task.addDependencySet(ds, null, null);
177     }
178 
179     // TODO: Find a better way of testing the project-stubbing behavior when a ProjectBuildingException takes place.
180     @Test
181     public void testAddDependencySet_ShouldNotAddDependenciesWhenProjectIsStubbed() throws Exception {
182         final MavenProject project = new MavenProject(new Model());
183 
184         final ProjectBuildingException pbe = new ProjectBuildingException("test", "Test error.", new Throwable());
185 
186         final String aid = "test-dep";
187         final String version = "2.0-SNAPSHOT";
188         final String type = "jar";
189 
190         final File file = new File("dep-artifact.jar");
191 
192         Artifact depArtifact = mock(Artifact.class);
193         when(depArtifact.getGroupId()).thenReturn("GROUPID");
194         when(depArtifact.getArtifactId()).thenReturn(aid);
195         when(depArtifact.getBaseVersion()).thenReturn(version);
196         when(depArtifact.getFile()).thenReturn(file);
197         ArtifactHandler artifactHandler = mock(ArtifactHandler.class);
198         when(artifactHandler.getExtension()).thenReturn(type);
199         when(depArtifact.getArtifactHandler()).thenReturn(artifactHandler);
200 
201         final File destFile = new File("assembly-dep-set.zip");
202 
203         final Archiver archiver = mock(Archiver.class);
204         when(archiver.getDestFile()).thenReturn(destFile);
205         when(archiver.getOverrideDirectoryMode()).thenReturn(0222);
206         when(archiver.getOverrideFileMode()).thenReturn(0222);
207 
208         final ProjectBuilder projectBuilder = mock(ProjectBuilder.class);
209         when(projectBuilder.build(any(Artifact.class), any(ProjectBuildingRequest.class)))
210                 .thenThrow(pbe);
211 
212         final MavenSession session = mock(MavenSession.class);
213         when(session.getProjectBuildingRequest()).thenReturn(mock(ProjectBuildingRequest.class));
214         when(session.getExecutionProperties()).thenReturn(new Properties());
215 
216         final AssemblerConfigurationSource configSource = mock(AssemblerConfigurationSource.class);
217         when(configSource.getFinalName()).thenReturn("final-name");
218         when(configSource.getMavenSession()).thenReturn(session);
219         when(configSource.getProject()).thenReturn(project);
220 
221         final DependencySet ds = new DependencySet();
222         ds.setOutputDirectory("/out");
223         DefaultAssemblyArchiverTest.setupInterpolators(configSource, project);
224 
225         final AddDependencySetsTask task = new AddDependencySetsTask(
226                 Collections.singletonList(ds), Collections.singleton(depArtifact), project, projectBuilder);
227 
228         task.addDependencySet(ds, archiver, configSource);
229 
230         // result of easymock migration, should be assert of expected result instead of verifying methodcalls
231         verify(configSource).getFinalName();
232         verify(configSource, atLeastOnce()).getMavenSession();
233         verify(configSource, atLeastOnce()).getProject();
234 
235         verify(archiver).addFile(file, "out/" + aid + "-" + version + "." + type);
236         verify(archiver, atLeastOnce()).getDestFile();
237         verify(archiver).getOverrideDirectoryMode();
238         verify(archiver).getOverrideFileMode();
239 
240         verify(session).getProjectBuildingRequest();
241         verify(session, times(2)).getExecutionProperties();
242 
243         verify(projectBuilder).build(any(Artifact.class), any(ProjectBuildingRequest.class));
244     }
245 
246     @Test
247     public void testAddDependencySet_ShouldAddOneDependencyFromProjectWithoutUnpacking() throws Exception {
248         verifyOneDependencyAdded("out", false);
249     }
250 
251     @Test
252     public void testAddDependencySet_ShouldAddOneDependencyFromProjectUnpacked() throws Exception {
253         verifyOneDependencyAdded("out", true);
254     }
255 
256     private void verifyOneDependencyAdded(final String outputLocation, final boolean unpack)
257             throws AssemblyFormattingException, ArchiverException, ArchiveCreationException, IOException,
258                     InvalidAssemblerConfigurationException, ProjectBuildingException {
259         final MavenProject project = new MavenProject(new Model());
260 
261         final DependencySet ds = new DependencySet();
262         ds.setOutputDirectory(outputLocation);
263         ds.setOutputFileNameMapping("artifact");
264         ds.setUnpack(unpack);
265         ds.setScope(Artifact.SCOPE_COMPILE);
266 
267         ds.setDirectoryMode(Integer.toString(10, 8));
268         ds.setFileMode(Integer.toString(10, 8));
269 
270         final MavenSession session = mock(MavenSession.class);
271         when(session.getProjectBuildingRequest()).thenReturn(mock(ProjectBuildingRequest.class));
272         when(session.getExecutionProperties()).thenReturn(new Properties());
273 
274         final AssemblerConfigurationSource configSource = mock(AssemblerConfigurationSource.class);
275         when(configSource.getMavenSession()).thenReturn(session);
276         when(configSource.getFinalName()).thenReturn("final-name");
277 
278         Artifact artifact = mock(Artifact.class);
279         final File artifactFile = temporaryFolder.newFile();
280         when(artifact.getFile()).thenReturn(artifactFile);
281         when(artifact.getGroupId()).thenReturn("GROUPID");
282 
283         final Archiver archiver = mock(Archiver.class);
284         when(archiver.getDestFile()).thenReturn(new File("junk"));
285         when(archiver.getOverrideDirectoryMode()).thenReturn(0222);
286         when(archiver.getOverrideFileMode()).thenReturn(0222);
287 
288         if (!unpack) {
289             when(configSource.getProject()).thenReturn(project);
290         }
291 
292         final MavenProject depProject = new MavenProject(new Model());
293         depProject.setGroupId("GROUPID");
294 
295         ProjectBuildingResult pbr = mock(ProjectBuildingResult.class);
296         when(pbr.getProject()).thenReturn(depProject);
297 
298         final ProjectBuilder projectBuilder = mock(ProjectBuilder.class);
299         when(projectBuilder.build(any(Artifact.class), any(ProjectBuildingRequest.class)))
300                 .thenReturn(pbr);
301 
302         final AddDependencySetsTask task = new AddDependencySetsTask(
303                 Collections.singletonList(ds), Collections.singleton(artifact), project, projectBuilder);
304         DefaultAssemblyArchiverTest.setupInterpolators(configSource, project);
305 
306         task.addDependencySet(ds, archiver, configSource);
307 
308         // result of easymock migration, should be assert of expected result instead of verifying methodcalls
309         verify(configSource).getFinalName();
310         verify(configSource, atLeastOnce()).getMavenSession();
311 
312         verify(archiver, atLeastOnce()).getDestFile();
313         verify(archiver).getOverrideDirectoryMode();
314         verify(archiver).getOverrideFileMode();
315         verify(archiver).setFileMode(10);
316         verify(archiver).setFileMode(146);
317         verify(archiver).setDirectoryMode(10);
318         verify(archiver).setDirectoryMode(146);
319 
320         verify(session).getProjectBuildingRequest();
321         verify(session, atLeastOnce()).getExecutionProperties();
322 
323         verify(projectBuilder).build(any(Artifact.class), any(ProjectBuildingRequest.class));
324 
325         if (unpack) {
326             verify(archiver).addArchivedFileSet(any(ArchivedFileSet.class), isNull());
327         } else {
328             verify(archiver).addFile(artifactFile, outputLocation + "/artifact", 10);
329             verify(configSource, atLeastOnce()).getProject();
330         }
331     }
332 
333     @Test
334     public void testGetDependencyArtifacts_ShouldGetOneDependencyArtifact() throws Exception {
335         final MavenProject project = new MavenProject(new Model());
336 
337         Artifact artifact = mock(Artifact.class);
338         project.setArtifacts(Collections.singleton(artifact));
339 
340         final DependencySet dependencySet = new DependencySet();
341 
342         final AddDependencySetsTask task = new AddDependencySetsTask(
343                 Collections.singletonList(dependencySet), Collections.singleton(artifact), project, null);
344 
345         final Set<Artifact> result = task.resolveDependencyArtifacts(dependencySet);
346 
347         assertNotNull(result);
348         assertEquals(1, result.size());
349         assertSame(artifact, result.iterator().next());
350     }
351 
352     @Test
353     public void testGetDependencyArtifacts_ShouldFilterOneDependencyArtifactViaInclude() throws Exception {
354         final MavenProject project = new MavenProject(new Model());
355 
356         final Set<Artifact> artifacts = new HashSet<>();
357 
358         Artifact am1 = mock(Artifact.class);
359         when(am1.getGroupId()).thenReturn("group");
360         when(am1.getArtifactId()).thenReturn("artifact");
361         artifacts.add(am1);
362 
363         Artifact am2 = mock(Artifact.class);
364         when(am2.getGroupId()).thenReturn("group2");
365         when(am2.getId()).thenReturn("group2:artifact2:1.0:jar");
366         artifacts.add(am2);
367 
368         final DependencySet dependencySet = new DependencySet();
369 
370         dependencySet.addInclude("group:artifact");
371         dependencySet.setUseTransitiveFiltering(true);
372 
373         final AddDependencySetsTask task =
374                 new AddDependencySetsTask(Collections.singletonList(dependencySet), artifacts, project, null);
375 
376         final Set<Artifact> result = task.resolveDependencyArtifacts(dependencySet);
377 
378         assertNotNull(result);
379         assertEquals(1, result.size());
380         assertSame(am1, result.iterator().next());
381     }
382 
383     @Test
384     public void testGetDependencyArtifacts_ShouldIgnoreTransitivePathFilteringWhenIncludeNotTransitive()
385             throws Exception {
386         final MavenProject project = new MavenProject(new Model());
387 
388         final Set<Artifact> artifacts = new HashSet<>();
389 
390         Artifact am1 = mock(Artifact.class);
391         when(am1.getGroupId()).thenReturn("group");
392         when(am1.getArtifactId()).thenReturn("artifact");
393         artifacts.add(am1);
394 
395         Artifact am2 = mock(Artifact.class);
396         when(am2.getGroupId()).thenReturn("group2");
397         when(am2.getId()).thenReturn("group2:artifact2:1.0:jar");
398         artifacts.add(am2);
399 
400         final DependencySet dependencySet = new DependencySet();
401 
402         dependencySet.addInclude("group:artifact");
403         dependencySet.setUseTransitiveFiltering(false);
404 
405         final AddDependencySetsTask task =
406                 new AddDependencySetsTask(Collections.singletonList(dependencySet), artifacts, project, null);
407 
408         final Set<Artifact> result = task.resolveDependencyArtifacts(dependencySet);
409 
410         assertNotNull(result);
411         assertEquals(1, result.size());
412         assertSame(am1, result.iterator().next());
413     }
414 
415     // MASSEMBLY-879
416     @Test
417     public void useDefaultExcludes() throws Exception {
418         Artifact zipArtifact = mock(Artifact.class);
419         when(zipArtifact.getGroupId()).thenReturn("some-artifact");
420         when(zipArtifact.getArtifactId()).thenReturn("of-type-zip");
421         when(zipArtifact.getId()).thenReturn("some-artifact:of-type-zip:1.0:zip");
422         when(zipArtifact.getFile()).thenReturn(temporaryFolder.newFile("of-type-zip.zip"));
423 
424         Artifact dirArtifact = mock(Artifact.class);
425         when(dirArtifact.getGroupId()).thenReturn("some-artifact");
426         when(dirArtifact.getArtifactId()).thenReturn("of-type-zip");
427         when(dirArtifact.getId()).thenReturn("some-artifact:of-type-zip:1.0:dir");
428         when(dirArtifact.getFile()).thenReturn(temporaryFolder.newFolder("of-type-zip"));
429 
430         final Set<Artifact> artifacts = new HashSet<>(Arrays.asList(zipArtifact, dirArtifact));
431 
432         final DependencySet dependencySet = new DependencySet();
433         dependencySet.setUseProjectArtifact(false);
434         dependencySet.setIncludes(Collections.singletonList("some-artifact:of-type-zip"));
435         dependencySet.setOutputDirectory("MyOutputDir");
436         dependencySet.setUnpack(true);
437         UnpackOptions unpackOptions = new UnpackOptions();
438         unpackOptions.setUseDefaultExcludes(false);
439         dependencySet.setUnpackOptions(unpackOptions);
440 
441         final MavenProject project = new MavenProject(new Model());
442         project.setGroupId("GROUPID");
443 
444         ProjectBuildingRequest pbReq = mock(ProjectBuildingRequest.class);
445         ProjectBuildingResult pbRes = mock(ProjectBuildingResult.class);
446         when(pbRes.getProject()).thenReturn(project);
447 
448         final ProjectBuilder projectBuilder = mock(ProjectBuilder.class);
449         when(projectBuilder.build(any(Artifact.class), any(ProjectBuildingRequest.class)))
450                 .thenReturn(pbRes);
451 
452         final AddDependencySetsTask task =
453                 new AddDependencySetsTask(Collections.singletonList(dependencySet), artifacts, project, projectBuilder);
454 
455         final MavenSession session = mock(MavenSession.class);
456         when(session.getProjectBuildingRequest()).thenReturn(pbReq);
457 
458         final AssemblerConfigurationSource configSource = mock(AssemblerConfigurationSource.class);
459         when(configSource.getMavenSession()).thenReturn(session);
460         DefaultAssemblyArchiverTest.setupInterpolators(configSource, project);
461 
462         final Archiver archiver = mock(Archiver.class);
463 
464         task.addDependencySet(dependencySet, archiver, configSource);
465 
466         ArgumentCaptor<ArchivedFileSet> archivedFileSet = ArgumentCaptor.forClass(ArchivedFileSet.class);
467         verify(archiver).addArchivedFileSet(archivedFileSet.capture(), isNull());
468         assertThat(archivedFileSet.getValue().isUsingDefaultExcludes(), is(false));
469 
470         ArgumentCaptor<FileSet> fileSet = ArgumentCaptor.forClass(FileSet.class);
471         verify(archiver).addFileSet(fileSet.capture());
472         assertThat(fileSet.getValue().isUsingDefaultExcludes(), is(false));
473     }
474 }