Mercurial > hg > monetdb-java
comparison tests/OnClientTester.java @ 574:3370027aeb7f onclient
Test more systematically that the connection is still alive after file transfer
Some MonetDB versions have a bug where the connection is closed by the server
when the client refuses to download.
The tests look at the the server version and skip the
lifeness check if the server is too old.
author | Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com> |
---|---|
date | Wed, 06 Oct 2021 11:34:18 +0200 (2021-10-06) |
parents | 8a4e6c82815a |
children | 08c9918177b2 |
comparison
equal
deleted
inserted
replaced
573:0fbf1cbde56c | 574:3370027aeb7f |
---|---|
57 | 57 |
58 if (failures > 0) | 58 if (failures > 0) |
59 System.exit(1); | 59 System.exit(1); |
60 } | 60 } |
61 | 61 |
62 /// Some tests have to work limitations of the protocol or bugs in the server. | |
63 /// This Enum is used to indicate the possibilities. | |
64 public enum BugFixLevel { | |
65 /// Only those tests that work with older MonetDB versions | |
66 Baseline(0, 0, 0), | |
67 | |
68 /// Connection keeps working after download request has been refused by client | |
69 CanRefuseDownload(11, 41, 12), | |
70 | |
71 ; | |
72 | |
73 private final int major; | |
74 private final int minor; | |
75 private final int micro; | |
76 | |
77 BugFixLevel(int major, int minor, int micro) { | |
78 this.major = major; | |
79 this.minor = minor; | |
80 this.micro = micro; | |
81 } | |
82 | |
83 boolean includesVersion(int major, int minor, int micro) { | |
84 if (major > this.major) | |
85 return true; | |
86 if (major < this.major) | |
87 return false; | |
88 if (minor > this.minor) | |
89 return true; | |
90 if (minor < this.minor) | |
91 return false; | |
92 return micro >= this.micro; | |
93 } | |
94 | |
95 static BugFixLevel forVersion(String version) { | |
96 String[] parts = version.split("[.]", 3); | |
97 assert parts.length == 3; | |
98 int major = Integer.parseInt(parts[0]); | |
99 int minor = Integer.parseInt(parts[1]); | |
100 int micro = Integer.parseInt(parts[2]); | |
101 | |
102 return BugFixLevel.forVersion(major, minor, micro); | |
103 } | |
104 | |
105 static BugFixLevel forVersion(int major, int minor, int micro) { | |
106 BugFixLevel lastValid = Baseline; | |
107 for (BugFixLevel level: BugFixLevel.values()) { | |
108 if (level.includesVersion(major, minor, micro)) | |
109 lastValid = level; | |
110 else | |
111 break; | |
112 } | |
113 return lastValid; | |
114 } | |
115 } | |
116 | |
62 void prepare() throws SQLException { | 117 void prepare() throws SQLException { |
63 execute("DROP TABLE IF EXISTS foo"); | 118 execute("DROP TABLE IF EXISTS foo"); |
64 execute("CREATE TABLE foo (i INT, t TEXT)"); | 119 execute("CREATE TABLE foo (i INT, t TEXT)"); |
65 } | 120 } |
66 | 121 |
67 public void test_Upload() throws Exception { | 122 private BugFixLevel getLevel() throws SQLException, Failure { |
123 String version = queryString("SELECT value FROM environment WHERE name = 'monet_version'"); | |
124 BugFixLevel level = BugFixLevel.forVersion(version); | |
125 out.println(" NOTE: version " + version + " means level = " + level); | |
126 return level; | |
127 } | |
128 | |
129 public void test_BugFixLevel() throws Failure { | |
130 assertEq("Baseline includes 0.0.0", true, BugFixLevel.Baseline.includesVersion(0, 0, 0)); | |
131 assertEq("Baseline includes 11.41.11", true, BugFixLevel.Baseline.includesVersion(11, 41, 11)); | |
132 assertEq("Baseline includes 11.41.12", true, BugFixLevel.Baseline.includesVersion(11, 41, 12)); | |
133 | |
134 assertEq("CanRefuseDownload includes 0.0.0", false, BugFixLevel.CanRefuseDownload.includesVersion(0, 0, 0)); | |
135 | |
136 assertEq("CanRefuseDownload includes 11.0.0", false, BugFixLevel.CanRefuseDownload.includesVersion(11, 0, 0)); | |
137 assertEq("CanRefuseDownload includes 12.0.0", true, BugFixLevel.CanRefuseDownload.includesVersion(12, 0, 0)); | |
138 | |
139 assertEq("CanRefuseDownload includes 11.41.0", false, BugFixLevel.CanRefuseDownload.includesVersion(11, 41, 0)); | |
140 assertEq("CanRefuseDownload includes 11.42.0", true, BugFixLevel.CanRefuseDownload.includesVersion(11, 42, 0)); | |
141 | |
142 assertEq("CanRefuseDownload includes 11.41.11", false, BugFixLevel.CanRefuseDownload.includesVersion(11, 41, 11)); | |
143 assertEq("CanRefuseDownload includes 11.41.12", true, BugFixLevel.CanRefuseDownload.includesVersion(11, 41, 12)); | |
144 | |
145 assertEq("Level for 0.0.0", BugFixLevel.Baseline, BugFixLevel.forVersion(0, 0, 0)); | |
146 assertEq("Level for 11.0.0", BugFixLevel.Baseline, BugFixLevel.forVersion(11, 0, 0)); | |
147 assertEq("Level for 11.41.0", BugFixLevel.Baseline, BugFixLevel.forVersion(11, 41, 0)); | |
148 assertEq("Level for 11.41.11", BugFixLevel.Baseline, BugFixLevel.forVersion(11, 41, 11)); | |
149 assertEq("Level for 11.41.12", BugFixLevel.CanRefuseDownload, BugFixLevel.forVersion(11, 41, 12)); | |
150 assertEq("Level for 11.42.0", BugFixLevel.CanRefuseDownload, BugFixLevel.forVersion(11, 42, 0)); | |
151 assertEq("Level for 12.0.0", BugFixLevel.CanRefuseDownload, BugFixLevel.forVersion(12, 0, 0)); | |
152 | |
153 assertEq("Level for \"11.41.11\"", BugFixLevel.Baseline, BugFixLevel.forVersion("11.41.11")); | |
154 assertEq("Level for \"11.41.12\"", BugFixLevel.CanRefuseDownload, BugFixLevel.forVersion("11.41.12")); | |
155 } | |
156 | |
157 public void test_Upload() throws SQLException, Failure { | |
68 prepare(); | 158 prepare(); |
69 MyUploadHandler handler = new MyUploadHandler(100); | 159 MyUploadHandler handler = new MyUploadHandler(100); |
70 conn.setUploadHandler(handler); | 160 conn.setUploadHandler(handler); |
71 update("COPY INTO foo FROM 'banana' ON CLIENT", 100); | 161 update("COPY INTO foo FROM 'banana' ON CLIENT", 100); |
72 assertEq("cancellation callback called", false, handler.isCancelled()); | 162 assertEq("cancellation callback called", false, handler.isCancelled()); |
73 queryInt("SELECT COUNT(*) FROM foo", 100); | 163 assertQueryInt("SELECT COUNT(*) FROM foo", 100); |
74 } | 164 } |
75 | 165 |
76 public void test_ClientRefusesUpload() throws Exception { | 166 public void test_ClientRefusesUpload() throws SQLException, Failure { |
77 prepare(); | 167 prepare(); |
78 MyUploadHandler handler = new MyUploadHandler("immediate error"); | 168 MyUploadHandler handler = new MyUploadHandler("immediate error"); |
79 conn.setUploadHandler(handler); | 169 conn.setUploadHandler(handler); |
80 expectError("COPY INTO foo FROM 'banana' ON CLIENT", "immediate error"); | 170 expectError("COPY INTO foo FROM 'banana' ON CLIENT", "immediate error"); |
81 assertEq("cancellation callback called", false, handler.isCancelled()); | 171 assertEq("cancellation callback called", false, handler.isCancelled()); |
82 queryInt("SELECT COUNT(*) FROM foo", 0); | 172 assertQueryInt("SELECT COUNT(*) FROM foo", 0); |
83 } | 173 } |
84 | 174 |
85 public void test_Offset0() throws SQLException, Failure { | 175 public void test_Offset0() throws SQLException, Failure { |
86 prepare(); | 176 prepare(); |
87 MyUploadHandler handler = new MyUploadHandler(100); | 177 MyUploadHandler handler = new MyUploadHandler(100); |
88 conn.setUploadHandler(handler); | 178 conn.setUploadHandler(handler); |
89 update("COPY OFFSET 0 INTO foo FROM 'banana' ON CLIENT", 100); | 179 update("COPY OFFSET 0 INTO foo FROM 'banana' ON CLIENT", 100); |
90 assertEq("cancellation callback called", false, handler.isCancelled()); | 180 assertEq("cancellation callback called", false, handler.isCancelled()); |
91 queryInt("SELECT MIN(i) FROM foo", 1); | 181 assertQueryInt("SELECT MIN(i) FROM foo", 1); |
92 queryInt("SELECT MAX(i) FROM foo", 100); | 182 assertQueryInt("SELECT MAX(i) FROM foo", 100); |
93 } | 183 } |
94 | 184 |
95 public void test_Offset1() throws SQLException, Failure { | 185 public void test_Offset1() throws SQLException, Failure { |
96 prepare(); | 186 prepare(); |
97 MyUploadHandler handler = new MyUploadHandler(100); | 187 MyUploadHandler handler = new MyUploadHandler(100); |
98 conn.setUploadHandler(handler); | 188 conn.setUploadHandler(handler); |
99 update("COPY OFFSET 1 INTO foo FROM 'banana' ON CLIENT", 100); | 189 update("COPY OFFSET 1 INTO foo FROM 'banana' ON CLIENT", 100); |
100 assertEq("cancellation callback called", false, handler.isCancelled()); | 190 assertEq("cancellation callback called", false, handler.isCancelled()); |
101 queryInt("SELECT MIN(i) FROM foo", 1); | 191 assertQueryInt("SELECT MIN(i) FROM foo", 1); |
102 queryInt("SELECT MAX(i) FROM foo", 100); | 192 assertQueryInt("SELECT MAX(i) FROM foo", 100); |
103 } | 193 } |
104 | 194 |
105 public void test_Offset5() throws SQLException, Failure { | 195 public void test_Offset5() throws SQLException, Failure { |
106 prepare(); | 196 prepare(); |
107 MyUploadHandler handler = new MyUploadHandler(100); | 197 MyUploadHandler handler = new MyUploadHandler(100); |
108 conn.setUploadHandler(handler); | 198 conn.setUploadHandler(handler); |
109 update("COPY OFFSET 5 INTO foo FROM 'banana' ON CLIENT", 96); | 199 update("COPY OFFSET 5 INTO foo FROM 'banana' ON CLIENT", 96); |
110 assertEq("cancellation callback called", false, handler.isCancelled()); | 200 assertEq("cancellation callback called", false, handler.isCancelled()); |
111 queryInt("SELECT MIN(i) FROM foo", 5); | 201 assertQueryInt("SELECT MIN(i) FROM foo", 5); |
112 queryInt("SELECT MAX(i) FROM foo", 100); | 202 assertQueryInt("SELECT MAX(i) FROM foo", 100); |
113 } | 203 } |
114 | 204 |
115 public void test_ServerStopsReading() throws SQLException, Failure { | 205 public void test_ServerStopsReading() throws SQLException, Failure { |
116 prepare(); | 206 prepare(); |
117 MyUploadHandler handler = new MyUploadHandler(100); | 207 MyUploadHandler handler = new MyUploadHandler(100); |
118 conn.setUploadHandler(handler); | 208 conn.setUploadHandler(handler); |
119 update("COPY 10 RECORDS INTO foo FROM 'banana' ON CLIENT", 10); | 209 update("COPY 10 RECORDS INTO foo FROM 'banana' ON CLIENT", 10); |
120 assertEq("cancellation callback called", true, handler.isCancelled()); | 210 assertEq("cancellation callback called", true, handler.isCancelled()); |
121 assertEq("handler encountered write error", true, handler.encounteredWriteError()); | 211 assertEq("handler encountered write error", true, handler.encounteredWriteError()); |
122 // Server stopped reading after 10 rows. Will we stay in sync? | 212 // connection is still alive |
123 queryInt("SELECT COUNT(i) FROM foo", 10); | 213 assertQueryInt("SELECT COUNT(i) FROM foo", 10); |
124 } | 214 } |
125 | 215 |
126 public void test_Download(int n) throws SQLException, Failure { | 216 public void test_Download(int n) throws SQLException, Failure { |
127 prepare(); | 217 prepare(); |
128 MyDownloadHandler handler = new MyDownloadHandler(); | 218 MyDownloadHandler handler = new MyDownloadHandler(); |
130 String q = "INSERT INTO foo SELECT value as i, 'number' || value AS t FROM sys.generate_series(0, " + n + ")"; | 220 String q = "INSERT INTO foo SELECT value as i, 'number' || value AS t FROM sys.generate_series(0, " + n + ")"; |
131 update(q, n); | 221 update(q, n); |
132 update("COPY (SELECT * FROM foo) INTO 'banana' ON CLIENT", -1); | 222 update("COPY (SELECT * FROM foo) INTO 'banana' ON CLIENT", -1); |
133 assertEq("download attempts", 1, handler.countAttempts()); | 223 assertEq("download attempts", 1, handler.countAttempts()); |
134 assertEq("lines downloaded", n, handler.lineCount()); | 224 assertEq("lines downloaded", n, handler.lineCount()); |
225 // connection is still alive | |
226 assertQueryInt("SELECT COUNT(*) FROM foo", n); | |
135 } | 227 } |
136 | 228 |
137 public void test_Download() throws SQLException, Failure { | 229 public void test_Download() throws SQLException, Failure { |
138 test_Download(100); | 230 test_Download(100); |
139 } | 231 } |
140 | 232 |
141 public void test_ClientRefusesDownload() throws SQLException, Failure { | 233 public void test_ClientRefusesDownload() throws SQLException, Failure { |
142 prepare(); | 234 prepare(); |
235 BugFixLevel level = getLevel(); | |
143 MyDownloadHandler handler = new MyDownloadHandler("download refused"); | 236 MyDownloadHandler handler = new MyDownloadHandler("download refused"); |
144 conn.setDownloadHandler(handler); | 237 conn.setDownloadHandler(handler); |
145 update("INSERT INTO foo SELECT value as i, 'number' || value AS t FROM sys.generate_series(0, 100)", 100); | 238 update("INSERT INTO foo SELECT value as i, 'number' || value AS t FROM sys.generate_series(0, 100)", 100); |
146 expectError("COPY (SELECT * FROM foo) INTO 'banana' ON CLIENT", "download refused"); | 239 expectError("COPY (SELECT * FROM foo) INTO 'banana' ON CLIENT", "download refused"); |
147 // Wish it were different but the server closes the connection | 240 // Wish it were different but the server closes the connection |
148 expectError("SELECT 42 -- check if the connection still works", "Connection to server lost!"); | 241 expectError("SELECT 42 -- check if the connection still works", "Connection to server lost!"); |
242 if (level.compareTo(BugFixLevel.CanRefuseDownload) >= 0) { | |
243 // connection is still alive | |
244 assertQueryInt("SELECT COUNT(*) FROM foo", 100); | |
245 } | |
149 } | 246 } |
150 | 247 |
151 public void test_LargeUpload() throws SQLException, Failure { | 248 public void test_LargeUpload() throws SQLException, Failure { |
152 watchDog.setDuration(25_000); | 249 watchDog.setDuration(25_000); |
153 prepare(); | 250 prepare(); |
155 MyUploadHandler handler = new MyUploadHandler(n); | 252 MyUploadHandler handler = new MyUploadHandler(n); |
156 conn.setUploadHandler(handler); | 253 conn.setUploadHandler(handler); |
157 handler.setChunkSize(1024 * 1024); | 254 handler.setChunkSize(1024 * 1024); |
158 update("COPY INTO foo FROM 'banana' ON CLIENT", n); | 255 update("COPY INTO foo FROM 'banana' ON CLIENT", n); |
159 assertEq("cancellation callback called", false, handler.isCancelled()); | 256 assertEq("cancellation callback called", false, handler.isCancelled()); |
160 queryInt("SELECT COUNT(DISTINCT i) FROM foo", n); | 257 // connection is still alive |
258 assertQueryInt("SELECT COUNT(DISTINCT i) FROM foo", n); | |
161 } | 259 } |
162 | 260 |
163 public void test_LargeDownload() throws SQLException, Failure { | 261 public void test_LargeDownload() throws SQLException, Failure { |
164 watchDog.setDuration(25_000); | 262 watchDog.setDuration(25_000); |
165 test_Download(4_000_000); | 263 test_Download(4_000_000); |
177 handle.uploadFrom(s); | 275 handle.uploadFrom(s); |
178 } | 276 } |
179 }; | 277 }; |
180 conn.setUploadHandler(handler); | 278 conn.setUploadHandler(handler); |
181 update("COPY INTO foo FROM 'banana' ON CLIENT", 3); | 279 update("COPY INTO foo FROM 'banana' ON CLIENT", 3); |
182 queryInt("SELECT i FROM foo WHERE t = 'three'", 3); | 280 // connection is still alive |
281 assertQueryInt("SELECT i FROM foo WHERE t = 'three'", 3); | |
183 } | 282 } |
184 | 283 |
185 public void test_UploadFromReader() throws SQLException, Failure { | 284 public void test_UploadFromReader() throws SQLException, Failure { |
186 prepare(); | 285 prepare(); |
187 UploadHandler handler = new UploadHandler() { | 286 UploadHandler handler = new UploadHandler() { |
194 handle.uploadFrom(r); | 293 handle.uploadFrom(r); |
195 } | 294 } |
196 }; | 295 }; |
197 conn.setUploadHandler(handler); | 296 conn.setUploadHandler(handler); |
198 update("COPY INTO foo FROM 'banana' ON CLIENT", 3); | 297 update("COPY INTO foo FROM 'banana' ON CLIENT", 3); |
199 queryInt("SELECT i FROM foo WHERE t = 'three'", 3); | 298 assertQueryInt("SELECT i FROM foo WHERE t = 'three'", 3); |
200 } | 299 } |
201 | 300 |
202 public void test_UploadFromReaderOffset() throws SQLException, Failure { | 301 public void test_UploadFromReaderOffset() throws SQLException, Failure { |
203 prepare(); | 302 prepare(); |
204 UploadHandler handler = new UploadHandler() { | 303 UploadHandler handler = new UploadHandler() { |
210 handle.uploadFrom(r, linesToSkip); | 309 handle.uploadFrom(r, linesToSkip); |
211 } | 310 } |
212 }; | 311 }; |
213 conn.setUploadHandler(handler); | 312 conn.setUploadHandler(handler); |
214 update("COPY OFFSET 2 INTO foo FROM 'banana' ON CLIENT", 2); | 313 update("COPY OFFSET 2 INTO foo FROM 'banana' ON CLIENT", 2); |
215 queryInt("SELECT i FROM foo WHERE t = 'three'", 3); | 314 assertQueryInt("SELECT i FROM foo WHERE t = 'three'", 3); |
216 } | 315 } |
217 | 316 |
218 public void test_FailUploadLate() throws SQLException, Failure { | 317 public void test_FailUploadLate() throws SQLException, Failure { |
219 prepare(); | 318 prepare(); |
220 MyUploadHandler handler = new MyUploadHandler(100, 50, "i don't like line 50"); | 319 MyUploadHandler handler = new MyUploadHandler(100, 50, "i don't like line 50"); |
244 expectError("COPY INTO foo(t) FROM 'banana'(t) ON CLIENT", "after all"); | 343 expectError("COPY INTO foo(t) FROM 'banana'(t) ON CLIENT", "after all"); |
245 assertEq("connection is closed", true, conn.isClosed()); | 344 assertEq("connection is closed", true, conn.isClosed()); |
246 // Cannot check the server log, but at the time I checked, it said "prematurely stopped client", which is fine. | 345 // Cannot check the server log, but at the time I checked, it said "prematurely stopped client", which is fine. |
247 } | 346 } |
248 | 347 |
249 // Disabled because it hangs, triggering the watchdog timer | |
250 public void test_FailDownloadLate() throws SQLException, Failure { | 348 public void test_FailDownloadLate() throws SQLException, Failure { |
251 prepare(); | 349 prepare(); |
252 MyDownloadHandler handler = new MyDownloadHandler(200, "download refused"); | 350 MyDownloadHandler handler = new MyDownloadHandler(200, "download refused"); |
253 conn.setDownloadHandler(handler); | 351 conn.setDownloadHandler(handler); |
254 update("INSERT INTO foo SELECT value as i, 'number' || value AS t FROM sys.generate_series(0, 100)", 100); | 352 update("INSERT INTO foo SELECT value as i, 'number' || value AS t FROM sys.generate_series(0, 100)", 100); |
267 ps.println("2|two"); | 365 ps.println("2|two"); |
268 ps.println("3|three"); | 366 ps.println("3|three"); |
269 ps.close(); | 367 ps.close(); |
270 conn.setUploadHandler(new FileTransferHandler(d, true)); | 368 conn.setUploadHandler(new FileTransferHandler(d, true)); |
271 update("COPY INTO foo FROM 'data.txt' ON CLIENT", 3); | 369 update("COPY INTO foo FROM 'data.txt' ON CLIENT", 3); |
272 queryInt("SELECT SUM(i) FROM foo", 6); | 370 assertQueryInt("SELECT SUM(i) FROM foo", 6); |
273 } | 371 } |
274 | 372 |
275 public void test_FileTransferHandlerUploadRefused() throws IOException, SQLException, Failure { | 373 public void test_FileTransferHandlerUploadRefused() throws IOException, SQLException, Failure { |
276 prepare(); | 374 prepare(); |
277 Path d = getTmpDir(currentTestName); | 375 Path d = getTmpDir(currentTestName); |
286 Path d2 = getTmpDir(currentTestName + "2"); | 384 Path d2 = getTmpDir(currentTestName + "2"); |
287 conn.setUploadHandler(new FileTransferHandler(d2, false)); | 385 conn.setUploadHandler(new FileTransferHandler(d2, false)); |
288 String quoted = f.toAbsolutePath().toString().replaceAll("'", "''"); | 386 String quoted = f.toAbsolutePath().toString().replaceAll("'", "''"); |
289 expectError("COPY INTO foo FROM R'"+ quoted + "' ON CLIENT", "not in upload directory"); | 387 expectError("COPY INTO foo FROM R'"+ quoted + "' ON CLIENT", "not in upload directory"); |
290 // connection is still alive | 388 // connection is still alive |
291 queryInt("SELECT SUM(i) FROM foo", 0); | 389 assertQueryInt("SELECT SUM(i) FROM foo", 0); |
292 } | 390 } |
293 | 391 |
294 public void test_FileTransferHandlerDownload() throws SQLException, Failure, IOException { | 392 public void test_FileTransferHandlerDownload() throws SQLException, Failure, IOException { |
295 prepare(); | 393 prepare(); |
296 update("INSERT INTO foo VALUES (42, 'forty-two')", 1); | 394 update("INSERT INTO foo VALUES (42, 'forty-two')", 1); |
298 conn.setDownloadHandler(new FileTransferHandler(d, false)); | 396 conn.setDownloadHandler(new FileTransferHandler(d, false)); |
299 update("COPY SELECT * FROM foo INTO 'data.txt' ON CLIENT", -1); | 397 update("COPY SELECT * FROM foo INTO 'data.txt' ON CLIENT", -1); |
300 List<String> lines = Files.readAllLines(d.resolve("data.txt")); | 398 List<String> lines = Files.readAllLines(d.resolve("data.txt")); |
301 assertEq("lines written", lines.size(), 1); | 399 assertEq("lines written", lines.size(), 1); |
302 assertEq("line content", lines.get(0), "42|\"forty-two\""); | 400 assertEq("line content", lines.get(0), "42|\"forty-two\""); |
401 // connection is still alive | |
402 assertQueryInt("SELECT SUM(i) FROM foo", 42); | |
303 } | 403 } |
304 | 404 |
305 public void test_FileTransferHandlerDownloadRefused() throws SQLException, Failure, IOException { | 405 public void test_FileTransferHandlerDownloadRefused() throws SQLException, Failure, IOException { |
306 prepare(); | 406 prepare(); |
407 BugFixLevel level = getLevel(); | |
307 update("INSERT INTO foo VALUES (42, 'forty-two')", 1); | 408 update("INSERT INTO foo VALUES (42, 'forty-two')", 1); |
308 Path d = getTmpDir(currentTestName); | 409 Path d = getTmpDir(currentTestName); |
309 Path d2 = getTmpDir(currentTestName + "2"); | 410 Path d2 = getTmpDir(currentTestName + "2"); |
310 conn.setDownloadHandler(new FileTransferHandler(d2, false)); | 411 conn.setDownloadHandler(new FileTransferHandler(d2, false)); |
311 String quoted = d.resolve("data.txt").toAbsolutePath().toString().replaceAll("'", "''"); | 412 String quoted = d.resolve("data.txt").toAbsolutePath().toString().replaceAll("'", "''"); |
312 expectError("COPY SELECT * FROM foo INTO R'" + quoted + "' ON CLIENT", "not in download directory"); | 413 expectError("COPY SELECT * FROM foo INTO R'" + quoted + "' ON CLIENT", "not in download directory"); |
313 | 414 if (level.compareTo(BugFixLevel.CanRefuseDownload) >= 0) { |
415 // connection is still alive | |
416 assertQueryInt("SELECT SUM(i) FROM foo", 42); | |
417 } | |
314 } | 418 } |
315 | 419 |
316 static class MyUploadHandler implements UploadHandler { | 420 static class MyUploadHandler implements UploadHandler { |
317 private final long rows; | 421 private final long rows; |
318 private final long errorAt; | 422 private final long errorAt; |