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