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.archiver;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.nio.charset.StandardCharsets;
24  import java.nio.file.Files;
25  import java.util.ArrayList;
26  import java.util.Collections;
27  import java.util.List;
28  import java.util.concurrent.TimeUnit;
29  
30  import org.codehaus.plexus.archiver.Archiver;
31  import org.codehaus.plexus.archiver.ArchiverException;
32  import org.codehaus.plexus.archiver.FileSet;
33  import org.codehaus.plexus.archiver.diags.TrackingArchiver;
34  import org.codehaus.plexus.archiver.jar.JarArchiver;
35  import org.codehaus.plexus.archiver.util.DefaultFileSet;
36  import org.codehaus.plexus.components.io.fileselectors.FileInfo;
37  import org.codehaus.plexus.components.io.fileselectors.FileSelector;
38  import org.codehaus.plexus.components.io.functions.InputStreamTransformer;
39  import org.junit.jupiter.api.Test;
40  import org.junit.jupiter.api.Timeout;
41  import org.junit.jupiter.api.extension.ExtendWith;
42  import org.junit.jupiter.api.io.TempDir;
43  import org.mockito.ArgumentCaptor;
44  import org.mockito.junit.jupiter.MockitoExtension;
45  import org.mockito.junit.jupiter.MockitoSettings;
46  import org.mockito.quality.Strictness;
47  
48  import static org.hamcrest.MatcherAssert.assertThat;
49  import static org.hamcrest.Matchers.is;
50  import static org.junit.jupiter.api.Assertions.assertEquals;
51  import static org.junit.jupiter.api.Assertions.assertNotNull;
52  import static org.junit.jupiter.api.Assertions.assertTrue;
53  import static org.mockito.Mockito.mock;
54  import static org.mockito.Mockito.verify;
55  import static org.mockito.Mockito.when;
56  
57  @MockitoSettings(strictness = Strictness.WARN)
58  @ExtendWith(MockitoExtension.class)
59  public class AssemblyProxyArchiverTest {
60      @TempDir
61      private File temporaryFolder;
62  
63      @Test
64      @Timeout(value = 5000, unit = TimeUnit.MILLISECONDS)
65      public void addFileSetSkipWhenSourceIsAssemblyWorkDir() throws IOException, ArchiverException {
66          final File sources = temporaryFolder;
67  
68          final File workdir = new File(sources, "workdir");
69  
70          final TrackingArchiver tracker = new TrackingArchiver();
71          final AssemblyProxyArchiver archiver = new AssemblyProxyArchiver("", tracker, null, null, null, workdir);
72  
73          archiver.setForced(true);
74  
75          final DefaultFileSet fs = new DefaultFileSet();
76          fs.setDirectory(workdir);
77  
78          archiver.addFileSet(fs);
79  
80          assertTrue(tracker.added.isEmpty());
81      }
82  
83      @Test
84      @Timeout(value = 5000, unit = TimeUnit.MILLISECONDS)
85      public void addFileSetAddExcludeWhenSourceContainsAssemblyWorkDir() throws IOException, ArchiverException {
86          final File sources = temporaryFolder;
87  
88          final File workdir = new File(sources, "workdir");
89          workdir.mkdir();
90  
91          Files.write(
92                  sources.toPath().resolve("test-included.txt"),
93                  Collections.singletonList("This is included"),
94                  StandardCharsets.UTF_8);
95          Files.write(
96                  workdir.toPath().resolve("test-excluded.txt"),
97                  Collections.singletonList("This is excluded"),
98                  StandardCharsets.UTF_8);
99  
100         final TrackingArchiver tracker = new TrackingArchiver();
101         final AssemblyProxyArchiver archiver = new AssemblyProxyArchiver("", tracker, null, null, null, workdir);
102 
103         archiver.setForced(true);
104 
105         final DefaultFileSet fs = new DefaultFileSet();
106         fs.setDirectory(sources);
107 
108         archiver.addFileSet(fs);
109 
110         assertEquals(1, tracker.added.size());
111 
112         final TrackingArchiver.Addition addition = tracker.added.get(0);
113         assertNotNull(addition.excludes);
114         assertEquals(1, addition.excludes.length);
115         assertEquals(workdir.getName(), addition.excludes[0]);
116     }
117 
118     @Test
119     public void addFileNoPermsCallAcceptFilesOnlyOnce() throws IOException, ArchiverException {
120         final Archiver delegate = mock(Archiver.class);
121 
122         final CounterSelector counter = new CounterSelector(true);
123         final List<FileSelector> selectors = new ArrayList<>();
124         selectors.add(counter);
125 
126         final AssemblyProxyArchiver archiver =
127                 new AssemblyProxyArchiver("", delegate, null, selectors, null, new File("."));
128         archiver.setForced(true);
129 
130         final File inputFile = File.createTempFile("junit", null, temporaryFolder);
131         archiver.addFile(inputFile, "file.txt");
132 
133         assertEquals(1, counter.getCount());
134         verify(delegate).addFile(inputFile, "file.txt");
135         verify(delegate).setForced(true);
136     }
137 
138     @Test
139     @SuppressWarnings("deprecation")
140     public void addDirectoryNoPermsCallAcceptFilesOnlyOnce() throws IOException, ArchiverException {
141         final Archiver delegate = new JarArchiver();
142 
143         final File output = File.createTempFile("junit", null, temporaryFolder);
144 
145         delegate.setDestFile(output);
146 
147         final CounterSelector counter = new CounterSelector(true);
148         final List<FileSelector> selectors = new ArrayList<>();
149         selectors.add(counter);
150 
151         final AssemblyProxyArchiver archiver =
152                 new AssemblyProxyArchiver("", delegate, null, selectors, null, new File("."));
153 
154         archiver.setForced(true);
155 
156         final File dir = newFolder(temporaryFolder, "junit");
157         Files.write(
158                 dir.toPath().resolve("file.txt"), Collections.singletonList("This is a test."), StandardCharsets.UTF_8);
159 
160         archiver.addDirectory(dir);
161 
162         archiver.createArchive();
163 
164         assertEquals(1, counter.getCount());
165     }
166 
167     @Test
168     public void assemblyWorkDir() {
169         final Archiver delegate = mock(Archiver.class);
170         final List<FileSelector> selectors = new ArrayList<>();
171 
172         final AssemblyProxyArchiver archiver = new AssemblyProxyArchiver(
173                 "prefix", delegate, null, selectors, null, new File(temporaryFolder, "module1"));
174 
175         FileSet fileSet = mock(FileSet.class);
176         when(fileSet.getDirectory()).thenReturn(temporaryFolder);
177         when(fileSet.getStreamTransformer()).thenReturn(mock(InputStreamTransformer.class));
178 
179         archiver.addFileSet(fileSet);
180 
181         ArgumentCaptor<FileSet> delFileSet = ArgumentCaptor.forClass(FileSet.class);
182         verify(delegate).addFileSet(delFileSet.capture());
183 
184         assertThat(delFileSet.getValue().getDirectory(), is(fileSet.getDirectory()));
185         assertThat(delFileSet.getValue().getExcludes(), is(new String[] {"module1"}));
186         assertThat(delFileSet.getValue().getFileMappers(), is(fileSet.getFileMappers()));
187         assertThat(delFileSet.getValue().getFileSelectors(), is(fileSet.getFileSelectors()));
188         assertThat(delFileSet.getValue().getIncludes(), is(new String[0]));
189         assertThat(delFileSet.getValue().getPrefix(), is("prefix/"));
190         assertThat(delFileSet.getValue().getStreamTransformer(), is(fileSet.getStreamTransformer()));
191     }
192 
193     private static final class CounterSelector implements FileSelector {
194 
195         private int count = 0;
196 
197         private boolean answer = false;
198 
199         CounterSelector(final boolean answer) {
200             this.answer = answer;
201         }
202 
203         int getCount() {
204             return count;
205         }
206 
207         public boolean isSelected(final FileInfo fileInfo) throws IOException {
208             if (fileInfo.isFile()) {
209                 count++;
210                 System.out.println("Counting file: " + fileInfo.getName() + ". Current count: " + count);
211             }
212 
213             return answer;
214         }
215     }
216 
217     private static File newFolder(File root, String... subDirs) throws IOException {
218         String subFolder = String.join("/", subDirs);
219         File result = new File(root, subFolder);
220         if (!result.mkdirs()) {
221             throw new IOException("Couldn't create folders " + root);
222         }
223         return result;
224     }
225 }