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.buildcache.its;
20  
21  import java.io.IOException;
22  import java.nio.file.Files;
23  import java.nio.file.Path;
24  import java.nio.file.Paths;
25  import java.util.Arrays;
26  import java.util.stream.Stream;
27  
28  import org.apache.maven.buildcache.its.junit.IntegrationTest;
29  import org.apache.maven.it.VerificationException;
30  import org.apache.maven.it.Verifier;
31  import org.junit.jupiter.api.Test;
32  
33  import static org.junit.jupiter.api.Assertions.assertFalse;
34  import static org.junit.jupiter.api.Assertions.assertTrue;
35  
36  /**
37   * Tests that the maven.build.cache.cacheCompile property correctly disables
38   * caching of compile-phase outputs.
39   */
40  @IntegrationTest("src/test/projects/issue-393-compile-restore")
41  class CacheCompileDisabledTest {
42  
43      @Test
44      void compileDoesNotCacheWhenDisabled(Verifier verifier) throws VerificationException, IOException {
45          verifier.setAutoclean(false);
46  
47          // The actual cache is stored in target/build-cache (relative to the extension root, not test project)
48          Path localCache = Paths.get(System.getProperty("maven.multiModuleProjectDirectory"))
49                  .resolve("target/build-cache");
50  
51          // Clean cache before test
52          if (Files.exists(localCache)) {
53              deleteDirectory(localCache);
54          }
55  
56          // First compile with cacheCompile disabled - compile only the app module to avoid dependency issues
57          verifier.setLogFileName("../log-compile-disabled.txt");
58          verifier.addCliOption("-Dmaven.build.cache.cacheCompile=false");
59          verifier.addCliOption("-pl");
60          verifier.addCliOption("app");
61          verifier.executeGoals(Arrays.asList("clean", "compile"));
62          verifier.verifyErrorFreeLog();
63  
64          // Verify NO cache entry was created (no buildinfo.xml in local cache)
65          boolean hasCacheEntry;
66          try (Stream<Path> walk = Files.walk(localCache)) {
67              hasCacheEntry = walk.anyMatch(p -> p.getFileName().toString().equals("buildinfo.xml"));
68          }
69          assertFalse(hasCacheEntry, "Cache entry should NOT be created when maven.build.cache.cacheCompile=false");
70  
71          // Clean project and run compile again
72          verifier.setLogFileName("../log-compile-disabled-2.txt");
73          verifier.addCliOption("-Dmaven.build.cache.cacheCompile=false");
74          verifier.addCliOption("-pl");
75          verifier.addCliOption("app");
76          verifier.executeGoals(Arrays.asList("clean", "compile"));
77          verifier.verifyErrorFreeLog();
78  
79          // Verify cache miss (should NOT restore from cache)
80          Path logFile = Paths.get(verifier.getBasedir()).getParent().resolve("log-compile-disabled-2.txt");
81          String logContent = new String(Files.readAllBytes(logFile));
82          assertFalse(
83                  logContent.contains("Found cached build, restoring"),
84                  "Should NOT restore from cache when cacheCompile was disabled");
85      }
86  
87      @Test
88      void compileCreatesCacheEntryWhenEnabled(Verifier verifier) throws VerificationException, IOException {
89          verifier.setAutoclean(false);
90  
91          // The actual cache is stored in target/build-cache (relative to the extension root, not test project)
92          Path localCache = Paths.get(System.getProperty("maven.multiModuleProjectDirectory"))
93                  .resolve("target/build-cache");
94  
95          // Clean cache before test
96          if (Files.exists(localCache)) {
97              deleteDirectory(localCache);
98          }
99  
100         // First compile with cacheCompile enabled (default) - compile only the app module
101         verifier.setLogFileName("../log-compile-enabled.txt");
102         verifier.addCliOption("-pl");
103         verifier.addCliOption("app");
104         verifier.executeGoals(Arrays.asList("clean", "compile"));
105         verifier.verifyErrorFreeLog();
106 
107         // Verify cache entry WAS created
108         boolean hasCacheEntry;
109         try (Stream<Path> walk = Files.walk(localCache)) {
110             hasCacheEntry = walk.anyMatch(p -> p.getFileName().toString().equals("buildinfo.xml"));
111         }
112         assertTrue(hasCacheEntry, "Cache entry should be created when maven.build.cache.cacheCompile=true (default)");
113 
114         // Clean project and run compile again
115         verifier.setLogFileName("../log-compile-enabled-2.txt");
116         verifier.addCliOption("-pl");
117         verifier.addCliOption("app");
118         verifier.executeGoals(Arrays.asList("clean", "compile"));
119         verifier.verifyErrorFreeLog();
120 
121         // Verify cache hit (should restore from cache)
122         verifier.verifyTextInLog("Found cached build, restoring");
123         verifier.verifyTextInLog("Skipping plugin execution (cached): compiler:compile");
124     }
125 
126     private void deleteDirectory(Path directory) throws IOException {
127         if (Files.exists(directory)) {
128             try (Stream<Path> walk = Files.walk(directory)) {
129                 walk.sorted((a, b) -> b.compareTo(a)).forEach(path -> {
130                     try {
131                         Files.delete(path);
132                     } catch (IOException e) {
133                         // Ignore
134                     }
135                 });
136             }
137         }
138     }
139 }