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.shared.filtering;
20  
21  import javax.inject.Inject;
22  
23  import java.io.File;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.nio.file.Files;
27  import java.nio.file.Path;
28  import java.util.ArrayList;
29  import java.util.Collections;
30  import java.util.HashSet;
31  import java.util.List;
32  import java.util.Properties;
33  import java.util.Set;
34  
35  import org.apache.commons.io.FileUtils;
36  import org.apache.maven.model.Resource;
37  import org.codehaus.plexus.testing.PlexusTest;
38  import org.junit.jupiter.api.BeforeEach;
39  import org.junit.jupiter.api.Test;
40  import org.sonatype.plexus.build.incremental.ThreadBuildContext;
41  
42  import static org.codehaus.plexus.testing.PlexusExtension.getBasedir;
43  import static org.junit.jupiter.api.Assertions.assertEquals;
44  import static org.junit.jupiter.api.Assertions.assertFalse;
45  import static org.junit.jupiter.api.Assertions.assertTrue;
46  
47  @PlexusTest
48  class IncrementalResourceFilteringTest {
49  
50      @Inject
51      MavenResourcesFiltering mavenResourcesFiltering;
52  
53      Path baseDirectory = new File(getBasedir()).toPath();
54      Path outputDirectory = baseDirectory.resolve("target/IncrementalResourceFilteringTest");
55      Path unitDirectory = baseDirectory.resolve("src/test/units-files/incremental");
56      Path filters = unitDirectory.resolve("filters.txt");
57      Path inputFile01 = unitDirectory.resolve("files/file01.txt");
58      Path inputFile02 = unitDirectory.resolve("files/file02.txt");
59      Path outputFile01 = outputDirectory.resolve("file01.txt");
60      Path outputFile02 = outputDirectory.resolve("file02.txt");
61  
62      @BeforeEach
63      void setUp() throws Exception {
64          if (outputDirectory.toFile().exists()) {
65              FileUtils.deleteDirectory(outputDirectory.toFile());
66          }
67          outputDirectory.toFile().mkdirs();
68      }
69  
70      @Test
71      void simpleIncrementalFiltering() throws Exception {
72          // run full build first
73          filter("time");
74  
75          assertTime("time", "file01.txt");
76          assertTime("time", "file02.txt");
77  
78          // only one file is expected to change
79          Set<Path> changedFiles = new HashSet<>();
80          changedFiles.add(inputFile01);
81  
82          TestIncrementalBuildContext ctx = new TestIncrementalBuildContext(baseDirectory, changedFiles);
83          ThreadBuildContext.setThreadBuildContext(ctx);
84  
85          filter("notime");
86          assertTime("notime", "file01.txt");
87          assertTime("time", "file02.txt"); // this one is unchanged
88  
89          assertTrue(ctx.getRefreshFiles().contains(outputFile01));
90  
91          // only one file is expected to change
92          Set<Path> deletedFiles = new HashSet<>();
93          deletedFiles.add(inputFile01);
94  
95          ctx = new TestIncrementalBuildContext(baseDirectory, null, deletedFiles);
96          ThreadBuildContext.setThreadBuildContext(ctx);
97  
98          filter("moretime");
99          assertFalse(outputFile01.toFile().exists());
100         assertTime("time", "file02.txt"); // this one is unchanged
101 
102         assertTrue(ctx.getRefreshFiles().contains(outputFile01));
103     }
104 
105     @Test
106     void outputChange() throws Exception {
107         // run full build first
108         filter("time");
109 
110         // all files are reprocessed after contents of output directory changed (e.g. was deleted)
111         Set<Path> changedFiles = new HashSet<>();
112         changedFiles.add(outputDirectory);
113         TestIncrementalBuildContext ctx = new TestIncrementalBuildContext(baseDirectory, changedFiles);
114         ThreadBuildContext.setThreadBuildContext(ctx);
115 
116         filter("notime");
117         assertTime("notime", "file01.txt");
118         assertTime("notime", "file02.txt");
119 
120         assertTrue(ctx.getRefreshFiles().contains(outputFile01));
121         assertTrue(ctx.getRefreshFiles().contains(outputFile02));
122     }
123 
124     @Test
125     void filterChange() throws Exception {
126         // run full build first
127         filter("time");
128 
129         // all files are reprocessed after content of filters changes
130         Set<Path> changedFiles = new HashSet<>();
131         changedFiles.add(filters);
132         TestIncrementalBuildContext ctx = new TestIncrementalBuildContext(baseDirectory, changedFiles);
133         ThreadBuildContext.setThreadBuildContext(ctx);
134 
135         filter("notime");
136         assertTime("notime", "file01.txt");
137         assertTime("notime", "file02.txt");
138 
139         assertTrue(ctx.getRefreshFiles().contains(outputFile01));
140         assertTrue(ctx.getRefreshFiles().contains(outputFile02));
141     }
142 
143     /**
144      * Check that missing targets are rebuilt even if source is not changed (MSHARED-1285)
145      */
146     @Test
147     void missingTarget() throws Exception {
148         // run full build first
149         filter("time");
150 
151         // erase target files
152         outputFile01.toFile().delete();
153         outputFile02.toFile().delete();
154         // report change only on one file
155         Set<Path> changedFiles = new HashSet<>();
156         changedFiles.add(inputFile01);
157         TestIncrementalBuildContext ctx = new TestIncrementalBuildContext(baseDirectory, changedFiles);
158         ThreadBuildContext.setThreadBuildContext(ctx);
159 
160         filter("time");
161 
162         assertTrue(ctx.getRefreshFiles().contains(outputFile01));
163         assertTrue(ctx.getRefreshFiles().contains(outputFile02));
164         assertTrue(outputFile01.toFile().exists());
165         assertTrue(outputFile02.toFile().exists());
166     }
167 
168     /**
169      * Check that updated targets with unchanged sources are updated (MSHARED-1285)
170      */
171     @Test
172     void updatedTarget() throws Exception {
173         // run full build first
174         filter("time");
175 
176         // touch target file02
177         FileUtils.touch(outputFile02.toFile());
178         Set<Path> changedFiles = new HashSet<>();
179         changedFiles.add(inputFile01);
180         // report change only on target file
181         changedFiles.add(outputFile02);
182         TestIncrementalBuildContext ctx = new TestIncrementalBuildContext(baseDirectory, changedFiles);
183         ThreadBuildContext.setThreadBuildContext(ctx);
184 
185         // both files are updated
186         filter("notime");
187         assertTime("notime", "file01.txt");
188         assertTime("notime", "file02.txt");
189 
190         assertTrue(ctx.getRefreshFiles().contains(outputFile01));
191         assertTrue(ctx.getRefreshFiles().contains(outputFile02));
192     }
193 
194     @Test
195     void filterDeleted() throws Exception {
196         // run full build first
197         filter("time");
198 
199         // all files are reprocessed after content of filters changes
200         Set<Path> deletedFiles = new HashSet<>();
201         deletedFiles.add(filters);
202         TestIncrementalBuildContext ctx = new TestIncrementalBuildContext(unitDirectory, null, deletedFiles);
203         ThreadBuildContext.setThreadBuildContext(ctx);
204 
205         filter("notime");
206         assertTime("notime", "file01.txt");
207         assertTime("notime", "file02.txt");
208 
209         assertTrue(ctx.getRefreshFiles().contains(outputFile01));
210         assertTrue(ctx.getRefreshFiles().contains(outputFile02));
211     }
212 
213     private void assertTime(String time, String relpath) throws IOException {
214         Properties properties = new Properties();
215 
216         try (InputStream is =
217                 Files.newInputStream(outputDirectory.resolve(relpath).toFile().toPath())) {
218             properties.load(is);
219         }
220 
221         assertEquals(time, properties.getProperty("time"));
222     }
223 
224     private void filter(String time) throws Exception {
225         File baseDir = new File(getBasedir());
226         StubMavenProject mavenProject = new StubMavenProject(baseDir);
227         mavenProject.setVersion("1.0");
228         mavenProject.setGroupId("org.apache");
229         mavenProject.setName("test project");
230 
231         Properties projectProperties = new Properties();
232         projectProperties.put("time", time);
233         projectProperties.put("java.version", "zloug");
234         mavenProject.setProperties(projectProperties);
235 
236         String unitFilesDir = unitDirectory.resolve("files").toString();
237 
238         Resource resource = new Resource();
239         List<Resource> resources = new ArrayList<>();
240         resources.add(resource);
241         resource.setDirectory(unitFilesDir);
242         resource.setFiltering(true);
243 
244         List<String> filtersFile = new ArrayList<>();
245         filtersFile.add(unitDirectory.resolve("filters.txt").toString());
246 
247         MavenResourcesExecution mre = new MavenResourcesExecution();
248         mre.setResources(resources);
249         mre.setOutputDirectory(outputDirectory.toFile());
250         mre.setEncoding("UTF-8");
251         mre.setMavenProject(mavenProject);
252         mre.setFilters(filtersFile);
253         mre.setNonFilteredFileExtensions(Collections.<String>emptyList());
254         mre.setMavenSession(new StubMavenSession());
255         mre.setUseDefaultFilterWrappers(true);
256 
257         mavenResourcesFiltering.filterResources(mre);
258     }
259 }