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