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)