diff --git a/src/test/java/org/openrewrite/java/dependencies/DependencyResolutionDiagnosticTest.java b/src/test/java/org/openrewrite/java/dependencies/DependencyResolutionDiagnosticTest.java
index 3367eb62..f57bb3e1 100644
--- a/src/test/java/org/openrewrite/java/dependencies/DependencyResolutionDiagnosticTest.java
+++ b/src/test/java/org/openrewrite/java/dependencies/DependencyResolutionDiagnosticTest.java
@@ -17,6 +17,7 @@
import org.junit.jupiter.api.Test;
import org.openrewrite.DocumentExample;
+import org.openrewrite.ExecutionContext;
import org.openrewrite.InMemoryExecutionContext;
import org.openrewrite.Parser;
import org.openrewrite.java.dependencies.table.RepositoryAccessibilityReport;
@@ -27,12 +28,18 @@
import java.io.ByteArrayInputStream;
import java.nio.file.Path;
+import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.openrewrite.gradle.Assertions.buildGradle;
import static org.openrewrite.gradle.toolingapi.Assertions.withToolingApi;
import static org.openrewrite.maven.Assertions.pomXml;
+/**
+ * Which URL Maven Central and the Gradle Plugin Portal are reached at depends on the machine the tests run on: where
+ * CI names a mirror in MAVEN_CENTRAL_MIRROR_URL, the mirror stands in for both. So these tests check the repositories
+ * they declare themselves by URL, and Central and the plugin portal only by being reachable.
+ */
@SuppressWarnings("GroovyAssignabilityCheck")
class DependencyResolutionDiagnosticTest implements RewriteTest {
@@ -68,15 +75,11 @@ void gradle() {
// It is a limitation of the tooling API which prevents configuration-granularity error information from being collected.
// So the GradleDependencyConfigurationErrors table will never be populated in unit tests.
.dataTable(RepositoryAccessibilityReport.Row.class, rows -> {
- assertThat(rows)
- .hasSize(4)
- .contains(
- new RepositoryAccessibilityReport.Row("https://repo.maven.apache.org/maven2", "", "", 200, "", ""));
assertThat(rows).filteredOn(row -> row.getUri().startsWith("file:/") && "".equals(row.getPingExceptionMessage())).hasSize(1);
- assertThat(rows).contains(
- new RepositoryAccessibilityReport.Row("https://plugins.gradle.org/m2", "", "", 200, "", ""));
assertThat(rows)
.filteredOn(row -> "https://nonexistent.moderne.io/maven2".equals(row.getUri()) && row.getPingHttpCode() == null).hasSize(1);
+ // Maven Central and the plugin portal, which are one row where a mirror stands in for both
+ assertThat(remote(rows)).hasSizeBetween(1, 2).allSatisfy(DependencyResolutionDiagnosticTest::reachable);
}),
//language=groovy
buildGradle(
@@ -107,12 +110,14 @@ void gradleNoDefaultRepos() {
spec -> spec.beforeRecipe(withToolingApi())
// It is a limitation of the tooling API which prevents configuration-granularity error information from being collected.
// So the GradleDependencyConfigurationErrors table will never be populated in unit tests.
- .dataTable(RepositoryAccessibilityReport.Row.class, rows -> assertThat(rows)
- .hasSize(2)
- .contains(
- new RepositoryAccessibilityReport.Row("https://plugins.gradle.org/m2", "", "", 200, "", ""))
- .contains(
- new RepositoryAccessibilityReport.Row("https://nonexistent.moderne.io/maven2", "java.net.UnknownHostException", "nonexistent.moderne.io", null, "", ""))),
+ .dataTable(RepositoryAccessibilityReport.Row.class, rows -> {
+ assertThat(rows)
+ .hasSize(2)
+ .contains(
+ new RepositoryAccessibilityReport.Row("https://nonexistent.moderne.io/maven2", "java.net.UnknownHostException", "nonexistent.moderne.io", null, "", ""));
+ // The plugin portal, which Gradle adds
+ assertThat(remote(rows)).singleElement().satisfies(DependencyResolutionDiagnosticTest::reachable);
+ }),
//language=groovy
buildGradle(
"""
@@ -182,19 +187,19 @@ void maven() {
spec -> {
// CI may inject ~/.m2/settings.xml with `*` to route Maven through a cache.
// That rewrites the pom-declared `nonexistent` repo to the mirror URL, so neither Maven Central
- // nor the test's `nonexistent.moderne.io` repo appear in the diagnostic. Force empty settings
- // here so the recipe sees the pom-declared repositories directly.
+ // nor the test's `nonexistent.moderne.io` repo appear in the diagnostic. Use settings of the test's
+ // own here, so the recipe sees the pom-declared repositories directly.
MavenExecutionContextView ctx = MavenExecutionContextView.view(new InMemoryExecutionContext());
- ctx.setMavenSettings(new MavenSettings(null, null, null, null, null, null));
+ ctx.setMavenSettings(settingsMirroringOnlyCentral(ctx));
spec
.executionContext(ctx)
.dataTable(RepositoryAccessibilityReport.Row.class, rows -> {
- assertThat(rows).contains(
- new RepositoryAccessibilityReport.Row("https://repo.maven.apache.org/maven2", "", "", 200, "", ""));
assertThat(rows).filteredOn(row -> row.getUri().startsWith("file:/") && "".equals(row.getPingExceptionMessage())).hasSize(1);
assertThat(rows).contains(
new RepositoryAccessibilityReport.Row("https://nonexistent.moderne.io/maven2", "java.net.UnknownHostException", "nonexistent.moderne.io", null, "", "")
);
+ // Maven Central, which the recipe adds
+ assertThat(remote(rows)).singleElement().satisfies(DependencyResolutionDiagnosticTest::reachable);
});
},
//language=xml
@@ -223,11 +228,14 @@ void dependencyNotFound() {
spec -> spec.recipe(new DependencyResolutionDiagnostic("org.nonexistent", "nonexistent", "0"))
.beforeRecipe(withToolingApi())
.dataTable(RepositoryAccessibilityReport.Row.class, rows ->
- assertThat(rows).contains(
- new RepositoryAccessibilityReport.Row("https://repo.maven.apache.org/maven2",
- "", "", 200, "org.openrewrite.maven.MavenDownloadingException",
- "org.nonexistent:nonexistent:0 failed. Unable to download POM: org.nonexistent:nonexistent:0. Tried repositories:\nhttps://repo.maven.apache.org/maven2/: HTTP 404")
- )
+ // Maven Central, which is reachable but has no such dependency
+ assertThat(rows).anySatisfy(row -> {
+ reachable(row);
+ assertThat(row.getDependencyResolveExceptionType()).isEqualTo("org.openrewrite.maven.MavenDownloadingException");
+ assertThat(row.getDependencyResolveExceptionMessage())
+ .startsWith("org.nonexistent:nonexistent:0 failed. Unable to download POM: org.nonexistent:nonexistent:0. Tried repositories:\n" + row.getUri())
+ .endsWith(": HTTP 404");
+ })
),
//language=groovy
buildGradle(
@@ -242,4 +250,46 @@ void dependencyNotFound() {
)
);
}
+
+ /** The rows of the repositories other than the local one and the one that doesn't exist. */
+ private static List remote(List rows) {
+ return rows.stream()
+ .filter(row -> !row.getUri().startsWith("file:/") && !row.getUri().contains("nonexistent.moderne.io"))
+ .toList();
+ }
+
+ private static void reachable(RepositoryAccessibilityReport.Row row) {
+ assertThat(row.getPingHttpCode()).as("what %s answered", row.getUri()).isEqualTo(200);
+ assertThat(row.getPingExceptionType()).as("what reaching %s threw", row.getUri()).isEmpty();
+ }
+
+ /**
+ * Settings with no mirror but one of Maven Central, the mirror CI names in MAVEN_CENTRAL_MIRROR_URL, _USERNAME and
+ * _PASSWORD, so that Central is reached as the rest of the build reaches it. With no mirror named, none at all.
+ */
+ private static MavenSettings settingsMirroringOnlyCentral(ExecutionContext ctx) {
+ if (System.getenv("MAVEN_CENTRAL_MIRROR_URL") == null) {
+ return new MavenSettings(null, null, null, null, null, null);
+ }
+ return MavenSettings.parse(new Parser.Input(Path.of("settings.xml"), () -> new ByteArrayInputStream(
+ //language=xml
+ """
+
+
+
+ central-mirror
+ ${env.MAVEN_CENTRAL_MIRROR_USERNAME}
+ ${env.MAVEN_CENTRAL_MIRROR_PASSWORD}
+
+
+
+
+ central-mirror
+ central
+ ${env.MAVEN_CENTRAL_MIRROR_URL}
+
+
+
+ """.getBytes())), ctx);
+ }
}