From 21f168f4d08c9f48515dc84fc46271a75a760d4b Mon Sep 17 00:00:00 2001 From: Magnus Persson <1431685+magnusp@users.noreply.github.com> Date: Fri, 23 Oct 2026 23:44:06 +0200 Subject: [PATCH] chore: pin sqld test image to v0.24.33 --- AGENTS.md | 3 ++- TESTCONTAINERS-USAGE.md | 16 ++++++++++++---- .../libsql/conformance/XerialTestServer.java | 15 +++++++++++---- .../magnusp/libsql/itest/NamespacePathIT.java | 3 +-- .../magnusp/libsql/itest/NetworkToxicityIT.java | 3 ++- .../magnusp/libsql/itest/SqldContainerBase.java | 12 +++++++++++- pom.xml | 12 ++++++++++++ 7 files changed, 51 insertions(+), 13 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 2cfd38a..014dd81 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -55,7 +55,8 @@ libsql-java/ - Maps SQLite dynamic typing to JDBC SQL types and translates Hrana error codes to `SQLException` hierarchies. 4. **`libsql-itests`**: - - All tests run against containerized `sqld` (`ghcr.io/tursodatabase/libsql-server:latest`). + - All tests run against a pinned `sqld` image (`ghcr.io/tursodatabase/libsql-server:v0.24.33`). + - The pin lives in the root `pom.xml` as the `libsql.image` property, and Maven passes it to both the integration and conformance test JVMs. Override it with `-Dlibsql.image=...` only for a deliberate version bump. - Includes HikariCP connection pool churn tests and Toxiproxy network toxicity tests. --- diff --git a/TESTCONTAINERS-USAGE.md b/TESTCONTAINERS-USAGE.md index 0ef8ec9..b41b1b1 100644 --- a/TESTCONTAINERS-USAGE.md +++ b/TESTCONTAINERS-USAGE.md @@ -9,10 +9,17 @@ This document explains how Testcontainers is configured and utilized in this pro Testing a pure-Java JDBC driver for Turso requires verifying real SQLite behavior, lock contention, HTTP pipeline batons, and network edge cases over the wire. Rather than mocking HTTP endpoints, we run real `sqld` instances using Testcontainers. ### Container Image -* **Image**: `ghcr.io/tursodatabase/libsql-server:latest` +* **Image**: `ghcr.io/tursodatabase/libsql-server:v0.24.33` * **Exposed Port**: `8080` (HTTP and Hrana pipeline endpoint) -The image can also be overridden via the system property `-Dlibsql.image=`. +The image is pinned to a released `sqld` version so that `latest` cannot silently change +the behavior under test. The pin is defined once in the root `pom.xml` as the +`libsql.image` property, and Maven passes it to both the integration and conformance +test JVMs. To test a different version, override the property: + +```bash +./mvnw verify -Dlibsql.image=ghcr.io/tursodatabase/libsql-server:v0.24.33 +``` --- @@ -35,7 +42,8 @@ import java.time.Duration; @Testcontainers public abstract class SqldContainerBase { - private static final String LIBSQL_IMAGE = System.getProperty("libsql.image", "ghcr.io/tursodatabase/libsql-server:latest"); + // Supplied by the root pom's libsql.image property via surefire/failsafe. + private static final String LIBSQL_IMAGE = System.getProperty("libsql.image"); private static final int PORT = 8080; @Container @@ -105,7 +113,7 @@ public class NetworkToxicityIntegrationIT { private static final Network NETWORK = Network.newNetwork(); - private static final GenericContainer LIBSQL = new GenericContainer<>("ghcr.io/tursodatabase/libsql-server:latest") + private static final GenericContainer LIBSQL = new GenericContainer<>(SqldContainerBase.LIBSQL_IMAGE) .withNetwork(NETWORK) .withNetworkAliases("libsql-srv") .withExposedPorts(8080) diff --git a/libsql-conformance/src/test/java/com/github/magnusp/libsql/conformance/XerialTestServer.java b/libsql-conformance/src/test/java/com/github/magnusp/libsql/conformance/XerialTestServer.java index 982828d..5946c99 100644 --- a/libsql-conformance/src/test/java/com/github/magnusp/libsql/conformance/XerialTestServer.java +++ b/libsql-conformance/src/test/java/com/github/magnusp/libsql/conformance/XerialTestServer.java @@ -22,10 +22,7 @@ public final class XerialTestServer { - private static final String IMAGE = - System.getProperty( - "libsql.image", - "ghcr.io/tursodatabase/libsql-server@sha256:6dd3eb276d9d3604e4a48ac4a999a2e267814732d57d7e94c04ba71482333a67"); + private static final String IMAGE = requireLibsqlImage(); private static final int HTTP_PORT = 8080; private static final int ADMIN_PORT = 9090; private static final Duration REQUEST_TIMEOUT = Duration.ofSeconds(30); @@ -52,6 +49,16 @@ public final class XerialTestServer { private XerialTestServer() {} + private static String requireLibsqlImage() { + String image = System.getProperty("libsql.image"); + if (image == null || image.isBlank()) { + throw new IllegalStateException( + "libsql.image is not set. Run the conformance tests with Maven so the" + + " pinned sqld image from the root pom is used."); + } + return image; + } + public static synchronized void start() { if (container != null) { return; diff --git a/libsql-itests/src/test/java/com/github/magnusp/libsql/itest/NamespacePathIT.java b/libsql-itests/src/test/java/com/github/magnusp/libsql/itest/NamespacePathIT.java index 74a330c..f8624ed 100644 --- a/libsql-itests/src/test/java/com/github/magnusp/libsql/itest/NamespacePathIT.java +++ b/libsql-itests/src/test/java/com/github/magnusp/libsql/itest/NamespacePathIT.java @@ -33,12 +33,11 @@ @Testcontainers public class NamespacePathIT { - private static final String LIBSQL_IMAGE = System.getProperty("libsql.image", "ghcr.io/tursodatabase/libsql-server:latest"); private static final int HTTP_PORT = 8080; private static final int ADMIN_PORT = 9090; @Container - public static final GenericContainer SQLD_CONTAINER = new GenericContainer<>(LIBSQL_IMAGE) + public static final GenericContainer SQLD_CONTAINER = new GenericContainer<>(SqldContainerBase.LIBSQL_IMAGE) .withExposedPorts(HTTP_PORT, ADMIN_PORT) .withCommand( "sqld", diff --git a/libsql-itests/src/test/java/com/github/magnusp/libsql/itest/NetworkToxicityIT.java b/libsql-itests/src/test/java/com/github/magnusp/libsql/itest/NetworkToxicityIT.java index 0b1149a..90ad922 100644 --- a/libsql-itests/src/test/java/com/github/magnusp/libsql/itest/NetworkToxicityIT.java +++ b/libsql-itests/src/test/java/com/github/magnusp/libsql/itest/NetworkToxicityIT.java @@ -31,7 +31,8 @@ public class NetworkToxicityIT { private static final Network NETWORK = Network.newNetwork(); - private static final GenericContainer LIBSQL = new GenericContainer<>("ghcr.io/tursodatabase/libsql-server:latest") + private static final GenericContainer LIBSQL = + new GenericContainer<>(SqldContainerBase.LIBSQL_IMAGE) .withNetwork(NETWORK) .withNetworkAliases("libsql-srv") .withExposedPorts(8080) diff --git a/libsql-itests/src/test/java/com/github/magnusp/libsql/itest/SqldContainerBase.java b/libsql-itests/src/test/java/com/github/magnusp/libsql/itest/SqldContainerBase.java index 23c2daa..1294a73 100644 --- a/libsql-itests/src/test/java/com/github/magnusp/libsql/itest/SqldContainerBase.java +++ b/libsql-itests/src/test/java/com/github/magnusp/libsql/itest/SqldContainerBase.java @@ -11,9 +11,19 @@ @Testcontainers public abstract class SqldContainerBase { - private static final String LIBSQL_IMAGE = System.getProperty("libsql.image", "ghcr.io/tursodatabase/libsql-server:latest"); + static final String LIBSQL_IMAGE = requireLibsqlImage(); private static final int PORT = 8080; + private static String requireLibsqlImage() { + String image = System.getProperty("libsql.image"); + if (image == null || image.isBlank()) { + throw new IllegalStateException( + "libsql.image is not set. Run the integration tests with Maven so the" + + " pinned sqld image from the root pom is used."); + } + return image; + } + @Container public static final GenericContainer LIBSQL_CONTAINER = new GenericContainer<>(LIBSQL_IMAGE) .withExposedPorts(PORT) diff --git a/pom.xml b/pom.xml index 3967bea..25c4945 100644 --- a/pom.xml +++ b/pom.xml @@ -46,6 +46,8 @@ 2.0.5 7.1.0 4.36.1 + + ghcr.io/tursodatabase/libsql-server:v0.24.33 @@ -137,11 +139,21 @@ org.apache.maven.plugins maven-surefire-plugin 3.6.0 + + + ${libsql.image} + + org.apache.maven.plugins maven-failsafe-plugin 3.6.0 + + + ${libsql.image} + +