Skip to content

Commit

Permalink
Simplify and speed up verification tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mhalbritter committed Dec 11, 2024
1 parent 1275f99 commit 60689d8
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,21 @@
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.spi.locator.ServiceLocator;
import org.eclipse.aether.transfer.AbstractTransferListener;
import org.eclipse.aether.transfer.TransferEvent;
import org.eclipse.aether.transfer.TransferResource;
import org.eclipse.aether.transport.http.HttpTransporterFactory;
import org.eclipse.aether.util.artifact.JavaScopes;
import org.eclipse.aether.util.filter.DependencyFilterUtils;
import org.eclipse.aether.util.graph.visitor.FilteringDependencyVisitor;
import org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

final class DependencyResolver {

private static final Logger LOGGER = LoggerFactory.getLogger(DependencyResolver.class);

static final RemoteRepository mavenCentral = createRemoteRepository("central", "https://repo1.maven.org/maven2",
false);

Expand All @@ -70,12 +77,14 @@ final class DependencyResolver {
try {
ServiceLocator serviceLocator = createServiceLocator();
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
session.setTransferListener(new Slf4jTransferListener());
session.setArtifactDescriptorPolicy(new SimpleArtifactDescriptorPolicy(false, false));
LocalRepository localRepository = new LocalRepository(localRepositoryLocation.toFile());
this.repositorySystem = serviceLocator.getService(RepositorySystem.class);
session
.setLocalRepositoryManager(this.repositorySystem.newLocalRepositoryManager(session, localRepository));
session.setUserProperties(System.getProperties());
session.setIgnoreArtifactDescriptorRepositories(true);
session.setReadOnly();
this.repositorySystemSession = session;
}
Expand All @@ -98,24 +107,18 @@ static RemoteRepository createRemoteRepository(String id, String url, boolean sn

static List<String> resolveDependencies(Homes homes, String groupId, String artifactId, String version,
List<BillOfMaterials> boms, List<RemoteRepository> repositories) {
Path home = homes.acquire();
DependencyResolver resolver = new DependencyResolver(homes.get().resolve("repository"));
List<Dependency> managedDependencies = resolver.getManagedDependencies(boms, repositories);
Dependency aetherDependency = new Dependency(new DefaultArtifact(groupId, artifactId, "pom",
resolver.getVersion(groupId, artifactId, version, managedDependencies)), "compile");
CollectRequest collectRequest = new CollectRequest(aetherDependency, repositories);
collectRequest.setManagedDependencies(managedDependencies);
try {
DependencyResolver instance = new DependencyResolver(home.resolve("repository"));
List<Dependency> managedDependencies = instance.getManagedDependencies(boms, repositories);
Dependency aetherDependency = new Dependency(new DefaultArtifact(groupId, artifactId, "pom",
instance.getVersion(groupId, artifactId, version, managedDependencies)), "compile");
CollectRequest collectRequest = new CollectRequest(aetherDependency, repositories);
collectRequest.setManagedDependencies(managedDependencies);
try {
CollectResult result = instance.collectDependencies(collectRequest);
return DependencyCollector.collect(result.getRoot(), RuntimeTransitiveOnlyDependencyFilter.INSTANCE);
}
catch (DependencyCollectionException ex) {
throw new RuntimeException(ex);
}
CollectResult result = resolver.collectDependencies(collectRequest);
return DependencyCollector.collect(result.getRoot(), RuntimeTransitiveOnlyDependencyFilter.INSTANCE);
}
finally {
homes.release(home);
catch (DependencyCollectionException ex) {
throw new RuntimeException(ex);
}
}

Expand Down Expand Up @@ -149,6 +152,7 @@ private List<Dependency> resolveManagedDependencies(String groupId, String artif
}

private CollectResult collectDependencies(CollectRequest dependencyRequest) throws DependencyCollectionException {
LOGGER.info("Resolving {} from {}", dependencyRequest.getRoot(), dependencyRequest.getRepositories());
return this.repositorySystem.collectDependencies(this.repositorySystemSession, dependencyRequest);
}

Expand Down Expand Up @@ -210,4 +214,33 @@ public boolean accept(DependencyNode node, List<DependencyNode> parents) {

}

private static final class Slf4jTransferListener extends AbstractTransferListener {

@Override
public void transferStarted(TransferEvent event) {
LOGGER.info("Started downloading {}", resourceToString(event.getResource()));
}

@Override
public void transferCorrupted(TransferEvent event) {
LOGGER.warn("Found corrupted download {}", resourceToString(event.getResource()));
}

@Override
public void transferSucceeded(TransferEvent event) {
LOGGER.info("Done downloading {} bytes for {}", event.getTransferredBytes(),
resourceToString(event.getResource()));
}

@Override
public void transferFailed(TransferEvent event) {
LOGGER.info("Failed downloading {}", resourceToString(event.getResource()));
}

private String resourceToString(TransferResource resource) {
return resource.getRepositoryUrl() + resource.getResourceName();
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import io.spring.initializr.generator.version.Version;
Expand Down Expand Up @@ -60,6 +61,8 @@
@ActiveProfiles("test")
class MetadataVerificationTests {

private static final Pattern MILESTONE_PATTERN = Pattern.compile("M\\d+");

private final InitializrMetadata metadata;

MetadataVerificationTests(@Autowired InitializrMetadataProvider metadataProvider) {
Expand Down Expand Up @@ -138,11 +141,11 @@ private List<RemoteRepository> getRepositories(Dependency dependency, Version bo
}
if (bootVersion.getQualifier() != null) {
String qualifier = bootVersion.getQualifier().getId();
if (!qualifier.equals("RELEASE")) {
if (qualifier.contains("SNAPSHOT")) {
repositories.computeIfAbsent("spring-snapshots", this::repositoryForId);
}
else if (MILESTONE_PATTERN.matcher(qualifier).matches()) {
repositories.computeIfAbsent("spring-milestones", this::repositoryForId);
if (qualifier.contains("SNAPSHOT")) {
repositories.computeIfAbsent("spring-snapshots", this::repositoryForId);
}
}
}
return new ArrayList<>(repositories.values());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,37 +130,24 @@ void projectBuilds(Version bootVersion, Packaging packaging, Language language,
request.setApplicationName("DemoApplication");
request.setDependencies(Arrays.asList("devtools", "configuration-processor"));
Path project = this.invoker.invokeProjectStructureGeneration(request).getRootDirectory();
Path home = acquireHome(buildSystem);
try {
ProcessBuilder processBuilder = createProcessBuilder(project, buildSystem, home);
Path output = TemporaryFiles.newTemporaryDirectory("ProjectGenerationIntegrationTests-projectBuilds")
.resolve("output.log");
processBuilder.redirectError(output.toFile());
processBuilder.redirectOutput(output.toFile());
assertThat(processBuilder.start().waitFor()).describedAs(String.join("\n", Files.readAllLines(output)))
.isEqualTo(0);
}
finally {
releaseHome(buildSystem, home);
}
Path home = getHome(buildSystem);
ProcessBuilder processBuilder = createProcessBuilder(project, buildSystem, home);
Path output = TemporaryFiles.newTemporaryDirectory("ProjectGenerationIntegrationTests-projectBuilds")
.resolve("output.log");
processBuilder.redirectError(output.toFile());
processBuilder.redirectOutput(output.toFile());
assertThat(processBuilder.start().waitFor()).describedAs(String.join("\n", Files.readAllLines(output)))
.isEqualTo(0);
}

private Path acquireHome(BuildSystem buildSystem) {
private Path getHome(BuildSystem buildSystem) {
return switch (buildSystem.id()) {
case MavenBuildSystem.ID -> Homes.MAVEN.acquire();
case GradleBuildSystem.ID -> Homes.GRADLE.acquire();
case MavenBuildSystem.ID -> Homes.MAVEN.get();
case GradleBuildSystem.ID -> Homes.GRADLE.get();
default -> throw new IllegalStateException("Unknown build system '%s'".formatted(buildSystem.id()));
};
}

private void releaseHome(BuildSystem buildSystem, Path home) {
switch (buildSystem.id()) {
case MavenBuildSystem.ID -> Homes.MAVEN.release(home);
case GradleBuildSystem.ID -> Homes.GRADLE.release(home);
default -> throw new IllegalStateException("Unknown build system '%s'".formatted(buildSystem.id()));
}
}

private ProcessBuilder createProcessBuilder(Path directory, BuildSystem buildSystem, Path home) {
if (buildSystem.id().equals(MavenBuildSystem.ID)) {
String command = (isWindows()) ? "mvnw.cmd" : "mvnw";
Expand Down
46 changes: 8 additions & 38 deletions test-support/src/main/java/io/spring/start/testsupport/Homes.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;

import org.springframework.util.Assert;

/**
* Manages Maven and Gradle home directories.
Expand All @@ -48,46 +41,23 @@ public class Homes {
*/
public static final Homes GRADLE = new Homes("gradle-home");

private final Set<Path> homes = ConcurrentHashMap.newKeySet();

private final Queue<Path> freeHomes = new ConcurrentLinkedQueue<>();

private final AtomicInteger counter = new AtomicInteger();
private final Path path;

private final String prefix;

public Homes(String prefix) {
this.prefix = prefix;
Homes(String name) {
this.path = createTempDirectory(name);
}

/**
* Acquires a path to the home. Callers are responsible to call {@link #release(Path)}
* when done.
* Returns the path to the home.
* @return the path to the home
*/
public Path acquire() {
Path home = this.freeHomes.poll();
if (home == null) {
home = createTempDirectory();
this.homes.add(home);
}
return home;
}

/**
* Releases a path to the home.
* @param home the path to the home
*/
public void release(Path home) {
Assert.state(this.homes.contains(home), "Invalid home '%s'".formatted(home));
this.freeHomes.add(home);
public Path get() {
return this.path;
}

private Path createTempDirectory() {
private static Path createTempDirectory(String name) {
try {
Path path = TemporaryFiles.getTempDir()
.resolve("homes")
.resolve(this.prefix + "-" + this.counter.getAndIncrement());
Path path = TemporaryFiles.getTempDir().resolve("homes").resolve(name);
Files.createDirectories(path);
return path;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

package io.spring.start.testsupport;

import java.nio.file.Path;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
Expand All @@ -30,14 +28,14 @@
class HomesTests {

@Test
void shouldAcquireNewHome() {
Homes homes = new Homes("test");
Path home1 = homes.acquire();
Path home2 = homes.acquire();
assertThat(home1).isNotEqualTo(home2);
homes.release(home1);
Path home3 = homes.acquire();
assertThat(home3).isEqualTo(home1);
void shouldGetNewHome() {
Homes test1 = new Homes("test1");
Homes test1Again = new Homes("test1");
Homes test2 = new Homes("test2");
assertThat(test1.get()).isEmptyDirectory();
assertThat(test1.get()).isEqualTo(test1.get());
assertThat(test1.get()).isEqualTo(test1Again.get());
assertThat(test1.get()).isNotEqualTo(test2.get());
}

}

0 comments on commit 60689d8

Please sign in to comment.