1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.buildcache;
20
21 import java.io.File;
22 import java.nio.file.Paths;
23 import java.util.Arrays;
24 import java.util.List;
25 import java.util.stream.Collectors;
26
27 import org.apache.commons.lang3.SystemUtils;
28 import org.apache.maven.buildcache.xml.CacheConfig;
29 import org.apache.maven.buildcache.xml.build.CompletedExecution;
30 import org.apache.maven.buildcache.xml.build.PropertyValue;
31 import org.apache.maven.buildcache.xml.config.TrackedProperty;
32 import org.apache.maven.execution.scope.internal.MojoExecutionScope;
33 import org.apache.maven.plugin.MavenPluginManager;
34 import org.apache.maven.plugin.MojoExecution;
35 import org.apache.maven.project.MavenProject;
36 import org.jetbrains.annotations.NotNull;
37 import org.junit.jupiter.api.BeforeEach;
38 import org.junit.jupiter.api.Nested;
39 import org.junit.jupiter.api.Test;
40 import org.testcontainers.shaded.org.apache.commons.lang3.tuple.Pair;
41
42 import static org.junit.jupiter.api.Assertions.assertFalse;
43 import static org.junit.jupiter.api.Assertions.assertTrue;
44 import static org.mockito.Mockito.mock;
45 import static org.mockito.Mockito.when;
46
47 class BuildCacheMojosExecutionStrategyTest {
48
49 @Nested
50 class ParametersMatchingTest {
51
52 private BuildCacheMojosExecutionStrategy strategy;
53 private MavenProject projectMock;
54 private MojoExecution executionMock;
55 private CompletedExecution cacheRecordMock;
56 private CacheConfig cacheConfigMock;
57
58 @BeforeEach
59 void setUp() {
60 cacheConfigMock = mock(CacheConfig.class);
61 strategy = new BuildCacheMojosExecutionStrategy(
62 mock(CacheController.class),
63 cacheConfigMock,
64 mock(MojoParametersListener.class),
65 mock(LifecyclePhasesHelper.class),
66 mock(MavenPluginManager.class),
67 mock(MojoExecutionScope.class));
68
69 projectMock = mock(MavenProject.class);
70 executionMock = mock(MojoExecution.class);
71 cacheRecordMock = mock(CompletedExecution.class);
72 }
73
74 @Test
75 void testBasicParamsMatching() {
76
77 boolean windows = SystemUtils.IS_OS_WINDOWS;
78
79 List<Pair<TrackedProperty, PropertyValue>> cacheProperties = Arrays.asList(
80 setupProperty("bool", "true"),
81 setupProperty("primitive", "1"),
82 setupProperty("file", "c"),
83 setupProperty("path", windows ? "..\\d\\e" : "../d/e"),
84 setupProperty("list", "[a, b, c]"),
85 setupProperty("array", "{c,d,e}"),
86 setupProperty("nullObject", null));
87
88 List<TrackedProperty> trackedProperties =
89 cacheProperties.stream().map(Pair::getLeft).collect(Collectors.toList());
90
91 List<PropertyValue> cacheRecordProperties =
92 cacheProperties.stream().map(Pair::getRight).collect(Collectors.toList());
93
94 when(cacheConfigMock.getTrackedProperties(executionMock)).thenReturn(trackedProperties);
95 when(cacheRecordMock.getProperties()).thenReturn(cacheRecordProperties);
96
97 when(projectMock.getBasedir()).thenReturn(windows ? new File("c:\\a\\b") : new File("/a/b"));
98
99 TestMojo testMojo = TestMojo.create(
100 true,
101 1,
102 windows
103 ? Paths.get("c:\\a\\b\\c").toFile()
104 : Paths.get("/a/b/c").toFile(),
105 Paths.get(windows ? "..\\d\\e" : "../d/e"),
106 Arrays.<String>asList("a", "b", "c"),
107 new String[] {"c", "d", "e"});
108
109 assertTrue(strategy.isParamsMatched(projectMock, executionMock, testMojo, cacheRecordMock));
110 }
111
112 @Test
113 void testSkipValue() {
114
115 String propertyName = "anyObject";
116
117 TrackedProperty config = new TrackedProperty();
118 config.setPropertyName(propertyName);
119 config.setSkipValue("true");
120
121
122 PropertyValue cache = new PropertyValue();
123 cache.setName(propertyName);
124 cache.setValue("false");
125
126 when(cacheConfigMock.getTrackedProperties(executionMock)).thenReturn(Arrays.asList(config));
127 when(cacheRecordMock.getProperties()).thenReturn(Arrays.asList(cache));
128
129 when(projectMock.getBasedir()).thenReturn(new File("."));
130
131
132 TestMojo testMojo = new TestMojo();
133 testMojo.setAnyObject("true");
134
135 assertTrue(
136 strategy.isParamsMatched(projectMock, executionMock, testMojo, cacheRecordMock),
137 "If property set to 'skipValue' mismatch could be ignored because cached build"
138 + " is more complete than requested build");
139 }
140
141 @Test
142 void testDefaultValue() {
143
144 String propertyName = "anyObject";
145
146 TrackedProperty config = new TrackedProperty();
147 config.setPropertyName(propertyName);
148 config.setDefaultValue("defaultValue");
149
150
151 PropertyValue cache = new PropertyValue();
152 cache.setName(propertyName);
153 cache.setValue(null);
154
155 when(cacheConfigMock.getTrackedProperties(executionMock)).thenReturn(Arrays.asList(config));
156 when(cacheRecordMock.getProperties()).thenReturn(Arrays.asList(cache));
157
158 when(projectMock.getBasedir()).thenReturn(new File("."));
159
160
161 TestMojo testMojo = new TestMojo();
162 testMojo.setAnyObject("defaultValue");
163
164 assertTrue(
165 strategy.isParamsMatched(projectMock, executionMock, testMojo, cacheRecordMock),
166 "If property has defaultValue it must be matched even if cache record has no this field");
167 }
168
169 @Test
170 void testMismatch() {
171
172 String propertyName = "anyObject";
173
174 TrackedProperty config = new TrackedProperty();
175 config.setPropertyName(propertyName);
176
177
178 PropertyValue cache = new PropertyValue();
179 cache.setName(propertyName);
180 cache.setValue("1");
181
182 when(cacheConfigMock.getTrackedProperties(executionMock)).thenReturn(Arrays.asList(config));
183 when(cacheRecordMock.getProperties()).thenReturn(Arrays.asList(cache));
184
185 when(projectMock.getBasedir()).thenReturn(new File("."));
186
187
188 TestMojo testMojo = new TestMojo();
189 testMojo.setAnyObject("2");
190
191 assertFalse(strategy.isParamsMatched(projectMock, executionMock, testMojo, cacheRecordMock));
192 }
193
194 @NotNull
195 private Pair<TrackedProperty, PropertyValue> setupProperty(String propertyName, String value) {
196 TrackedProperty config = new TrackedProperty();
197 config.setPropertyName(propertyName);
198
199 PropertyValue cache = new PropertyValue();
200 cache.setName(propertyName);
201 cache.setValue(value);
202
203 return Pair.of(config, cache);
204 }
205 }
206 }