1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.buildcache.xml;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25 import java.nio.file.AccessMode;
26 import java.nio.file.FileSystem;
27 import java.nio.file.Path;
28 import java.nio.file.spi.FileSystemProvider;
29 import java.util.Arrays;
30 import java.util.Collections;
31 import java.util.HashMap;
32 import java.util.Map;
33 import java.util.Optional;
34 import java.util.Properties;
35 import java.util.stream.Collectors;
36
37 import org.apache.commons.lang3.tuple.Pair;
38 import org.apache.maven.buildcache.DefaultPluginScanConfig;
39 import org.apache.maven.buildcache.hash.HashFactory;
40 import org.apache.maven.buildcache.xml.config.Configuration;
41 import org.apache.maven.buildcache.xml.config.Remote;
42 import org.apache.maven.execution.MavenExecutionRequest;
43 import org.apache.maven.execution.MavenSession;
44 import org.apache.maven.model.Plugin;
45 import org.apache.maven.model.PluginExecution;
46 import org.apache.maven.plugin.MojoExecution;
47 import org.apache.maven.rtinfo.RuntimeInformation;
48 import org.junit.jupiter.api.BeforeEach;
49 import org.junit.jupiter.api.Test;
50 import org.junit.jupiter.api.extension.ExtendWith;
51 import org.mockito.ArgumentMatchers;
52 import org.mockito.Mock;
53 import org.mockito.Mockito;
54 import org.mockito.junit.jupiter.MockitoExtension;
55 import org.mockito.junit.jupiter.MockitoSettings;
56 import org.mockito.quality.Strictness;
57
58 import static org.junit.Assert.assertFalse;
59 import static org.junit.Assert.assertNull;
60 import static org.junit.jupiter.api.Assertions.assertEquals;
61 import static org.junit.jupiter.api.Assertions.assertTrue;
62 import static org.mockito.Mockito.doThrow;
63 import static org.mockito.Mockito.mock;
64 import static org.mockito.Mockito.when;
65
66 @ExtendWith(MockitoExtension.class)
67 @MockitoSettings(strictness = Strictness.LENIENT)
68 @SuppressWarnings("unchecked")
69 public class CacheConfigImplTest {
70
71 @Mock
72 private MavenSession mavenSession;
73
74 @Mock
75 private Properties mockProperties;
76
77 @Mock
78 private MavenExecutionRequest mockMavenExecutionRequest;
79
80 @Mock
81 private RuntimeInformation rtInfo;
82
83 @Mock
84 private XmlService xmlService;
85
86 @Mock
87 private File rootConfigFile;
88
89 private org.apache.maven.buildcache.xml.config.CacheConfig testCacheConfig;
90 private CacheConfigImpl testObject;
91
92 @BeforeEach
93 void setUp() throws IOException {
94
95
96
97
98
99 when(mavenSession.getRequest()).thenReturn(mockMavenExecutionRequest);
100 when(mavenSession.getUserProperties()).thenReturn(mockProperties);
101 when(mavenSession.getSystemProperties()).thenReturn(mockProperties);
102
103
104 when(rtInfo.isMavenVersion(ArgumentMatchers.anyString())).thenReturn(true);
105
106
107 deepMockConfigFile(rootConfigFile, true);
108 when(mockMavenExecutionRequest.getMultiModuleProjectDirectory()).thenReturn(rootConfigFile);
109
110 testCacheConfig = new XmlService().loadCacheConfig("<cache></cache>".getBytes());
111 when(xmlService.loadCacheConfig(rootConfigFile)).thenReturn(testCacheConfig);
112
113
114 testObject = new CacheConfigImpl(xmlService, mavenSession, rtInfo);
115 }
116
117 private static void deepMockConfigFile(File mockFile, boolean exists) throws IOException {
118 Path mockPath = mock(Path.class);
119 when(mockFile.toPath()).thenReturn(mockPath);
120 when(mockPath.toFile()).thenReturn(mockFile);
121 when(mockPath.resolve(ArgumentMatchers.anyString())).thenReturn(mockPath);
122
123
124
125 FileSystem mockFileSystem = mock(FileSystem.class);
126 when(mockPath.getFileSystem()).thenReturn(mockFileSystem);
127 FileSystemProvider mockProvider = mock(FileSystemProvider.class);
128 when(mockFileSystem.provider()).thenReturn(mockProvider);
129
130
131 if (!exists) {
132 doThrow(new IOException("mock IOException"))
133 .when(mockProvider)
134 .checkAccess(ArgumentMatchers.eq(mockPath), ArgumentMatchers.any(AccessMode.class));
135 }
136
137
138
139 Optional<Method> methodToMock = Arrays.stream(FileSystemProvider.class.getDeclaredMethods())
140 .filter(method -> "exists".equals(method.getName()))
141 .findAny();
142 if (methodToMock.isPresent()) {
143 Class<?>[] paramTypes = methodToMock.get().getParameterTypes();
144 Object[] params = Arrays.stream(paramTypes)
145 .map(paramType -> Mockito.any(paramType))
146 .toArray();
147 try {
148 Mockito.when(methodToMock.get().invoke(mockProvider, params)).thenReturn(exists);
149 } catch (IllegalAccessException | InvocationTargetException e) {
150 throw new RuntimeException("Error while mocking the 'exists' method from FileSystemProvider", e);
151 }
152 }
153 }
154
155 private void assertDefaults() {
156 assertDefaults(Collections.emptyMap());
157 }
158
159 private void assertDefaults(Pair<String, Runnable>... overrides) {
160 assertDefaults(Arrays.stream(overrides).collect(Collectors.toMap(Pair::getKey, Pair::getValue)));
161 }
162
163 private void assertDefaults(Map<String, Runnable> overrides) {
164 Map<String, Runnable> asserts = new HashMap<>();
165 asserts.put("adjustMetaInfVersion", () -> assertFalse(testObject.adjustMetaInfVersion()));
166 asserts.put("calculateProjectVersionChecksum", () -> assertFalse(testObject.calculateProjectVersionChecksum()));
167 asserts.put("canIgnore", () -> assertFalse(testObject.canIgnore(mock(MojoExecution.class))));
168 asserts.put("getAlwaysRunPlugins", () -> assertNull(testObject.getAlwaysRunPlugins()));
169 asserts.put("getAttachedOutputs", () -> assertEquals(Collections.emptyList(), testObject.getAttachedOutputs()));
170 asserts.put("getBaselineCacheUrl", () -> assertNull(testObject.getBaselineCacheUrl()));
171 asserts.put("getDefaultGlob", () -> assertEquals("*", testObject.getDefaultGlob()));
172 asserts.put(
173 "getEffectivePomExcludeProperties",
174 () -> assertEquals(
175 Collections.emptyList(), testObject.getEffectivePomExcludeProperties(mock(Plugin.class))));
176 asserts.put("getExcludePatterns", () -> assertEquals(Collections.emptyList(), testObject.getExcludePatterns()));
177 asserts.put(
178 "getExecutionDirScanConfig",
179 () -> assertTrue(
180 testObject.getExecutionDirScanConfig(mock(Plugin.class), mock(PluginExecution.class))
181 instanceof DefaultPluginScanConfig));
182 asserts.put(
183 "getGlobalExcludePaths",
184 () -> assertEquals(Collections.emptyList(), testObject.getGlobalExcludePaths()));
185 asserts.put(
186 "getGlobalIncludePaths",
187 () -> assertEquals(Collections.emptyList(), testObject.getGlobalIncludePaths()));
188 asserts.put("getHashFactory", () -> assertEquals(HashFactory.XX, testObject.getHashFactory()));
189 asserts.put("getId", () -> assertEquals("cache", testObject.getId()));
190 asserts.put("getLocalRepositoryLocation", () -> assertNull(testObject.getLocalRepositoryLocation()));
191 asserts.put(
192 "getLoggedProperties",
193 () -> assertEquals(Collections.emptyList(), testObject.getLoggedProperties(mock(MojoExecution.class))));
194 asserts.put("getMaxLocalBuildsCached", () -> assertEquals(3, testObject.getMaxLocalBuildsCached()));
195 asserts.put("getMultiModule", () -> assertNull(testObject.getMultiModule()));
196 asserts.put(
197 "getNologProperties",
198 () -> assertEquals(Collections.emptyList(), testObject.getNologProperties(mock(MojoExecution.class))));
199 asserts.put(
200 "getPluginDirScanConfig",
201 () -> assertTrue(
202 testObject.getPluginDirScanConfig(mock(Plugin.class)) instanceof DefaultPluginScanConfig));
203 asserts.put(
204 "getTrackedProperties",
205 () -> assertEquals(
206 Collections.emptyList(), testObject.getTrackedProperties(mock(MojoExecution.class))));
207 asserts.put("getTransport", () -> assertEquals("resolver", testObject.getTransport()));
208 asserts.put("getUrl", () -> assertNull(testObject.getUrl()));
209 asserts.put("isBaselineDiffEnabled", () -> assertFalse(testObject.isBaselineDiffEnabled()));
210 asserts.put("isEnabled", () -> assertTrue(testObject.isEnabled()));
211 asserts.put("isFailFast", () -> assertFalse(testObject.isFailFast()));
212 asserts.put("isForcedExecution", () -> assertFalse(testObject.isForcedExecution(null)));
213 asserts.put("isLazyRestore", () -> assertFalse(testObject.isLazyRestore()));
214 asserts.put("isLogAllProperties", () -> assertFalse(testObject.isLogAllProperties(null)));
215 asserts.put("isProcessPlugins", () -> assertEquals("true", testObject.isProcessPlugins()));
216 asserts.put("isRemoteCacheEnabled", () -> assertFalse(testObject.isRemoteCacheEnabled()));
217 asserts.put("isRestoreGeneratedSources", () -> assertTrue(testObject.isRestoreGeneratedSources()));
218 asserts.put("isSaveToRemote", () -> assertFalse(testObject.isSaveToRemote()));
219 asserts.put("isSaveToRemoteFinal", () -> assertFalse(testObject.isSaveToRemoteFinal()));
220 asserts.put("isSkipCache", () -> assertFalse(testObject.isSkipCache()));
221
222 asserts.putAll(overrides);
223
224 asserts.values().forEach(Runnable::run);
225 }
226
227 @Test
228 void testInitializationInvalidMavenVersion() {
229 when(rtInfo.isMavenVersion(ArgumentMatchers.anyString())).thenReturn(false);
230
231 assertEquals(CacheState.DISABLED, testObject.initialize());
232 }
233
234 @Test
235 void testInitializationDisabledUserProperty() {
236 when(mockProperties.getProperty(CacheConfigImpl.CACHE_ENABLED_PROPERTY_NAME))
237 .thenReturn("false");
238
239 assertEquals(CacheState.DISABLED, testObject.initialize());
240 }
241
242 @Test
243 void testInitializationDisabledSystemProperty() {
244 when(mockProperties.getProperty(CacheConfigImpl.CACHE_ENABLED_PROPERTY_NAME))
245 .thenReturn(null)
246 .thenReturn("false");
247
248 assertEquals(CacheState.DISABLED, testObject.initialize());
249 }
250
251 @Test
252 void testInitializationDisabledInXML() {
253 Configuration configuration = new Configuration();
254 configuration.setEnabled(false);
255 testCacheConfig.setConfiguration(configuration);
256
257 assertEquals(CacheState.DISABLED, testObject.initialize());
258 }
259
260 @Test
261 void testInitializationNonExistantXMLFromProperty() {
262 when(mockProperties.getProperty(CacheConfigImpl.CONFIG_PATH_PROPERTY_NAME))
263 .thenReturn("does-not-exist");
264
265 assertEquals(CacheState.INITIALIZED, testObject.initialize());
266 assertDefaults();
267 }
268
269 @Test
270 void testInitializationNonExistantXMLFromRoot() throws IOException {
271 deepMockConfigFile(rootConfigFile, false);
272
273 assertEquals(CacheState.INITIALIZED, testObject.initialize());
274 assertDefaults();
275 }
276
277 @Test
278 void testInitializationExplicitlyEnabledUserPropertyOverridesXML() {
279 Configuration configuration = new Configuration();
280 configuration.setEnabled(false);
281 testCacheConfig.setConfiguration(configuration);
282 when(mockProperties.getProperty(CacheConfigImpl.CACHE_ENABLED_PROPERTY_NAME))
283 .thenReturn("true");
284
285 assertEquals(CacheState.INITIALIZED, testObject.initialize());
286 assertDefaults();
287 }
288
289 @Test
290 void testRemoteEnableInXMLButNoURL() {
291 Configuration configuration = new Configuration();
292 Remote remote = new Remote();
293 remote.setEnabled(true);
294 configuration.setRemote(remote);
295 testCacheConfig.setConfiguration(configuration);
296
297 assertEquals(CacheState.INITIALIZED, testObject.initialize());
298 assertDefaults();
299 }
300
301 @Test
302 void testRemoteEnableInXMLWithURL() {
303 Configuration configuration = new Configuration();
304 Remote remote = new Remote();
305 remote.setEnabled(true);
306 remote.setUrl("dummy.url.xyz");
307 configuration.setRemote(remote);
308 testCacheConfig.setConfiguration(configuration);
309
310 assertEquals(CacheState.INITIALIZED, testObject.initialize());
311 assertDefaults(
312 Pair.of("getUrl", () -> assertEquals("dummy.url.xyz", testObject.getUrl())),
313 Pair.of("isRemoteCacheEnabled", () -> assertTrue(testObject.isRemoteCacheEnabled())));
314 }
315
316 @Test
317 void testRemoteEnableByUserPropertyOverrideNoURL() {
318 when(mockProperties.getProperty(CacheConfigImpl.REMOTE_ENABLED_PROPERTY_NAME))
319 .thenReturn("true");
320
321 assertEquals(CacheState.INITIALIZED, testObject.initialize());
322 assertDefaults();
323 }
324
325 @Test
326 void testRemoteEnableByUserPropertyOverrideWithURL() {
327 Configuration configuration = new Configuration();
328 Remote remote = new Remote();
329 remote.setUrl("dummy.url.xyz");
330 configuration.setRemote(remote);
331 testCacheConfig.setConfiguration(configuration);
332 when(mockProperties.getProperty(CacheConfigImpl.REMOTE_ENABLED_PROPERTY_NAME))
333 .thenReturn("true");
334
335 assertEquals(CacheState.INITIALIZED, testObject.initialize());
336 assertDefaults(
337 Pair.of("getUrl", () -> assertEquals("dummy.url.xyz", testObject.getUrl())),
338 Pair.of("isRemoteCacheEnabled", () -> assertTrue(testObject.isRemoteCacheEnabled())));
339 }
340
341 @Test
342 void testRemoteDisableByUserPropertyOverride() {
343 Configuration configuration = new Configuration();
344 Remote remote = new Remote();
345 remote.setUrl("dummy.url.xyz");
346 remote.setEnabled(true);
347 configuration.setRemote(remote);
348 testCacheConfig.setConfiguration(configuration);
349 when(mockProperties.getProperty(CacheConfigImpl.REMOTE_ENABLED_PROPERTY_NAME))
350 .thenReturn("false");
351
352 assertEquals(CacheState.INITIALIZED, testObject.initialize());
353 assertDefaults(Pair.of("getUrl", () -> assertEquals("dummy.url.xyz", testObject.getUrl())));
354 }
355
356 @Test
357 void testRemoveSaveEnabledInXML() {
358 Configuration configuration = new Configuration();
359 Remote remote = new Remote();
360 remote.setUrl("dummy.url.xyz");
361 remote.setEnabled(true);
362 remote.setSaveToRemote(true);
363 configuration.setRemote(remote);
364 testCacheConfig.setConfiguration(configuration);
365
366 assertEquals(CacheState.INITIALIZED, testObject.initialize());
367 assertDefaults(
368 Pair.of("getUrl", () -> assertEquals("dummy.url.xyz", testObject.getUrl())),
369 Pair.of("isRemoteCacheEnabled", () -> assertTrue(testObject.isRemoteCacheEnabled())),
370 Pair.of("isSaveToRemote", () -> assertTrue(testObject.isSaveToRemote())));
371 }
372
373 @Test
374 void testRemoveSaveEnabledByUserProperty() {
375 Configuration configuration = new Configuration();
376 Remote remote = new Remote();
377 remote.setUrl("dummy.url.xyz");
378 remote.setEnabled(true);
379 configuration.setRemote(remote);
380 testCacheConfig.setConfiguration(configuration);
381 when(mockProperties.getProperty(CacheConfigImpl.SAVE_TO_REMOTE_PROPERTY_NAME))
382 .thenReturn("true");
383
384 assertEquals(CacheState.INITIALIZED, testObject.initialize());
385 assertDefaults(
386 Pair.of("getUrl", () -> assertEquals("dummy.url.xyz", testObject.getUrl())),
387 Pair.of("isRemoteCacheEnabled", () -> assertTrue(testObject.isRemoteCacheEnabled())),
388 Pair.of("isSaveToRemote", () -> assertTrue(testObject.isSaveToRemote())));
389 }
390
391 @Test
392 void testRemoveSaveDisabledByUserProperty() {
393 Configuration configuration = new Configuration();
394 Remote remote = new Remote();
395 remote.setUrl("dummy.url.xyz");
396 remote.setEnabled(true);
397 remote.setSaveToRemote(true);
398 configuration.setRemote(remote);
399 testCacheConfig.setConfiguration(configuration);
400 when(mockProperties.getProperty(CacheConfigImpl.SAVE_TO_REMOTE_PROPERTY_NAME))
401 .thenReturn("false");
402
403 assertEquals(CacheState.INITIALIZED, testObject.initialize());
404 assertDefaults(
405 Pair.of("getUrl", () -> assertEquals("dummy.url.xyz", testObject.getUrl())),
406 Pair.of("isRemoteCacheEnabled", () -> assertTrue(testObject.isRemoteCacheEnabled())));
407 }
408
409 @Test
410 void testRemoteSaveIgnoredWhenRemoteDisabledInXML() {
411 Configuration configuration = new Configuration();
412 Remote remote = new Remote();
413 remote.setSaveToRemote(true);
414 configuration.setRemote(remote);
415 testCacheConfig.setConfiguration(configuration);
416
417 assertEquals(CacheState.INITIALIZED, testObject.initialize());
418 assertDefaults();
419 }
420
421 @Test
422 void testRemoteSaveIgnoredWhenRemoteDisabledUserProperty() {
423 when(mockProperties.getProperty(CacheConfigImpl.SAVE_TO_REMOTE_PROPERTY_NAME))
424 .thenReturn("true");
425
426 assertEquals(CacheState.INITIALIZED, testObject.initialize());
427 assertDefaults();
428 }
429
430 @Test
431 void testRemoteSaveIgnoredWhenRemoteDisabledByUserPropertyOverride() {
432 Configuration configuration = new Configuration();
433 Remote remote = new Remote();
434 remote.setUrl("dummy.url.xyz");
435 remote.setEnabled(true);
436 remote.setSaveToRemote(true);
437 configuration.setRemote(remote);
438 testCacheConfig.setConfiguration(configuration);
439 when(mockProperties.getProperty(CacheConfigImpl.REMOTE_ENABLED_PROPERTY_NAME))
440 .thenReturn("false");
441
442 assertEquals(CacheState.INITIALIZED, testObject.initialize());
443 assertDefaults(Pair.of("getUrl", () -> assertEquals("dummy.url.xyz", testObject.getUrl())));
444 }
445
446 @Test
447 void testRemoveSaveFinalEnabledByUserProperty() {
448 Configuration configuration = new Configuration();
449 Remote remote = new Remote();
450 remote.setUrl("dummy.url.xyz");
451 remote.setEnabled(true);
452 remote.setSaveToRemote(true);
453 configuration.setRemote(remote);
454 testCacheConfig.setConfiguration(configuration);
455 when(mockProperties.getProperty(CacheConfigImpl.SAVE_NON_OVERRIDEABLE_NAME))
456 .thenReturn("true");
457
458 assertEquals(CacheState.INITIALIZED, testObject.initialize());
459 assertDefaults(
460 Pair.of("getUrl", () -> assertEquals("dummy.url.xyz", testObject.getUrl())),
461 Pair.of("isRemoteCacheEnabled", () -> assertTrue(testObject.isRemoteCacheEnabled())),
462 Pair.of("isSaveToRemote", () -> assertTrue(testObject.isSaveToRemote())),
463 Pair.of("isSaveToRemoteFinal", () -> assertTrue(testObject.isSaveToRemoteFinal())));
464 }
465
466 @Test
467 void testRemoveSaveFinalIgnoredWhenRemoteSaveDisabled() {
468 Configuration configuration = new Configuration();
469 Remote remote = new Remote();
470 remote.setUrl("dummy.url.xyz");
471 remote.setEnabled(true);
472 configuration.setRemote(remote);
473 testCacheConfig.setConfiguration(configuration);
474 when(mockProperties.getProperty(CacheConfigImpl.SAVE_NON_OVERRIDEABLE_NAME))
475 .thenReturn("true");
476
477 assertEquals(CacheState.INITIALIZED, testObject.initialize());
478 assertDefaults(
479 Pair.of("getUrl", () -> assertEquals("dummy.url.xyz", testObject.getUrl())),
480 Pair.of("isRemoteCacheEnabled", () -> assertTrue(testObject.isRemoteCacheEnabled())));
481 }
482 }