@@ -155,4 +156,41 @@
+
+
+
+
+ xerial-control
+
+
+ org.xerial
+ sqlite-jdbc
+ ${xerial.version}
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+
+ **/*Test.java
+
+
+ **/com/github/magnusp/**/*Test.java
+
+
+ xerial
+
+
+
+
+
+
+
diff --git a/libsql-conformance/src/test/java/com/github/magnusp/libsql/conformance/XerialControl.java b/libsql-conformance/src/test/java/com/github/magnusp/libsql/conformance/XerialControl.java
new file mode 100644
index 0000000..59c1540
--- /dev/null
+++ b/libsql-conformance/src/test/java/com/github/magnusp/libsql/conformance/XerialControl.java
@@ -0,0 +1,78 @@
+package com.github.magnusp.libsql.conformance;
+
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Enumeration;
+
+/**
+ * Selects the upstream xerial driver for the parity control run.
+ *
+ * The control run compiles the same vendored test manifest as the libSQL run but executes it
+ * against sqlite-jdbc 3.53.4.0. Both drivers are on the test class path, so the control run first
+ * removes every driver visible to this class loader and then registers the pinned xerial driver
+ * explicitly. That keeps {@code jdbc:sqlite:} URLs from reaching the libSQL driver.
+ */
+final class XerialControl {
+
+ static final String ENABLED_PROPERTY = "conformance.control.driver";
+ static final String XERIAL_DRIVER = "org.sqlite.JDBC";
+
+ private static final String PROBE_URL = "jdbc:sqlite::memory:";
+
+ private XerialControl() {}
+
+ static boolean isEnabled() {
+ return "xerial".equals(System.getProperty(ENABLED_PROPERTY));
+ }
+
+ static void register() {
+ deregisterVisibleDrivers();
+ try {
+ Driver driver =
+ (Driver) Class.forName(XERIAL_DRIVER).getConstructor().newInstance();
+ DriverManager.registerDriver(driver);
+ } catch (ReflectiveOperationException e) {
+ throw new IllegalStateException(
+ "Xerial control run could not load " + XERIAL_DRIVER, e);
+ } catch (SQLException e) {
+ throw new IllegalStateException(
+ "Xerial control run could not register " + XERIAL_DRIVER, e);
+ }
+ verify();
+ }
+
+ private static void deregisterVisibleDrivers() {
+ ClassLoader classLoader = XerialControl.class.getClassLoader();
+ Enumeration drivers = DriverManager.getDrivers();
+ while (drivers.hasMoreElements()) {
+ Driver driver = drivers.nextElement();
+ if (driver.getClass().getClassLoader() == classLoader) {
+ try {
+ DriverManager.deregisterDriver(driver);
+ } catch (SQLException e) {
+ throw new IllegalStateException(
+ "Xerial control run could not deregister " + driver, e);
+ }
+ }
+ }
+ }
+
+ private static void verify() {
+ try {
+ Driver driver = DriverManager.getDriver(PROBE_URL);
+ if (!XERIAL_DRIVER.equals(driver.getClass().getName())) {
+ throw new IllegalStateException(
+ "Xerial control run resolved "
+ + driver.getClass().getName()
+ + " for "
+ + PROBE_URL
+ + " instead of "
+ + XERIAL_DRIVER);
+ }
+ } catch (SQLException e) {
+ throw new IllegalStateException(
+ "Xerial control run found no driver for " + PROBE_URL, e);
+ }
+ }
+}
diff --git a/libsql-conformance/src/test/java/com/github/magnusp/libsql/conformance/XerialLauncherSessionListener.java b/libsql-conformance/src/test/java/com/github/magnusp/libsql/conformance/XerialLauncherSessionListener.java
index 9838895..9448905 100644
--- a/libsql-conformance/src/test/java/com/github/magnusp/libsql/conformance/XerialLauncherSessionListener.java
+++ b/libsql-conformance/src/test/java/com/github/magnusp/libsql/conformance/XerialLauncherSessionListener.java
@@ -7,6 +7,10 @@ public final class XerialLauncherSessionListener implements LauncherSessionListe
@Override
public void launcherSessionOpened(LauncherSession session) {
+ if (XerialControl.isEnabled()) {
+ XerialControl.register();
+ return;
+ }
XerialConformanceDriver.register();
LibsqlConformanceGuard.verify();
}
diff --git a/upstream-xerial_sqlite-jdbc.manifest b/upstream-xerial_sqlite-jdbc.manifest
index 847eeda..d58a8d7 100644
--- a/upstream-xerial_sqlite-jdbc.manifest
+++ b/upstream-xerial_sqlite-jdbc.manifest
@@ -8,12 +8,63 @@
# # divergence: --
# Use the reason to say which libSQL or Hrana behavior makes parity impossible.
#
+# Selection rationale. The conformance suite selects tests that exercise JDBC
+# behavior through ordinary SQL, so the Hrana transport can satisfy them
+# unchanged. Tests that drive sqlite-jdbc's native extension API, connection
+# configuration surface, or known libSQL parity gaps stay upstream. Each
+# selected and rejected class from the pinned 3.53.4.0 test tree is listed.
+
+# Selected support code.
+# selected: src/test/java/org/sqlite/Utils.java -- compile-option assumptions shared by selected tests; not a test class.
+
+# Selected tests.
+# selected: src/test/java/org/sqlite/ResultSetTest.java -- ResultSet navigation and getter conversions over ordinary SQL.
+# selected: src/test/java/org/sqlite/InsertQueryTest.java -- transaction reuse and commit visibility across shared and independent connections.
+# selected: src/test/java/org/sqlite/FetchSizeTest.java -- fetch-size configuration and stable result ordering.
+# selected: src/test/java/org/sqlite/CachedRowSetTest.java -- disconnected CachedRowSet population through a JDBC connection.
+# selected: src/test/java/org/sqlite/JSON1Test.java -- SQL JSON function output and text conversion.
+# selected: src/test/java/org/sqlite/MetadataLeakTest.java -- metadata result sets close the statement that produced them.
+# selected: src/test/java/org/sqlite/PreparedStatementThreadTest.java -- concurrent execute and close must not crash or hide failures.
+# selected: src/test/java/org/sqlite/ResultSetWithoutResultsTest.java -- statement result-kind transitions leave no stale result set.
+# selected: src/test/java/org/sqlite/RSMetaDataTest.java -- ResultSetMetaData column names, types, and nullability.
+
+# Rejected tests.
+# rejected: src/test/java/org/sqlite/TypeMapTest.java -- removed: libSQL accepts but ignores type maps (tracked by #48), so a parity assertion would be red; asserting the no-op would be a weak test.
+# rejected: src/test/java/org/sqlite/BackupTest.java -- drives sqlite-jdbc's native backup API; Hrana exposes no backup primitive.
+# rejected: src/test/java/org/sqlite/BusyHandlerTest.java -- registers native busy-handler callbacks that Hrana does not expose.
+# rejected: src/test/java/org/sqlite/CollationTest.java -- registers JVM collations through sqlite-jdbc's native extension API.
+# rejected: src/test/java/org/sqlite/ConnectionTest.java -- exercises sqlite-jdbc URL, open-mode, and resource-loading configuration that has no Hrana equivalent; covered JDBC paths are asserted by selected tests.
+# rejected: src/test/java/org/sqlite/DBMetaDataTest.java -- DatabaseMetaData parity is tracked by #41, #42, and #50; selecting it now would be red.
+# rejected: src/test/java/org/sqlite/ErrorMessageTest.java -- asserts sqlite-jdbc wording and native result codes; sqld returns different messages and error codes.
+# rejected: src/test/java/org/sqlite/ExtendedCommandTest.java -- exercises sqlite-jdbc's dot-command parser, not the JDBC API.
+# rejected: src/test/java/org/sqlite/ExtensionTest.java -- loads native SQLite extensions; the libSQL server does not permit extension loading.
+# rejected: src/test/java/org/sqlite/JDBCTest.java -- mixes driver URL handling, extension loading, and sqlite-jdbc read-only configuration; broad driver-level coverage is asserted by selected tests.
+# rejected: src/test/java/org/sqlite/ListenerTest.java -- update, commit, rollback, and authorizer hooks require native callbacks unavailable over Hrana.
+# rejected: src/test/java/org/sqlite/MathFunctionsTest.java -- passes only when the server binary was compiled with SQLITE_ENABLE_MATH_FUNCTIONS; the sqld image build is not pinned to that option.
+# rejected: src/test/java/org/sqlite/MultipleClassLoaderTest.java -- verifies sqlite-jdbc's native library loading per class loader; libSQL has no native library.
+# rejected: src/test/java/org/sqlite/PrepStmtTest.java -- includes getGeneratedKeys (#39) and CLOB/binary binding parity that are not yet implemented; selected prepared-statement paths cover the rest.
+# rejected: src/test/java/org/sqlite/ProgressHandlerTest.java -- registers native progress callbacks that Hrana does not expose.
+# rejected: src/test/java/org/sqlite/QueryTest.java -- date/time and blob conversion cases belong to the value-conversion lane (#31, #32, #33, #34); selecting it now would mix known gaps into the parity baseline.
+# rejected: src/test/java/org/sqlite/ReadUncommittedTest.java -- depends on sqlite-jdbc shared-cache and read-uncommitted connection configuration; sqld does not expose it.
+# rejected: src/test/java/org/sqlite/SavepointTest.java -- savepoints are not implemented by the libSQL driver.
+# rejected: src/test/java/org/sqlite/SerializeTest.java -- serializes and restores a native database image; Hrana has no equivalent.
+# rejected: src/test/java/org/sqlite/SQLiteConfigTest.java -- tests sqlite-jdbc's configuration object, not the JDBC API.
+# rejected: src/test/java/org/sqlite/SQLiteConnectionPoolDataSourceTest.java -- tests sqlite-jdbc DataSource and pooling classes that libSQL does not provide.
+# rejected: src/test/java/org/sqlite/SQLiteDataSourceTest.java -- tests sqlite-jdbc DataSource classes that libSQL does not provide.
+# rejected: src/test/java/org/sqlite/SQLiteJDBCLoaderTest.java -- tests the native SQLite library loader.
+# rejected: src/test/java/org/sqlite/StatementTest.java -- statement reuse and lifecycle parity is tracked by #47; selected ResultSet tests cover the current read paths.
+# rejected: src/test/java/org/sqlite/TransactionTest.java -- asserts SQLite file-locking and multi-connection wait behavior that a single sqld server cannot reproduce; commit visibility is covered by InsertQueryTest.
+# rejected: src/test/java/org/sqlite/UDFCustomErrorTest.java -- registers JVM UDFs and inspects native error callbacks.
+# rejected: src/test/java/org/sqlite/UDFTest.java -- registers JVM UDFs through sqlite-jdbc's native extension API.
+# rejected: src/test/java/org/sqlite/util/OSInfoTest.java -- tests sqlite-jdbc's OS and native-library detection utility.
+# rejected: src/test/java/org/sqlite/architecture/CodingRulesTest.java -- ArchUnit rules over sqlite-jdbc source conventions; not runtime JDBC behavior.
+# rejected: src/test/java/org/sqlite/architecture/TestCodingRulesTest.java -- ArchUnit rules over sqlite-jdbc test conventions; not runtime JDBC behavior.
+
# First conformance batch.
src/test/java/org/sqlite/Utils.java
src/test/java/org/sqlite/ResultSetTest.java
src/test/java/org/sqlite/InsertQueryTest.java
src/test/java/org/sqlite/FetchSizeTest.java
-src/test/java/org/sqlite/TypeMapTest.java
src/test/java/org/sqlite/CachedRowSetTest.java
# Second batch: metadata, JSON, threading, and empty result sets.
@@ -32,4 +83,6 @@ VERSION
# when its last connection closes, so the conformance tests must close every
# connection they open; leaving one open leaks the namespace for the whole run.
# divergence: src/test/java/org/sqlite/JSON1Test.java -- Hrana holds a namespace until its last connection closes, so the conformance copy closes the leaked per-test connections.
-# divergence: src/test/java/org/sqlite/CachedRowSetTest.java -- Hrana holds a namespace until its last connection closes, so the conformance copy closes the leaked connection.
+# divergence: src/test/java/org/sqlite/CachedRowSetTest.java -- Hrana holds a namespace until its last connection closes, so the conformance copy closes the leaked connection and asserts the row it reads.
+# divergence: src/test/java/org/sqlite/InsertQueryTest.java -- upstream misuses the connection factory so the transaction is applied to a different connection and never asserts the result; the conformance copy reuses the transaction connection, asserts rollback and commit visibility, and asserts the final count (#51).
+# divergence: src/test/java/org/sqlite/PreparedStatementThreadTest.java -- upstream swallows ExecutionException, which also wraps assertion failures; the conformance copy rethrows AssertionError so the race test can fail (#51).
diff --git a/upstream-xerial_sqlite-jdbc/CHECKSUMS.sha256 b/upstream-xerial_sqlite-jdbc/CHECKSUMS.sha256
index 95607c9..4b493d5 100644
--- a/upstream-xerial_sqlite-jdbc/CHECKSUMS.sha256
+++ b/upstream-xerial_sqlite-jdbc/CHECKSUMS.sha256
@@ -11,24 +11,22 @@ a0670cf020edf700524c43c85321c2ba027a8bace5682001db60875d4a9fe52b ./NOTICE
# upstream 0a60829ce6edd56de46fb87303401c5c1e1e666da5631056340f5c5ce902dcdf ./VERSION
0a60829ce6edd56de46fb87303401c5c1e1e666da5631056340f5c5ce902dcdf ./VERSION
# upstream 1351fdca2644e90ac9028ed99c6096c9ecee82ccb7d45cedd9bb454887fd2c6b ./src/test/java/org/sqlite/CachedRowSetTest.java
-9e896e20522e4c5f4bc786ad7f8c5b6765428ad531fc0c07130b5f0beb81756f ./src/test/java/org/sqlite/CachedRowSetTest.java
+e1743294d2e5e781fae3b647d0bfc2eeeeb856c5276efe308f8b58979b3ab178 ./src/test/java/org/sqlite/CachedRowSetTest.java
# upstream 9fb0f2df7de66cac0a46b241c0c1cd3311a80646d0431d377097741b99053760 ./src/test/java/org/sqlite/FetchSizeTest.java
9fb0f2df7de66cac0a46b241c0c1cd3311a80646d0431d377097741b99053760 ./src/test/java/org/sqlite/FetchSizeTest.java
# upstream 6dfcecb209e01829ba0aea782b47351443e3970ad1d33ac4c3fb979e6dff1f40 ./src/test/java/org/sqlite/InsertQueryTest.java
-6dfcecb209e01829ba0aea782b47351443e3970ad1d33ac4c3fb979e6dff1f40 ./src/test/java/org/sqlite/InsertQueryTest.java
+ae4568fd773f158f04e89df8e0fe2326381b6af7ed1316193830d38f7cadbae5 ./src/test/java/org/sqlite/InsertQueryTest.java
# upstream bb07398946480ca44c70d03e6f8c399f53506b44c83a312e2d28aebd239c0238 ./src/test/java/org/sqlite/JSON1Test.java
075745907a5174b922db6a45b9c29f45901af1835af27a0014f5fac835b41d0f ./src/test/java/org/sqlite/JSON1Test.java
# upstream 242bb51330240174bab5f443aa4d8de1049e6d947374e080a636c4aa4d0049ee ./src/test/java/org/sqlite/MetadataLeakTest.java
242bb51330240174bab5f443aa4d8de1049e6d947374e080a636c4aa4d0049ee ./src/test/java/org/sqlite/MetadataLeakTest.java
# upstream 7af8ae0999a0bf26a20c96ab23131505bd79827e6af17742771e36e9d8d985f4 ./src/test/java/org/sqlite/PreparedStatementThreadTest.java
-7af8ae0999a0bf26a20c96ab23131505bd79827e6af17742771e36e9d8d985f4 ./src/test/java/org/sqlite/PreparedStatementThreadTest.java
+bc6d868d2069dcc5db54a7720e7ecd9f725c83dbf910ec8ec61222b98f6198c1 ./src/test/java/org/sqlite/PreparedStatementThreadTest.java
# upstream d787e71bdf2b8d12a2669eb06c432cf2a39ac77f678a92459e3dd9b6c4519a43 ./src/test/java/org/sqlite/RSMetaDataTest.java
d787e71bdf2b8d12a2669eb06c432cf2a39ac77f678a92459e3dd9b6c4519a43 ./src/test/java/org/sqlite/RSMetaDataTest.java
# upstream 6065d284933c8462cc13217992820a9261075c0e9ee126df6cbe9961d90303f9 ./src/test/java/org/sqlite/ResultSetTest.java
6065d284933c8462cc13217992820a9261075c0e9ee126df6cbe9961d90303f9 ./src/test/java/org/sqlite/ResultSetTest.java
# upstream 958c1f2ff5ca2f1257dfd847207ea793839969b234d140576b51af346697233c ./src/test/java/org/sqlite/ResultSetWithoutResultsTest.java
958c1f2ff5ca2f1257dfd847207ea793839969b234d140576b51af346697233c ./src/test/java/org/sqlite/ResultSetWithoutResultsTest.java
-# upstream ed2fb4bf7319bcba0662b83707375501337173956bae7c57dda6e6a2c46b7505 ./src/test/java/org/sqlite/TypeMapTest.java
-ed2fb4bf7319bcba0662b83707375501337173956bae7c57dda6e6a2c46b7505 ./src/test/java/org/sqlite/TypeMapTest.java
# upstream bef3eddca2a6b80472050a3a52d5e7246128f0644d29c24ed091709b0ed6f121 ./src/test/java/org/sqlite/Utils.java
bef3eddca2a6b80472050a3a52d5e7246128f0644d29c24ed091709b0ed6f121 ./src/test/java/org/sqlite/Utils.java
diff --git a/upstream-xerial_sqlite-jdbc/src/test/java/org/sqlite/CachedRowSetTest.java b/upstream-xerial_sqlite-jdbc/src/test/java/org/sqlite/CachedRowSetTest.java
index 7b9de8d..5d18c6e 100644
--- a/upstream-xerial_sqlite-jdbc/src/test/java/org/sqlite/CachedRowSetTest.java
+++ b/upstream-xerial_sqlite-jdbc/src/test/java/org/sqlite/CachedRowSetTest.java
@@ -1,5 +1,7 @@
package org.sqlite;
+import static org.assertj.core.api.Assertions.assertThat;
+
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
@@ -22,6 +24,11 @@ public void gh_224() throws SQLException {
try (CachedRowSet crs = factory.createCachedRowSet()) {
crs.setCommand("select * from person");
crs.execute(connection);
+
+ assertThat(crs.next()).isTrue();
+ assertThat(crs.getInt("id")).isEqualTo(1);
+ assertThat(crs.getString("name")).isEqualTo("leo");
+ assertThat(crs.next()).isFalse();
}
}
}
diff --git a/upstream-xerial_sqlite-jdbc/src/test/java/org/sqlite/InsertQueryTest.java b/upstream-xerial_sqlite-jdbc/src/test/java/org/sqlite/InsertQueryTest.java
index a4b2ade..b1e8dd2 100644
--- a/upstream-xerial_sqlite-jdbc/src/test/java/org/sqlite/InsertQueryTest.java
+++ b/upstream-xerial_sqlite-jdbc/src/test/java/org/sqlite/InsertQueryTest.java
@@ -9,6 +9,9 @@
// --------------------------------------
package org.sqlite;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
import java.io.File;
import java.sql.*;
import java.util.ArrayList;
@@ -114,73 +117,85 @@ public void insertLockTestUsingIndependentConnection() throws Exception {
void insertAndQuery(ConnectionFactory factory) throws SQLException {
try {
- Statement st = factory.getConnection().createStatement();
- st.executeUpdate(
- "CREATE TABLE IF NOT EXISTS data (fid VARCHAR(255) PRIMARY KEY, type VARCHAR(64), data BLOB);");
- st.executeUpdate(
- "CREATE TABLE IF NOT EXISTS ResourcesTags (bd_fid VARCHAR(255), name VARCHAR(64), version INTEGER);");
- st.close();
+ Connection transactionConnection = factory.getConnection();
+ try (Statement st = transactionConnection.createStatement()) {
+ st.executeUpdate(
+ "CREATE TABLE IF NOT EXISTS data (fid VARCHAR(255) PRIMARY KEY, type VARCHAR(64), data BLOB);");
+ st.executeUpdate(
+ "CREATE TABLE IF NOT EXISTS ResourcesTags (bd_fid VARCHAR(255), name VARCHAR(64), version INTEGER);");
+ }
- factory.getConnection().setAutoCommit(false);
+ transactionConnection.setAutoCommit(false);
// Object Serialization
- PreparedStatement statAddBD =
- factory.getConnection()
- .prepareStatement("INSERT OR REPLACE INTO data values (?, ?, ?)");
- PreparedStatement statDelRT =
- factory.getConnection()
- .prepareStatement("DELETE FROM ResourcesTags WHERE bd_fid = ?");
- PreparedStatement statAddRT =
- factory.getConnection()
- .prepareStatement("INSERT INTO ResourcesTags values (?, ?, ?)");
-
- for (int i = 0; i < 10; i++) {
- BD item = new BD(Integer.toHexString(i), Integer.toString(i));
-
- // SQLite database insertion
- statAddBD.setString(1, item.getFullId());
- statAddBD.setString(2, item.getType());
- statAddBD.setBytes(3, BD.serializeBD(item));
- statAddBD.execute();
-
- // Then, its resources tags
- statDelRT.setString(1, item.getFullId());
- statDelRT.execute();
-
- statAddRT.setString(1, item.getFullId());
-
- for (int j = 0; j < 2; j++) {
- statAddRT.setString(2, "1");
- statAddRT.setLong(3, 1L);
- statAddRT.execute();
- }
+ try (PreparedStatement statAddBD =
+ transactionConnection.prepareStatement(
+ "INSERT OR REPLACE INTO data values (?, ?, ?)");
+ PreparedStatement statDelRT =
+ transactionConnection.prepareStatement(
+ "DELETE FROM ResourcesTags WHERE bd_fid = ?");
+ PreparedStatement statAddRT =
+ transactionConnection.prepareStatement(
+ "INSERT INTO ResourcesTags values (?, ?, ?)")) {
+
+ insertRows(statAddBD, statDelRT, statAddRT, 10);
+
+ // Rolling back on the transaction connection proves the inserts ran there.
+ // Statements executed on another connection would already be committed.
+ transactionConnection.rollback();
+ assertRowCount(factory, 0, "rollback must discard the inserted rows");
+
+ insertRows(statAddBD, statDelRT, statAddRT, 10);
+ transactionConnection.commit();
+ assertRowCount(factory, 10, "commit must persist the inserted rows");
}
- factory.getConnection().setAutoCommit(true);
-
- statAddBD.close();
- statDelRT.close();
- statAddRT.close();
-
- //
- PreparedStatement stat;
- Long result = 0L;
- String query = "SELECT COUNT(fid) FROM data";
-
- stat = factory.getConnection().prepareStatement(query);
- ResultSet rs = stat.executeQuery();
-
- rs.next();
- result = rs.getLong(1);
- // System.out.println("count = " + result);
-
- rs.close();
- stat.close();
+ transactionConnection.setAutoCommit(true);
} finally {
factory.dispose();
}
}
+ private void insertRows(
+ PreparedStatement statAddBD,
+ PreparedStatement statDelRT,
+ PreparedStatement statAddRT,
+ int rows)
+ throws SQLException {
+ for (int i = 0; i < rows; i++) {
+ BD item = new BD(Integer.toHexString(i), Integer.toString(i));
+
+ // SQLite database insertion
+ statAddBD.setString(1, item.getFullId());
+ statAddBD.setString(2, item.getType());
+ statAddBD.setBytes(3, BD.serializeBD(item));
+ statAddBD.execute();
+
+ // Then, its resources tags
+ statDelRT.setString(1, item.getFullId());
+ statDelRT.execute();
+
+ statAddRT.setString(1, item.getFullId());
+
+ for (int j = 0; j < 2; j++) {
+ statAddRT.setString(2, "1");
+ statAddRT.setLong(3, 1L);
+ statAddRT.execute();
+ }
+ }
+ }
+
+ private void assertRowCount(ConnectionFactory factory, long expected, String message)
+ throws SQLException {
+ Connection verificationConnection = factory.getConnection();
+ try (PreparedStatement stat =
+ verificationConnection.prepareStatement("SELECT COUNT(fid) FROM data");
+ ResultSet rs = stat.executeQuery()) {
+ assertTrue(rs.next(), "COUNT query must return a row");
+ assertEquals(expected, rs.getLong(1), message);
+ }
+ }
+
@Disabled("Not sure this worked recently, the second query cannot find the table 'sample'")
@Test
public void reproduceDatabaseLocked() throws SQLException {
diff --git a/upstream-xerial_sqlite-jdbc/src/test/java/org/sqlite/PreparedStatementThreadTest.java b/upstream-xerial_sqlite-jdbc/src/test/java/org/sqlite/PreparedStatementThreadTest.java
index 69685b0..0d10163 100644
--- a/upstream-xerial_sqlite-jdbc/src/test/java/org/sqlite/PreparedStatementThreadTest.java
+++ b/upstream-xerial_sqlite-jdbc/src/test/java/org/sqlite/PreparedStatementThreadTest.java
@@ -105,7 +105,11 @@ private void testRace(ExecutorService executorService, CloseCallback closeCallba
Thread.currentThread().interrupt();
fail("", e);
} catch (ExecutionException e) {
- // this is OK, so long as we don't seg fault
+ // A checked SQLException from the close race is expected. Assertion failures are
+ // not: ExecutionException wraps them, so rethrow them or the test cannot fail.
+ if (e.getCause() instanceof AssertionError assertionError) {
+ throw assertionError;
+ }
}
}
diff --git a/upstream-xerial_sqlite-jdbc/src/test/java/org/sqlite/TypeMapTest.java b/upstream-xerial_sqlite-jdbc/src/test/java/org/sqlite/TypeMapTest.java
deleted file mode 100644
index 66bf9e4..0000000
--- a/upstream-xerial_sqlite-jdbc/src/test/java/org/sqlite/TypeMapTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.sqlite;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.util.Map;
-import org.junit.jupiter.api.Test;
-
-public class TypeMapTest {
-
- public Connection getConnection() throws SQLException {
- return DriverManager.getConnection("jdbc:sqlite::memory:");
- }
-
- @Test
- public void getTypeMap() throws Exception {
- Connection conn = getConnection();
-
- Map> m = conn.getTypeMap();
-
- conn.close();
- }
-
- @Test
- public void setTypeMap() throws Exception {
- Connection conn = getConnection();
-
- Map> m = conn.getTypeMap();
- conn.setTypeMap(m);
-
- conn.close();
- }
-}