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.dependency.fromConfiguration;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.nio.file.Files;
24  import java.util.ArrayList;
25  import java.util.Collection;
26  import java.util.Collections;
27  import java.util.List;
28  
29  import org.apache.maven.artifact.Artifact;
30  import org.apache.maven.artifact.versioning.VersionRange;
31  import org.apache.maven.execution.MavenSession;
32  import org.apache.maven.model.Dependency;
33  import org.apache.maven.plugin.LegacySupport;
34  import org.apache.maven.plugin.MojoExecutionException;
35  import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase;
36  import org.apache.maven.plugins.dependency.testUtils.DependencyArtifactStubFactory;
37  import org.apache.maven.plugins.dependency.utils.markers.UnpackFileMarkerHandler;
38  import org.apache.maven.project.MavenProject;
39  import org.codehaus.plexus.archiver.manager.ArchiverManager;
40  
41  public class TestUnpackMojo extends AbstractDependencyMojoTestCase {
42  
43      UnpackMojo mojo;
44  
45      protected void setUp() throws Exception {
46          super.setUp("unpack", true, false);
47  
48          File testPom = new File(getBasedir(), "target/test-classes/unit/unpack-test/plugin-config.xml");
49          mojo = (UnpackMojo) lookupMojo("unpack", testPom);
50          mojo.setOutputDirectory(new File(this.testDir, "outputDirectory"));
51          mojo.setMarkersDirectory(new File(this.testDir, "markers"));
52          mojo.setSilent(true);
53  
54          assertNotNull(mojo);
55          assertNotNull(mojo.getProject());
56          // MavenProject project = mojo.getProject();
57          // init classifier things
58          // it needs to get the archivermanager
59          stubFactory.setUnpackableFile(lookup(ArchiverManager.class));
60          // i'm using one file repeatedly to archive so I can test the name
61          // programmatically.
62          stubFactory.setSrcFile(new File(
63                  getBasedir() + File.separatorChar + "target/test-classes/unit/unpack-dependencies-test/test.txt"));
64  
65          MavenSession session = newMavenSession(mojo.getProject());
66          setVariableValueToObject(mojo, "session", session);
67  
68          LegacySupport legacySupport = lookup(LegacySupport.class);
69  
70          legacySupport.setSession(session);
71          installLocalRepository(legacySupport);
72      }
73  
74      public ArtifactItem getSingleArtifactItem(boolean removeVersion) throws MojoExecutionException {
75          List<ArtifactItem> list = mojo.getProcessedArtifactItems(removeVersion);
76          return list.get(0);
77      }
78  
79      public void testGetArtifactItems() throws Exception {
80  
81          ArtifactItem item = new ArtifactItem();
82  
83          item.setArtifactId("artifact");
84          item.setGroupId("groupId");
85          item.setVersion("1.0");
86  
87          ArrayList<ArtifactItem> list = new ArrayList<>(1);
88          list.add(createArtifact(item));
89  
90          mojo.setArtifactItems(list);
91  
92          ArtifactItem result = getSingleArtifactItem(false);
93          assertEquals(mojo.getOutputDirectory(), result.getOutputDirectory());
94  
95          File output = new File(mojo.getOutputDirectory(), "override");
96          item.setOutputDirectory(output);
97          result = getSingleArtifactItem(false);
98          assertEquals(output, result.getOutputDirectory());
99      }
100 
101     public void assertMarkerFiles(Collection<ArtifactItem> items, boolean exist) {
102         for (ArtifactItem item : items) {
103             assertMarkerFile(exist, item);
104         }
105     }
106 
107     public void assertMarkerFile(boolean val, ArtifactItem item) {
108         UnpackFileMarkerHandler handle = new UnpackFileMarkerHandler(item, mojo.getMarkersDirectory());
109         try {
110             assertEquals(val, handle.isMarkerSet());
111         } catch (MojoExecutionException e) {
112             fail(e.getLongMessage());
113         }
114     }
115 
116     public void testUnpackFile() throws Exception {
117         List<ArtifactItem> list = stubFactory.getArtifactItems(stubFactory.getClassifiedArtifacts());
118 
119         mojo.setArtifactItems(list);
120 
121         mojo.execute();
122 
123         assertMarkerFiles(list, true);
124     }
125 
126     public void testSkip() throws Exception {
127         List<ArtifactItem> list = stubFactory.getArtifactItems(stubFactory.getClassifiedArtifacts());
128 
129         mojo.setSkip(true);
130         mojo.setArtifactItems(list);
131 
132         mojo.execute();
133 
134         assertMarkerFiles(list, false);
135     }
136 
137     public void testUnpackToLocation() throws Exception {
138         List<ArtifactItem> list = stubFactory.getArtifactItems(stubFactory.getClassifiedArtifacts());
139         ArtifactItem item = list.get(0);
140         item.setOutputDirectory(new File(mojo.getOutputDirectory(), "testOverride"));
141 
142         mojo.setArtifactItems(list);
143 
144         mojo.execute();
145 
146         assertMarkerFiles(list, true);
147     }
148 
149     public void testUnpackToLocationWhereLocationCannotBeCreatedThrowsException() throws Exception {
150         List<ArtifactItem> list = stubFactory.getArtifactItems(stubFactory.getClassifiedArtifacts());
151         ArtifactItem item = list.get(0);
152         item.setOutputDirectory(new File(mojo.getOutputDirectory(), "testOverride"));
153 
154         mojo.setArtifactItems(list);
155         final File currentFile = mojo.getOutputDirectory();
156 
157         // pretend that the output directory cannot be found event after mkdirs has been called by the mojo
158         // ifor instance in the case when the outputDirectory cannot be created because of permissions on the
159         // parent of the output directory
160         mojo.setOutputDirectory(new File(currentFile.getAbsolutePath()) {
161 
162             private static final long serialVersionUID = -8559876942040177020L;
163 
164             @Override
165             public boolean exists() {
166                 // this file will always report that it does not exist
167                 return false;
168             }
169         });
170         try {
171             mojo.execute();
172             fail("Expected Exception Here.");
173         } catch (MojoExecutionException e) {
174             // caught the expected exception.
175         }
176     }
177 
178     public void testMissingVersionNotFound() throws Exception {
179         ArtifactItem item = new ArtifactItem();
180 
181         item.setArtifactId("artifactId");
182         item.setClassifier("");
183         item.setGroupId("groupId");
184         item.setType("type");
185 
186         List<ArtifactItem> list = new ArrayList<>();
187         list.add(item);
188         mojo.setArtifactItems(list);
189 
190         try {
191             mojo.execute();
192             fail("Expected Exception Here.");
193         } catch (MojoExecutionException e) {
194             // caught the expected exception.
195         }
196     }
197 
198     public List<Dependency> getDependencyList(ArtifactItem item) {
199         Dependency dep = new Dependency();
200         dep.setArtifactId(item.getArtifactId());
201         dep.setClassifier(item.getClassifier());
202         dep.setGroupId(item.getGroupId());
203         dep.setType(item.getType());
204         dep.setVersion("2.0-SNAPSHOT");
205 
206         Dependency dep2 = new Dependency();
207         dep2.setArtifactId(item.getArtifactId());
208         dep2.setClassifier("classifier");
209         dep2.setGroupId(item.getGroupId());
210         dep2.setType(item.getType());
211         dep2.setVersion("2.1");
212 
213         List<Dependency> list = new ArrayList<>(2);
214         list.add(dep2);
215         list.add(dep);
216 
217         return list;
218     }
219 
220     public void testMissingVersionFromDependencies() throws Exception {
221         ArtifactItem item = new ArtifactItem();
222 
223         item.setArtifactId("artifactId");
224         item.setClassifier("");
225         item.setGroupId("groupId");
226         item.setType("jar");
227 
228         List<ArtifactItem> list = new ArrayList<>();
229         list.add(item);
230         mojo.setArtifactItems(list);
231 
232         MavenProject project = mojo.getProject();
233         project.setDependencies(createArtifacts(getDependencyList(item)));
234 
235         mojo.execute();
236         assertMarkerFile(true, item);
237         assertEquals("2.0-SNAPSHOT", item.getVersion());
238     }
239 
240     public void testMissingVersionFromDependenciesWithClassifier() throws Exception {
241         ArtifactItem item = new ArtifactItem();
242 
243         item.setArtifactId("artifactId");
244         item.setClassifier("classifier");
245         item.setGroupId("groupId");
246         item.setType("war");
247 
248         List<ArtifactItem> list = new ArrayList<>();
249         list.add(item);
250         mojo.setArtifactItems(list);
251 
252         MavenProject project = mojo.getProject();
253         project.setDependencies(createArtifacts(getDependencyList(item)));
254 
255         mojo.execute();
256         assertMarkerFile(true, item);
257         assertEquals("2.1", item.getVersion());
258     }
259 
260     public List<Dependency> getDependencyMgtList(ArtifactItem item) {
261         Dependency dep = new Dependency();
262         dep.setArtifactId(item.getArtifactId());
263         dep.setClassifier(item.getClassifier());
264         dep.setGroupId(item.getGroupId());
265         dep.setType(item.getType());
266         dep.setVersion("3.0-SNAPSHOT");
267 
268         Dependency dep2 = new Dependency();
269         dep2.setArtifactId(item.getArtifactId());
270         dep2.setClassifier("classifier");
271         dep2.setGroupId(item.getGroupId());
272         dep2.setType(item.getType());
273         dep2.setVersion("3.1");
274 
275         List<Dependency> list = new ArrayList<>(2);
276         list.add(dep2);
277         list.add(dep);
278 
279         return list;
280     }
281 
282     public void testMissingVersionFromDependencyMgt() throws Exception {
283         ArtifactItem item = new ArtifactItem();
284 
285         item.setArtifactId("artifactId");
286         item.setClassifier("");
287         item.setGroupId("groupId");
288         item.setType("jar");
289 
290         MavenProject project = mojo.getProject();
291         project.setDependencies(createArtifacts(getDependencyList(item)));
292 
293         item = new ArtifactItem();
294 
295         item.setArtifactId("artifactId-2");
296         item.setClassifier("");
297         item.setGroupId("groupId");
298         item.setType("jar");
299 
300         List<ArtifactItem> list = new ArrayList<>();
301         list.add(item);
302 
303         mojo.setArtifactItems(list);
304 
305         project.getDependencyManagement().setDependencies(createArtifacts(getDependencyMgtList(item)));
306 
307         mojo.execute();
308         assertMarkerFile(true, item);
309         assertEquals("3.0-SNAPSHOT", item.getVersion());
310     }
311 
312     public void testMissingVersionFromDependencyMgtWithClassifier() throws Exception {
313         ArtifactItem item = new ArtifactItem();
314 
315         item.setArtifactId("artifactId");
316         item.setClassifier("classifier");
317         item.setGroupId("groupId");
318         item.setType("jar");
319 
320         MavenProject project = mojo.getProject();
321         project.setDependencies(createArtifacts(getDependencyList(item)));
322 
323         item = new ArtifactItem();
324 
325         item.setArtifactId("artifactId-2");
326         item.setClassifier("classifier");
327         item.setGroupId("groupId");
328         item.setType("jar");
329 
330         stubFactory.createArtifact(
331                 "groupId",
332                 "artifactId-2",
333                 VersionRange.createFromVersion("3.0-SNAPSHOT"),
334                 null,
335                 "jar",
336                 "classifier",
337                 false);
338         stubFactory.createArtifact(
339                 "groupId", "artifactId-2", VersionRange.createFromVersion("3.1"), null, "jar", "classifier", false);
340 
341         List<ArtifactItem> list = new ArrayList<>();
342         list.add(item);
343 
344         mojo.setArtifactItems(list);
345 
346         project.getDependencyManagement().setDependencies(createArtifacts(getDependencyMgtList(item)));
347 
348         mojo.execute();
349 
350         assertMarkerFile(true, item);
351         assertEquals("3.1", item.getVersion());
352     }
353 
354     public void testArtifactNotFound() throws Exception {
355         dotestArtifactExceptions(false, true);
356     }
357 
358     public void testArtifactResolutionException() throws Exception {
359         dotestArtifactExceptions(true, false);
360     }
361 
362     public void dotestArtifactExceptions(boolean are, boolean anfe) throws Exception {
363         ArtifactItem item = new ArtifactItem();
364 
365         item.setArtifactId("artifactId");
366         item.setClassifier("");
367         item.setGroupId("groupId");
368         item.setType("type");
369         item.setVersion("1.0");
370 
371         List<ArtifactItem> list = new ArrayList<>();
372         list.add(item);
373         mojo.setArtifactItems(list);
374 
375         try {
376             mojo.execute();
377             fail("ExpectedException");
378         } catch (MojoExecutionException e) {
379             assertEquals("Unable to find/resolve artifact.", e.getMessage());
380         }
381     }
382 
383     public void testNoArtifactItems() {
384         try {
385             mojo.getProcessedArtifactItems(false);
386             fail("Expected Exception");
387         } catch (MojoExecutionException e) {
388             assertEquals("There are no artifactItems configured.", e.getMessage());
389         }
390     }
391 
392     public void testUnpackDontOverWriteReleases() throws Exception {
393         stubFactory.setCreateFiles(true);
394         Artifact release = stubFactory.getReleaseArtifact();
395         assertTrue(release.getFile().setLastModified(System.currentTimeMillis() - 2000));
396 
397         ArtifactItem item = new ArtifactItem(createArtifact(release));
398 
399         List<ArtifactItem> list = new ArrayList<>(1);
400         list.add(item);
401         mojo.setArtifactItems(list);
402 
403         mojo.setOverWriteIfNewer(false);
404 
405         mojo.execute();
406 
407         assertUnpacked(item, false);
408     }
409 
410     public void testUnpackDontOverWriteSnapshots() throws Exception {
411         stubFactory.setCreateFiles(true);
412         Artifact artifact = stubFactory.getSnapshotArtifact();
413         assertTrue(artifact.getFile().setLastModified(System.currentTimeMillis() - 2000));
414 
415         ArtifactItem item = new ArtifactItem(createArtifact(artifact));
416 
417         List<ArtifactItem> list = new ArrayList<>(1);
418         list.add(item);
419         mojo.setArtifactItems(list);
420 
421         mojo.setOverWriteIfNewer(false);
422 
423         mojo.execute();
424 
425         assertUnpacked(item, false);
426     }
427 
428     public void testUnpackOverWriteReleases() throws Exception {
429         stubFactory.setCreateFiles(true);
430         Artifact release = stubFactory.getReleaseArtifact();
431         assertTrue(release.getFile().setLastModified(System.currentTimeMillis() - 2000));
432 
433         ArtifactItem item = new ArtifactItem(createArtifact(release));
434 
435         List<ArtifactItem> list = new ArrayList<>(1);
436         list.add(item);
437         mojo.setArtifactItems(list);
438 
439         mojo.setOverWriteIfNewer(false);
440         mojo.setOverWriteReleases(true);
441         mojo.execute();
442 
443         assertUnpacked(item, true);
444     }
445 
446     public void testUnpackOverWriteSnapshot() throws Exception {
447         stubFactory.setCreateFiles(true);
448         Artifact artifact = stubFactory.getSnapshotArtifact();
449         assertTrue(artifact.getFile().setLastModified(System.currentTimeMillis() - 2000));
450 
451         ArtifactItem item = new ArtifactItem(createArtifact(artifact));
452 
453         List<ArtifactItem> list = new ArrayList<>(1);
454         list.add(item);
455         mojo.setArtifactItems(list);
456 
457         mojo.setOverWriteIfNewer(false);
458         mojo.setOverWriteReleases(false);
459         mojo.setOverWriteSnapshots(true);
460         mojo.execute();
461 
462         assertUnpacked(item, true);
463     }
464 
465     /**
466      * The following code has been modified to prevent the
467      * JDK bug which is described in detail
468      * https://bugs.openjdk.java.net/browse/JDK-8177809
469      *
470      */
471     public void testUnpackOverWriteIfNewer() throws Exception {
472         final long now = System.currentTimeMillis();
473 
474         mojo.setSilent(false);
475         stubFactory.setCreateFiles(true);
476         Artifact artifact = stubFactory.getSnapshotArtifact();
477         assertTrue(artifact.getFile().setLastModified(now - 20000));
478 
479         ArtifactItem item = new ArtifactItem(createArtifact(artifact));
480 
481         List<ArtifactItem> list = Collections.singletonList(item);
482         mojo.setArtifactItems(list);
483         mojo.setOverWriteIfNewer(true);
484         mojo.execute();
485         File unpackedFile = getUnpackedFile(item);
486 
487         // round down to the last second
488         long time = now;
489         time = time - (time % 1000);
490         // go back 10 more seconds for linux
491         time -= 10000;
492         // set to known value
493         assertTrue(unpackedFile.setLastModified(time));
494         // set source to be newer about some seconds,
495         // especially on macOS it shouldn't be smaller than 8s in order to mitigate flapping test
496         assertTrue(artifact.getFile().setLastModified(time + 8000));
497 
498         // manually set markerfile (must match getMarkerFile in DefaultMarkerFileHandler)
499         File marker = new File(mojo.getMarkersDirectory(), artifact.getId().replace(':', '-') + ".marker");
500         assertTrue(marker.setLastModified(time));
501 
502         mojo.execute();
503 
504         long markerLastModifiedMillis =
505                 Files.getLastModifiedTime(marker.toPath()).toMillis();
506         long unpackedFileLastModifiedMillis =
507                 Files.getLastModifiedTime(unpackedFile.toPath()).toMillis();
508 
509         assertTrue(
510                 "unpackedFile '" + unpackedFile + "' lastModified() == " + markerLastModifiedMillis
511                         + ": should be different",
512                 markerLastModifiedMillis != unpackedFileLastModifiedMillis);
513     }
514 
515     public void assertUnpacked(ArtifactItem item, boolean overWrite) throws Exception {
516 
517         File unpackedFile = getUnpackedFile(item);
518 
519         Thread.sleep(100);
520         // round down to the last second
521         long time = System.currentTimeMillis();
522         time = time - (time % 1000);
523         assertTrue(unpackedFile.setLastModified(time));
524 
525         assertEquals(time, unpackedFile.lastModified());
526         mojo.execute();
527 
528         if (overWrite) {
529             assertTrue(time != unpackedFile.lastModified());
530         } else {
531             assertEquals(time, unpackedFile.lastModified());
532         }
533     }
534 
535     public File getUnpackedFile(ArtifactItem item) {
536         File unpackedFile = new File(
537                 item.getOutputDirectory(), DependencyArtifactStubFactory.getUnpackableFileName(item.getArtifact()));
538 
539         assertTrue(unpackedFile.exists());
540         return unpackedFile;
541     }
542 
543     // respects the createUnpackableFile flag of the ArtifactStubFactory
544     private List<Dependency> createArtifacts(List<Dependency> items) throws IOException {
545         for (Dependency item : items) {
546             String classifier = "".equals(item.getClassifier()) ? null : item.getClassifier();
547             stubFactory.createArtifact(
548                     item.getGroupId(),
549                     item.getArtifactId(),
550                     VersionRange.createFromVersion(item.getVersion()),
551                     null,
552                     item.getType(),
553                     classifier,
554                     item.isOptional());
555         }
556         return items;
557     }
558 
559     private Artifact createArtifact(Artifact art) throws IOException {
560         String classifier = "".equals(art.getClassifier()) ? null : art.getClassifier();
561         stubFactory.createArtifact(
562                 art.getGroupId(),
563                 art.getArtifactId(),
564                 VersionRange.createFromVersion(art.getVersion()),
565                 null,
566                 art.getType(),
567                 classifier,
568                 art.isOptional());
569         return art;
570     }
571 
572     private ArtifactItem createArtifact(ArtifactItem item) throws IOException {
573         String classifier = "".equals(item.getClassifier()) ? null : item.getClassifier();
574         stubFactory.createArtifact(
575                 item.getGroupId(), item.getArtifactId(), item.getVersion(), null, item.getType(), classifier);
576         return item;
577     }
578 }