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