This is an automated email from the ASF dual-hosted git repository.

epugh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr-mcp.git


The following commit(s) were added to refs/heads/main by this push:
     new 93ffdb79 build(test): pin Testcontainers images in the version catalog 
(#199)
93ffdb79 is described below

commit 93ffdb79f43009f916060fee8d2aa13811145b71
Author: Aditya Parikh <[email protected]>
AuthorDate: Wed Sep 16 14:03:50 2026 -0400

    build(test): pin Testcontainers images in the version catalog (#199)
    
    * test(observability): re-enable OtlpExportIntegrationTest
    
    The class had been @Disabled since #41 because starting the Grafana LGTM
    Testcontainer threw a ClassNotFoundException for
    org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP. The Jetty
    pin has since moved with the SolrJ 10 bump, jetty-client 12.0.34 is on the
    test runtime classpath and contains that class, and the container now
    starts cleanly.
    
    With the annotation removed, three methods failed with
    AuthenticationCredentialsNotFoundException: the test calls @PreAuthorize
    service methods directly, with no MCP request and hence no principal. Rather
    than switch http.security.enabled off, the test authenticates its own thread
    with a TestingAuthenticationToken in @BeforeEach and clears it in
    @AfterEach, so method security stays active while OTLP export is verified.
    
    All seven methods pass; the build no longer reports any skipped tests.
    
    Co-Authored-By: Claude Fable 5.1 <[email protected]>
    Claude-Session: https://claude.ai/code/session_019zJ9WA8nNyA5Yxb8ueM7vV
    Signed-off-by: Aditya Parikh <[email protected]>
    
    * build(test): pin Testcontainers images in the version catalog
    
    Pin the Solr and Grafana LGTM images the tests start to exact tags,
    solr:9.9.0-slim and grafana/otel-lgtm:0.33.0, declared once as
    test-image-solr / test-image-lgtm in gradle/libs.versions.toml. Previously
    the Solr default was spelled out three times and the LGTM image floated on
    latest: the locally cached "latest" was 0.28.0 from May while Docker Hub's
    had moved to 0.33.0, so the same test run meant different things on
    different machines.
    
    processTestResources expands the pins into test-images.properties and the
    Gradle test tasks also forward them as system properties. A new TestImages
    resolver prefers a non-blank -Dsolr.test.image / -Dlgtm.test.image, so the
    Solr compatibility matrix keeps working, and falls back to the resource
    otherwise; the resource is included in the native test binary explicitly.
    TestImagesTest fails the build if a pin is missing, floats on latest, or is
    not an exact release tag.
    
    Verified: ./gradlew build 407 tests, 0 failures, 0 skipped;
    ./gradlew nativeTest -Pnative 405 tests, 0 failures, 138 skipped (Mockito).
    
    Co-Authored-By: Claude Fable 5.1 <[email protected]>
    Claude-Session: https://claude.ai/code/session_019zJ9WA8nNyA5Yxb8ueM7vV
    Signed-off-by: Aditya Parikh <[email protected]>
    
    * build(test): read catalog pins directly in TestImagesTest
    
    TestImagesTest cleared the real solr.test.image / lgtm.test.image system
    properties, and Gradle runs every test class in one fork, so any container
    started after it fell back to the catalog pin. The Solr compatibility matrix
    in CI passes -Dsolr.test.image and could end up testing the pinned version
    while reporting another. The pin-guard tests now read the expanded resource
    through TestImages.pinned(key) and never touch system properties; the two
    override tests that covered three lines of resolve() are dropped.
    
    Also hoists the catalog pins to one declaration in build.gradle.kts, removes
    the duplicate systemProperty forwarding on integrationTest (withType<Test>
    already covers it), and stops the docs from demonstrating the moving
    solr:9.9-slim tag as an override example.
    
    Co-Authored-By: Claude Fable 5.1 <[email protected]>
    Claude-Session: https://claude.ai/code/session_01CiUHyyXLTo9ATdgg8eRFZJ
    Signed-off-by: Aditya Parikh <[email protected]>
    
    * test(observability): drop stale disabled-note and redundant 
setAuthenticated
    
    The class javadoc still said the test was disabled for a Jetty
    ClassNotFoundException; that paragraph now describes the LGTM container and
    the self-authenticated test thread. TestingAuthenticationToken's authorities
    constructor already marks the token authenticated, so the explicit call 
goes.
    
    Co-Authored-By: Claude Fable 5.1 <[email protected]>
    Claude-Session: https://claude.ai/code/session_01CiUHyyXLTo9ATdgg8eRFZJ
    Signed-off-by: Aditya Parikh <[email protected]>
    
    * build(test): back out TestImages indirection per review
    
    Eric Pugh asked to back this out: it adds indirection for little value,
    and hides the Docker image name that should be visible right at the
    Testcontainers call, matching the pattern apache/solr itself uses.
    
    TestcontainersConfiguration and OtlpExportIntegrationTest now read
    System.getProperty("solr.test.image"/"lgtm.test.image", <literal pin>)
    directly, so the image is visible in the call and -Dsolr.test.image
    still drives the Solr compatibility matrix in CI. TestImages.java,
    TestImagesTest.java, and the test-images.properties resource (plus its
    native -H:IncludeResources hint) are gone with the class that used
    them. The gradle/libs.versions.toml pins stay as the single declared
    version, with a comment that the call-site literals must be bumped
    alongside them.
    
    Verified: ./gradlew build 403 tests, 0 failures, 0 skipped (JDK 25).
    
    Co-Authored-By: Claude Sonnet 5 <[email protected]>
    Signed-off-by: Aditya Parikh <[email protected]>
    
    ---------
    
    Signed-off-by: Aditya Parikh <[email protected]>
    Co-authored-by: Claude Fable 5.1 <[email protected]>
---
 AGENTS.md                                             |  6 +++---
 build.gradle.kts                                      | 19 +++++++++++++++----
 dev-docs/DEVELOPMENT.md                               |  6 +++---
 gradle/libs.versions.toml                             |  7 +++++++
 .../solr/mcp/server/TestcontainersConfiguration.java  |  4 +++-
 .../observability/OtlpExportIntegrationTest.java      |  5 ++++-
 6 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/AGENTS.md b/AGENTS.md
index 15ddc422..53fd90c6 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -381,12 +381,12 @@ are exercised. The Jib JVM path runs in 
`build-and-publish.yml`.
 
 ### Solr Version Compatibility Testing
 
-The Solr Docker image used in tests is configurable via the `solr.test.image` 
system property (default: `solr:9.9-slim`):
+The Solr Docker image used in tests is pinned as `test-image-solr` in 
`gradle/libs.versions.toml` (the Grafana LGTM image for the OTLP test as 
`test-image-lgtm`), matching the literal default in 
`TestcontainersConfiguration`/`OtlpExportIntegrationTest`. Override the Solr 
image for one run with the `solr.test.image` system property:
 
 ```bash
 ./gradlew test -Dsolr.test.image=solr:8.11-slim    # Solr 8.11
 ./gradlew test -Dsolr.test.image=solr:9.4-slim     # Solr 9.4
-./gradlew test -Dsolr.test.image=solr:9.9-slim     # Solr 9.9 (default)
+./gradlew test -Dsolr.test.image=solr:9.9.0-slim     # Solr 9.9 (the pinned 
default)
 ./gradlew test -Dsolr.test.image=solr:9.10-slim    # Solr 9.10
 ./gradlew test -Dsolr.test.image=solr:10-slim      # Solr 10
 ```
@@ -404,7 +404,7 @@ Remaining known differences from Solr 9:
 - **`/admin/mbeans` removed:** Cache and handler stats from 
`getCollectionStats()` will always be `null` on Solr 10. A future migration to 
`/admin/metrics` will restore these metrics.
 - **Metrics migration:** Dropwizard metrics replaced by OpenTelemetry. Metric 
names switch to snake_case in Solr 10.
 - **SolrJ base URL:** Already uses root URLs — **no change needed**.
-- **SolrJ version:** `solr-solrj` is on 10.0.0 (`gradle/libs.versions.toml`), 
released to Maven Central and bumped in #58. Jetty artifacts are declared 
versionless and managed by Spring Boot's BOM, so there is no separate Jetty pin 
to update. Note the client is *newer* than the default test server: 
`solr.test.image` defaults to `solr:9.9-slim`, so the standard build exercises 
a SolrJ 10 client against Solr 9.9.
+- **SolrJ version:** `solr-solrj` is on 10.0.0 (`gradle/libs.versions.toml`), 
released to Maven Central and bumped in #58. Jetty artifacts are declared 
versionless and managed by Spring Boot's BOM, so there is no separate Jetty pin 
to update. Note the client is *newer* than the default test server: 
`solr.test.image` defaults to `solr:9.9.0-slim`, so the standard build 
exercises a SolrJ 10 client against Solr 9.9.
 
 ## Key Configuration
 
diff --git a/build.gradle.kts b/build.gradle.kts
index 12ede13a..b0933b5e 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -203,6 +203,18 @@ springBoot {
     buildInfo()
 }
 
+// Testcontainers image pins live in gradle/libs.versions.toml; 
-Dsolr.test.image
+// and -Dlgtm.test.image override them for a single run (e.g. the Solr
+// compatibility matrix in CI).
+val solrPin =
+    libs.versions.test.image.solr
+        .get()
+val lgtmPin =
+    libs.versions.test.image.lgtm
+        .get()
+val solrTestImage = System.getProperty("solr.test.image", solrPin)
+val lgtmTestImage = System.getProperty("lgtm.test.image", lgtmPin)
+
 tasks.withType<Test> {
     useJUnitPlatform {
         // Only exclude docker integration tests from regular test runs, not 
from dockerIntegrationTest
@@ -217,8 +229,9 @@ tasks.withType<Test> {
     if (name != "dockerIntegrationTest") {
         dependsOn(tasks.bootJar)
     }
-    // Forward solr.test.image system property to test JVMs for Solr version 
compatibility testing
-    systemProperty("solr.test.image", System.getProperty("solr.test.image", 
"solr:9.9-slim"))
+    // Forward the Testcontainers image pins (or a per-run -D override) to 
test JVMs.
+    systemProperty("solr.test.image", solrTestImage)
+    systemProperty("lgtm.test.image", lgtmTestImage)
     if (name != "dockerIntegrationTest") {
         finalizedBy(tasks.jacocoTestReport)
     }
@@ -254,8 +267,6 @@ tasks.register<Test>("integrationTest") {
     testClassesDirs = sourceSets["test"].output.classesDirs
     classpath = sourceSets["test"].runtimeClasspath
 
-    systemProperty("solr.test.image", System.getProperty("solr.test.image", 
"solr:9.9-slim"))
-
     mustRunAfter(tasks.named("unitTest"))
     finalizedBy(tasks.jacocoTestReport)
 
diff --git a/dev-docs/DEVELOPMENT.md b/dev-docs/DEVELOPMENT.md
index c11def43..88b5afa6 100644
--- a/dev-docs/DEVELOPMENT.md
+++ b/dev-docs/DEVELOPMENT.md
@@ -189,12 +189,12 @@ This runs tests tagged with `@Tag("docker-integration")` 
which verify:
 
 ### Solr Version Compatibility
 
-Tests run against `solr:9.9-slim` by default. Point them at another Solr 
version with the `solr.test.image` system property:
+Tests run against the Solr image pinned as `test-image-solr` in 
`gradle/libs.versions.toml` by default (the LGTM image for the OTLP test is 
pinned there too, as `test-image-lgtm`). Point them at another Solr version 
with the `solr.test.image` system property:
 
 ```bash
 ./gradlew test -Dsolr.test.image=solr:8.11-slim   # Solr 8.11
 ./gradlew test -Dsolr.test.image=solr:9.4-slim    # Solr 9.4
-./gradlew test -Dsolr.test.image=solr:9.9-slim    # Solr 9.9 (default)
+./gradlew test -Dsolr.test.image=solr:9.9.0-slim    # Solr 9.9 (the pinned 
default)
 ./gradlew test -Dsolr.test.image=solr:9.10-slim   # Solr 9.10
 ./gradlew test -Dsolr.test.image=solr:10-slim     # Solr 10
 ```
@@ -205,7 +205,7 @@ Tests run against `solr:9.9-slim` by default. Point them at 
another Solr version
 endpoint was removed in Solr 10, so `getCacheMetrics()`/`getHandlerMetrics()` 
catch
 `RuntimeException` and return `null` — `cacheStats`/`handlerStats` from 
`get-collection-stats`
 are therefore always `null` on Solr 10 (a future migration to `/admin/metrics` 
will restore
-them). SolrJ is on 10.0.0; since `solr.test.image` defaults to 
`solr:9.9-slim`, the standard
+them). SolrJ is on 10.0.0; since the pinned test image is Solr 9.9, the 
standard
 build runs a SolrJ 10 client against a Solr 9.9 server.
 
 ### Test with MCP Inspector
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index ca672722..b5cdc021 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -38,6 +38,13 @@ nullaway = "0.13.1"
 
 # Test dependencies
 testcontainers = "1.21.3"
+# Docker images started by Testcontainers. Exact tags only (never "latest" or a
+# moving minor tag). Forwarded to tests as the solr.test.image / 
lgtm.test.image
+# system properties, which also override them for a single run; the literal
+# default at each Testcontainers call site (TestcontainersConfiguration,
+# OtlpExportIntegrationTest) must be bumped along with these pins.
+test-image-solr = "solr:9.9.0-slim"
+test-image-lgtm = "grafana/otel-lgtm:0.33.0"
 awaitility = "4.3.0"
 opentelemetry-instrumentation-bom = "2.26.1"
 
diff --git 
a/src/test/java/org/apache/solr/mcp/server/TestcontainersConfiguration.java 
b/src/test/java/org/apache/solr/mcp/server/TestcontainersConfiguration.java
index 5f6267a2..ef324e1f 100644
--- a/src/test/java/org/apache/solr/mcp/server/TestcontainersConfiguration.java
+++ b/src/test/java/org/apache/solr/mcp/server/TestcontainersConfiguration.java
@@ -29,7 +29,9 @@ public class TestcontainersConfiguration {
 
        @Bean
        SolrContainer solr() {
-               String solrImage = System.getProperty("solr.test.image", 
"solr:9.9-slim");
+               // Pinned in gradle/libs.versions.toml as test-image-solr; 
-Dsolr.test.image
+               // overrides it for a single run (e.g. the Solr compatibility 
matrix in CI).
+               String solrImage = System.getProperty("solr.test.image", 
"solr:9.9.0-slim");
                return new SolrContainer(DockerImageName.parse(solrImage));
        }
 
diff --git 
a/src/test/java/org/apache/solr/mcp/server/observability/OtlpExportIntegrationTest.java
 
b/src/test/java/org/apache/solr/mcp/server/observability/OtlpExportIntegrationTest.java
index 894fae0e..bdf324f8 100644
--- 
a/src/test/java/org/apache/solr/mcp/server/observability/OtlpExportIntegrationTest.java
+++ 
b/src/test/java/org/apache/solr/mcp/server/observability/OtlpExportIntegrationTest.java
@@ -92,9 +92,12 @@ class OtlpExportIntegrationTest {
         * The {@code @ServiceConnection} annotation enables Spring Boot to 
recognize
         * this container for service connection auto-configuration.
         */
+       // Pinned in gradle/libs.versions.toml as test-image-lgtm; 
-Dlgtm.test.image
+       // overrides it for a single run.
        @Container
        @ServiceConnection
-       static LgtmStackContainer lgtmStack = new 
LgtmStackContainer("grafana/otel-lgtm:latest");
+       static LgtmStackContainer lgtmStack = new LgtmStackContainer(
+                       System.getProperty("lgtm.test.image", 
"grafana/otel-lgtm:0.33.0"));
 
        @Autowired
        private SearchService searchService;

Reply via email to