comparison tests/ConnectionTests.java @ 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
children e73c4a1f41c6
comparison
equal deleted inserted replaced
673:8464a17caedf 674:b885de91095d
1 import java.sql.Connection;
2 import java.sql.DriverManager;
3 import java.sql.ResultSet;
4 import java.sql.SQLException;
5 import java.sql.Statement;
6 import java.util.Properties;
7 import java.util.SimpleTimeZone;
8 import java.util.TimeZone;
9
10 public class ConnectionTests {
11
12 private final String url;
13 private final Properties connProps;
14 private final TimeZone timeZone;
15
16 public ConnectionTests(String url, Properties props, TimeZone timeZone) {
17 this.url = url;
18 Properties myProps = null;
19 if (props != null) {
20 myProps = new Properties();
21 myProps.putAll(props);
22 }
23 this.connProps = myProps;
24 this.timeZone = timeZone;
25 }
26
27 public ConnectionTests(String url) {
28 this(url, null, null);
29 }
30
31 public ConnectionTests withSuffix(String suffix) {
32 String newUrl = url;
33
34 if (newUrl.contains("?")) {
35 newUrl += "&";
36 } else {
37 newUrl += "?";
38 }
39 newUrl += suffix;
40
41 return new ConnectionTests(newUrl, this.connProps, this.timeZone);
42 }
43
44 public ConnectionTests withProp(String key, String value) {
45 ConnectionTests sub = new ConnectionTests(this.url, new Properties(), this.timeZone);
46 if (this.connProps != null)
47 sub.connProps.putAll(this.connProps);
48 sub.connProps.setProperty(key, value);
49 return sub;
50 }
51
52 public ConnectionTests withTimeZone(int offsetMinutes) {
53 TimeZone tz = new SimpleTimeZone(offsetMinutes * 60 * 1000, "Custom" + offsetMinutes);
54 return new ConnectionTests(this.url, this.connProps, tz);
55 }
56
57 public static void main(String[] args) throws SQLException, Failure {
58 String url = args[0];
59 runTests(url);
60 }
61
62 public static void runTests(String url) throws SQLException, Failure {
63 ConnectionTests tester = new ConnectionTests(url);
64
65 tester.checkAutoCommit(true);
66 tester.withSuffix("autocommit=true").checkAutoCommit(true);
67 tester.withSuffix("autocommit=false").checkAutoCommit(false);
68 tester.withProp("autocommit", "true").checkAutoCommit(true);
69 tester.withProp("autocommit", "false").checkAutoCommit(false);
70
71 tester.testTimeZone();
72 }
73
74 Connection connect() throws SQLException {
75 TimeZone restore = null;
76 try {
77 if (this.timeZone != null) {
78 restore = TimeZone.getDefault();
79 TimeZone.setDefault(this.timeZone);
80 }
81 if (connProps != null) {
82 return DriverManager.getConnection(url, connProps);
83 } else {
84 return DriverManager.getConnection(url);
85 }
86 } finally {
87 if (restore != null) {
88 TimeZone.setDefault(restore);
89 }
90 }
91 }
92
93 private void checkAutoCommit(boolean expectAutocommit) throws SQLException, Failure {
94 // Create and fill the table, leave one row uncommitted.
95 try (Connection conn = connect(); Statement stmt = conn.createStatement()) {
96 // Does the connection itself believe to be in the correct mode?
97 boolean autocommitEnabled = conn.getAutoCommit();
98 if (autocommitEnabled != expectAutocommit) {
99 throw new Failure("Expected autocommit to start as " + expectAutocommit + ", got " + autocommitEnabled);
100 }
101
102 // Let's test how it works out in practice
103 stmt.execute("DROP TABLE IF EXISTS connectiontests");
104 stmt.execute("CREATE TABLE connectiontests(i INT)");
105 stmt.execute("INSERT INTO connectiontests VALUES (42)");
106 if (!expectAutocommit)
107 conn.commit();
108 // This will only be committed in autocommit mode
109 stmt.execute("INSERT INTO connectiontests VALUES (99)");
110 }
111
112 // Check whether the uncommitted row is there or not
113 try (Connection conn = connect(); Statement stmt = conn.createStatement()) {
114 try (ResultSet rs = stmt.executeQuery("SELECT COUNT(i) FROM connectiontests")) {
115 rs.next();
116 int n = rs.getInt(1);
117 if (expectAutocommit) {
118 if (n != 2) {
119 throw new Failure("Expected 2 rows because autocommit should be on, got " + n);
120 }
121 } else {
122 if (n != 1) {
123 throw new Failure("Expected 1 row because autocommit should be off, got " + n);
124 }
125 }
126 }
127 }
128 }
129
130 private void testTimeZone() throws SQLException, Failure {
131 try (Connection conn = connect(); Statement stmt = conn.createStatement()) {
132 stmt.execute("DROP TABLE IF EXISTS connectiontests_ts");
133 stmt.execute("CREATE TABLE connectiontests_ts(ts TIMESTAMP WITH TIME ZONE)");
134 stmt.execute("INSERT INTO connectiontests_ts VALUES (str_to_timestamp(100, '%s'))");
135 }
136
137 this.withTimeZone(0).verifyTimeZoneSuffix("+00:00");
138 this.withTimeZone(240).verifyTimeZoneSuffix("+04:00");
139 this.withTimeZone(270).verifyTimeZoneSuffix("+04:30");
140 }
141
142 private void verifyTimeZoneSuffix(String suffix) throws SQLException, Failure {
143 try (Connection conn = connect(); Statement stmt = conn.createStatement()) {
144 ResultSet rs = stmt.executeQuery("SELECT * FROM connectiontests_ts");
145 rs.next();
146 String s = rs.getString(1);
147 if (!s.endsWith(suffix)) {
148 String msg = String.format("Expected suffix '%s', got timestamp '%s'", suffix, s);
149 throw new Failure(msg);
150 }
151 }
152 }
153
154 public class Failure extends Exception {
155 public Failure(String msg) {
156 super(msg);
157 }
158
159 @Override
160 public String getMessage() {
161 StringBuilder msg = new StringBuilder();
162 msg.append("When connected to ");
163 msg.append(url);
164 if (timeZone != null) {
165 msg.append(", in time zone ");
166 msg.append(timeZone.getID());
167 msg.append(" (");
168 msg.append(timeZone.getDisplayName());
169 msg.append(")");
170 } else {
171 msg.append(", in the default time zone");
172 }
173 if (connProps != null) {
174 msg.append(", with ");
175 msg.append(connProps.size());
176 msg.append(" properties");
177 connProps.forEach((k, v) -> {
178 msg.append(", ");
179 msg.append(k);
180 msg.append("=");
181 msg.append(v);
182 });
183 }
184 msg.append(": ");
185 msg.append(super.getMessage());
186 return msg.toString();
187 }
188 }
189 }