1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.buildcache.checksum;
20
21 import java.lang.reflect.Method;
22 import java.nio.charset.StandardCharsets;
23 import java.nio.file.Files;
24 import java.nio.file.Path;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.Properties;
29 import java.util.SortedMap;
30
31 import org.apache.maven.artifact.handler.ArtifactHandler;
32 import org.apache.maven.buildcache.MultiModuleSupport;
33 import org.apache.maven.buildcache.NormalizedModelProvider;
34 import org.apache.maven.buildcache.ProjectInputCalculator;
35 import org.apache.maven.buildcache.RemoteCacheRepository;
36 import org.apache.maven.buildcache.hash.HashFactory;
37 import org.apache.maven.buildcache.xml.CacheConfig;
38 import org.apache.maven.buildcache.xml.build.DigestItem;
39 import org.apache.maven.buildcache.xml.build.ProjectsInputInfo;
40 import org.apache.maven.execution.MavenSession;
41 import org.apache.maven.model.Dependency;
42 import org.apache.maven.project.MavenProject;
43 import org.eclipse.aether.RepositorySystem;
44 import org.eclipse.aether.RepositorySystemSession;
45 import org.junit.jupiter.api.BeforeEach;
46 import org.junit.jupiter.api.Test;
47 import org.junit.jupiter.api.extension.ExtendWith;
48 import org.junit.jupiter.api.io.TempDir;
49 import org.mockito.Mock;
50 import org.mockito.junit.jupiter.MockitoExtension;
51 import org.mockito.junit.jupiter.MockitoSettings;
52 import org.mockito.quality.Strictness;
53
54 import static org.junit.jupiter.api.Assertions.assertEquals;
55 import static org.mockito.Mockito.mock;
56 import static org.mockito.Mockito.never;
57 import static org.mockito.Mockito.verify;
58 import static org.mockito.Mockito.when;
59
60
61
62
63
64
65 @ExtendWith(MockitoExtension.class)
66 @MockitoSettings(strictness = Strictness.LENIENT)
67 class MavenProjectInputReactorAndSystemScopeRegressionTest {
68
69 @Mock
70 private MavenProject project;
71
72 @Mock
73 private MavenSession session;
74
75 @Mock
76 private RepositorySystem repoSystem;
77
78 @Mock
79 private RepositorySystemSession repositorySystemSession;
80
81 @Mock
82 private NormalizedModelProvider normalizedModelProvider;
83
84 @Mock
85 private MultiModuleSupport multiModuleSupport;
86
87 @Mock
88 private ProjectInputCalculator projectInputCalculator;
89
90 @Mock
91 private CacheConfig config;
92
93 @Mock
94 private RemoteCacheRepository remoteCache;
95
96 @Mock
97 private org.apache.maven.artifact.handler.manager.ArtifactHandlerManager artifactHandlerManager;
98
99 @TempDir
100 Path tempDir;
101
102 private MavenProjectInput mavenProjectInput;
103
104 @BeforeEach
105 void setUp() {
106 when(session.getRepositorySession()).thenReturn(repositorySystemSession);
107 when(project.getBasedir()).thenReturn(tempDir.toFile());
108 when(project.getProperties()).thenReturn(new Properties());
109 when(config.getDefaultGlob()).thenReturn("*");
110 when(config.isProcessPlugins()).thenReturn("false");
111 when(config.getGlobalExcludePaths()).thenReturn(new ArrayList<>());
112 when(config.calculateProjectVersionChecksum()).thenReturn(Boolean.FALSE);
113 when(config.getHashFactory()).thenReturn(HashFactory.SHA1);
114
115 org.apache.maven.model.Build build = new org.apache.maven.model.Build();
116 build.setDirectory(tempDir.toString());
117 build.setOutputDirectory(tempDir.resolve("target/classes").toString());
118 build.setTestOutputDirectory(tempDir.resolve("target/test-classes").toString());
119 build.setSourceDirectory(tempDir.resolve("src/main/java").toString());
120 build.setTestSourceDirectory(tempDir.resolve("src/test/java").toString());
121 build.setResources(new ArrayList<>());
122 build.setTestResources(new ArrayList<>());
123 when(project.getBuild()).thenReturn(build);
124
125 when(project.getDependencies()).thenReturn(new ArrayList<>());
126 when(project.getBuildPlugins()).thenReturn(new ArrayList<>());
127 when(project.getModules()).thenReturn(new ArrayList<>());
128 when(project.getPackaging()).thenReturn("jar");
129
130 ArtifactHandler handler = mock(ArtifactHandler.class);
131 when(handler.getClassifier()).thenReturn(null);
132 when(handler.getExtension()).thenReturn("jar");
133 when(artifactHandlerManager.getArtifactHandler(org.mockito.ArgumentMatchers.anyString()))
134 .thenReturn(handler);
135
136 mavenProjectInput = new MavenProjectInput(
137 project,
138 normalizedModelProvider,
139 multiModuleSupport,
140 projectInputCalculator,
141 session,
142 config,
143 repoSystem,
144 remoteCache,
145 artifactHandlerManager);
146 }
147
148 @Test
149 void testSystemScopeDependencyHashedFromSystemPathWithoutAetherResolution() throws Exception {
150 Path systemJar = tempDir.resolve("local-lib.jar");
151 Files.write(systemJar, "abc".getBytes(StandardCharsets.UTF_8));
152
153 Dependency dependency = new Dependency();
154 dependency.setGroupId("com.example");
155 dependency.setArtifactId("local-lib");
156 dependency.setVersion("1.0");
157 dependency.setType("jar");
158 dependency.setScope("system");
159 dependency.setSystemPath(systemJar.toString());
160 dependency.setOptional(true);
161
162 Method resolveArtifact = MavenProjectInput.class.getDeclaredMethod("resolveArtifact", Dependency.class);
163 resolveArtifact.setAccessible(true);
164 DigestItem digest = (DigestItem) resolveArtifact.invoke(mavenProjectInput, dependency);
165
166 String expectedHash = HashFactory.SHA1.createAlgorithm().hash(systemJar);
167 assertEquals(expectedHash, digest.getHash());
168
169 verify(repoSystem, never())
170 .resolveArtifact(org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any());
171 }
172
173 @Test
174 void testDynamicVersionReactorDependencyUsesProjectChecksumAndAvoidsAetherResolution() throws Exception {
175 Dependency dependency = new Dependency();
176 dependency.setGroupId("com.example");
177 dependency.setArtifactId("reactor-artifact");
178 dependency.setVersion("LATEST");
179 dependency.setType("jar");
180
181 when(multiModuleSupport.tryToResolveProject("com.example", "reactor-artifact", "LATEST"))
182 .thenReturn(java.util.Optional.empty());
183
184 MavenProject reactorProject = mock(MavenProject.class);
185 when(reactorProject.getGroupId()).thenReturn("com.example");
186 when(reactorProject.getArtifactId()).thenReturn("reactor-artifact");
187 when(reactorProject.getVersion()).thenReturn("1.0-SNAPSHOT");
188 when(session.getAllProjects()).thenReturn(Collections.singletonList(reactorProject));
189
190 ProjectsInputInfo projectInfo = mock(ProjectsInputInfo.class);
191 when(projectInfo.getChecksum()).thenReturn("reactorChecksum");
192 when(projectInputCalculator.calculateInput(reactorProject)).thenReturn(projectInfo);
193
194 Method getMutableDependenciesHashes =
195 MavenProjectInput.class.getDeclaredMethod("getMutableDependenciesHashes", String.class, List.class);
196 getMutableDependenciesHashes.setAccessible(true);
197
198 SortedMap<String, String> hashes = (SortedMap<String, String>)
199 getMutableDependenciesHashes.invoke(mavenProjectInput, "", Collections.singletonList(dependency));
200
201 assertEquals("reactorChecksum", hashes.get("com.example:reactor-artifact:jar"));
202
203 verify(repoSystem, never())
204 .resolveArtifact(org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any());
205 verify(projectInputCalculator).calculateInput(reactorProject);
206 }
207 }