MavenMetadataSourceRelocationTest.java
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.project.artifact;
import java.util.Collections;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.metadata.ResolutionGroup;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager;
import org.apache.maven.bridge.MavenRepositorySystem;
import org.apache.maven.model.DistributionManagement;
import org.apache.maven.model.Relocation;
import org.apache.maven.plugin.LegacySupport;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.project.ProjectBuildingResult;
import org.apache.maven.repository.legacy.metadata.DefaultMetadataResolutionRequest;
import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest;
import org.eclipse.aether.RepositorySystemSession;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Verifies that a relocation read from a resolved project's distribution management is validated before its
* components are applied to the artifact and project being resolved, exercising the real
* {@link MavenMetadataSource#retrieve(MetadataResolutionRequest)} code path with mocked collaborators (no
* on-disk artifact resolution, so this test does not depend on, or share, any module-level local repository).
*/
class MavenMetadataSourceRelocationTest {
private MavenMetadataSource newSource(ProjectBuilder projectBuilder) {
ArtifactFactory artifactFactory = mock(ArtifactFactory.class);
when(artifactFactory.createProjectArtifact(any(), any(), any(), any()))
.thenAnswer(invocation -> new DefaultArtifact(
(String) invocation.getArgument(0),
(String) invocation.getArgument(1),
(String) invocation.getArgument(2),
(String) invocation.getArgument(3),
"pom",
null,
new DefaultArtifactHandler("pom")));
LegacySupport legacySupport = mock(LegacySupport.class);
RepositorySystemSession repositorySession = mock(RepositorySystemSession.class);
when(legacySupport.getRepositorySession()).thenReturn(repositorySession);
when(legacySupport.getSession()).thenReturn(null);
return new MavenMetadataSource(
mock(RepositoryMetadataManager.class),
artifactFactory,
projectBuilder,
mock(MavenMetadataCache.class),
legacySupport,
mock(MavenRepositorySystem.class));
}
private static Artifact newArtifact(String groupId, String artifactId, String version) {
return new DefaultArtifact(
groupId, artifactId, version, Artifact.SCOPE_COMPILE, "pom", null, new DefaultArtifactHandler("pom"));
}
private static MavenProject newProject(String groupId, String artifactId, String version, Relocation relocation) {
MavenProject project = new MavenProject();
project.setGroupId(groupId);
project.setArtifactId(artifactId);
project.setVersion(version);
if (relocation != null) {
DistributionManagement distMgmt = new DistributionManagement();
distMgmt.setRelocation(relocation);
project.setDistributionManagement(distMgmt);
}
return project;
}
private static MetadataResolutionRequest newRequest(Artifact artifact) {
MetadataResolutionRequest request = new DefaultMetadataResolutionRequest();
request.setArtifact(artifact);
request.setLocalRepository(mock(ArtifactRepository.class));
request.setRemoteRepositories(Collections.emptyList());
return request;
}
@Test
void testRelocationInvalidArtifactIdIsRejected() throws Exception {
Relocation relocation = new Relocation();
relocation.setArtifactId("a/b");
MavenProject relocatingProject = newProject("group", "original", "1.0", relocation);
MavenProject finalProject = newProject("group", "a/b", "1.0", null);
ProjectBuildingResult first = mock(ProjectBuildingResult.class);
when(first.getProject()).thenReturn(relocatingProject);
ProjectBuildingResult second = mock(ProjectBuildingResult.class);
when(second.getProject()).thenReturn(finalProject);
ProjectBuilder projectBuilder = mock(ProjectBuilder.class);
when(projectBuilder.build(any(Artifact.class), any(ProjectBuildingRequest.class)))
.thenReturn(first, second);
MavenMetadataSource source = newSource(projectBuilder);
Artifact artifact = newArtifact("group", "original", "1.0");
MetadataResolutionRequest request = newRequest(artifact);
ArtifactMetadataRetrievalException exception =
assertThrows(ArtifactMetadataRetrievalException.class, () -> source.retrieve(request));
assertEquals(true, exception.getMessage().contains("a/b"));
assertEquals(true, exception.getMessage().contains("artifactId"));
}
@Test
void testWellFormedRelocationIsApplied() throws Exception {
Relocation relocation = new Relocation();
relocation.setGroupId("group.moved");
relocation.setArtifactId("artifact-moved");
relocation.setVersion("2.0");
MavenProject relocatingProject = newProject("group", "original", "1.0", relocation);
MavenProject finalProject = newProject("group.moved", "artifact-moved", "2.0", null);
ProjectBuildingResult first = mock(ProjectBuildingResult.class);
when(first.getProject()).thenReturn(relocatingProject);
ProjectBuildingResult second = mock(ProjectBuildingResult.class);
when(second.getProject()).thenReturn(finalProject);
ProjectBuilder projectBuilder = mock(ProjectBuilder.class);
when(projectBuilder.build(any(Artifact.class), any(ProjectBuildingRequest.class)))
.thenReturn(first, second);
MavenMetadataSource source = newSource(projectBuilder);
Artifact artifact = newArtifact("group", "original", "1.0");
MetadataResolutionRequest request = newRequest(artifact);
ResolutionGroup result = source.retrieve(request);
assertEquals("group.moved", artifact.getGroupId());
assertEquals("artifact-moved", artifact.getArtifactId());
assertEquals("2.0", artifact.getVersion());
assertEquals(artifact, result.getRelocatedArtifact());
}
}