Mercurial > hg > monetdb-java
changeset 674:b885de91095d
Add tests for autocommit and timezone handshake options
The other options are hard to test
author | Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com> |
---|---|
date | Mon, 31 Oct 2022 16:39:11 +0100 (2022-10-31) |
parents | 8464a17caedf |
children | 844139b33cdd |
files | tests/ConnectionTests.java tests/JDBC_API_Tester.java |
diffstat | 2 files changed, 191 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/tests/ConnectionTests.java @@ -0,0 +1,189 @@ +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; +import java.util.SimpleTimeZone; +import java.util.TimeZone; + +public class ConnectionTests { + + private final String url; + private final Properties connProps; + private final TimeZone timeZone; + + public ConnectionTests(String url, Properties props, TimeZone timeZone) { + this.url = url; + Properties myProps = null; + if (props != null) { + myProps = new Properties(); + myProps.putAll(props); + } + this.connProps = myProps; + this.timeZone = timeZone; + } + + public ConnectionTests(String url) { + this(url, null, null); + } + + public ConnectionTests withSuffix(String suffix) { + String newUrl = url; + + if (newUrl.contains("?")) { + newUrl += "&"; + } else { + newUrl += "?"; + } + newUrl += suffix; + + return new ConnectionTests(newUrl, this.connProps, this.timeZone); + } + + public ConnectionTests withProp(String key, String value) { + ConnectionTests sub = new ConnectionTests(this.url, new Properties(), this.timeZone); + if (this.connProps != null) + sub.connProps.putAll(this.connProps); + sub.connProps.setProperty(key, value); + return sub; + } + + public ConnectionTests withTimeZone(int offsetMinutes) { + TimeZone tz = new SimpleTimeZone(offsetMinutes * 60 * 1000, "Custom" + offsetMinutes); + return new ConnectionTests(this.url, this.connProps, tz); + } + + public static void main(String[] args) throws SQLException, Failure { + String url = args[0]; + runTests(url); + } + + public static void runTests(String url) throws SQLException, Failure { + ConnectionTests tester = new ConnectionTests(url); + + tester.checkAutoCommit(true); + tester.withSuffix("autocommit=true").checkAutoCommit(true); + tester.withSuffix("autocommit=false").checkAutoCommit(false); + tester.withProp("autocommit", "true").checkAutoCommit(true); + tester.withProp("autocommit", "false").checkAutoCommit(false); + + tester.testTimeZone(); + } + + Connection connect() throws SQLException { + TimeZone restore = null; + try { + if (this.timeZone != null) { + restore = TimeZone.getDefault(); + TimeZone.setDefault(this.timeZone); + } + if (connProps != null) { + return DriverManager.getConnection(url, connProps); + } else { + return DriverManager.getConnection(url); + } + } finally { + if (restore != null) { + TimeZone.setDefault(restore); + } + } + } + + private void checkAutoCommit(boolean expectAutocommit) throws SQLException, Failure { + // Create and fill the table, leave one row uncommitted. + try (Connection conn = connect(); Statement stmt = conn.createStatement()) { + // Does the connection itself believe to be in the correct mode? + boolean autocommitEnabled = conn.getAutoCommit(); + if (autocommitEnabled != expectAutocommit) { + throw new Failure("Expected autocommit to start as " + expectAutocommit + ", got " + autocommitEnabled); + } + + // Let's test how it works out in practice + stmt.execute("DROP TABLE IF EXISTS connectiontests"); + stmt.execute("CREATE TABLE connectiontests(i INT)"); + stmt.execute("INSERT INTO connectiontests VALUES (42)"); + if (!expectAutocommit) + conn.commit(); + // This will only be committed in autocommit mode + stmt.execute("INSERT INTO connectiontests VALUES (99)"); + } + + // Check whether the uncommitted row is there or not + try (Connection conn = connect(); Statement stmt = conn.createStatement()) { + try (ResultSet rs = stmt.executeQuery("SELECT COUNT(i) FROM connectiontests")) { + rs.next(); + int n = rs.getInt(1); + if (expectAutocommit) { + if (n != 2) { + throw new Failure("Expected 2 rows because autocommit should be on, got " + n); + } + } else { + if (n != 1) { + throw new Failure("Expected 1 row because autocommit should be off, got " + n); + } + } + } + } + } + + private void testTimeZone() throws SQLException, Failure { + try (Connection conn = connect(); Statement stmt = conn.createStatement()) { + stmt.execute("DROP TABLE IF EXISTS connectiontests_ts"); + stmt.execute("CREATE TABLE connectiontests_ts(ts TIMESTAMP WITH TIME ZONE)"); + stmt.execute("INSERT INTO connectiontests_ts VALUES (str_to_timestamp(100, '%s'))"); + } + + this.withTimeZone(0).verifyTimeZoneSuffix("+00:00"); + this.withTimeZone(240).verifyTimeZoneSuffix("+04:00"); + this.withTimeZone(270).verifyTimeZoneSuffix("+04:30"); + } + + private void verifyTimeZoneSuffix(String suffix) throws SQLException, Failure { + try (Connection conn = connect(); Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("SELECT * FROM connectiontests_ts"); + rs.next(); + String s = rs.getString(1); + if (!s.endsWith(suffix)) { + String msg = String.format("Expected suffix '%s', got timestamp '%s'", suffix, s); + throw new Failure(msg); + } + } + } + + public class Failure extends Exception { + public Failure(String msg) { + super(msg); + } + + @Override + public String getMessage() { + StringBuilder msg = new StringBuilder(); + msg.append("When connected to "); + msg.append(url); + if (timeZone != null) { + msg.append(", in time zone "); + msg.append(timeZone.getID()); + msg.append(" ("); + msg.append(timeZone.getDisplayName()); + msg.append(")"); + } else { + msg.append(", in the default time zone"); + } + if (connProps != null) { + msg.append(", with "); + msg.append(connProps.size()); + msg.append(" properties"); + connProps.forEach((k, v) -> { + msg.append(", "); + msg.append(k); + msg.append("="); + msg.append(v); + }); + } + msg.append(": "); + msg.append(super.getMessage()); + return msg.toString(); + } + } +}
--- a/tests/JDBC_API_Tester.java +++ b/tests/JDBC_API_Tester.java @@ -108,6 +108,8 @@ final public class JDBC_API_Tester { if (jt.foundDifferences) System.exit(-1); + ConnectionTests.runTests(con_URL); + OnClientTester oct = new OnClientTester(con_URL, 0); int failures = oct.runTests(); if (failures > 0)