comparison tests/OnClientTester.java @ 533:b75464874130 onclient

Keep better track of whether the server has cancelled the upload IOExceptions are suppressed by PrintStreams print/println methods. This means the client may not realize the server cancelled and we must suppress all further attempts to write. Also, the end of upload handshake is different if a cancellation occurred.
author Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
date Fri, 27 Aug 2021 13:45:38 +0200 (2021-08-27)
parents 53dc4349ace9
children b437529144f1
comparison
equal deleted inserted replaced
532:41a28ec7d1c1 533:b75464874130
47 execute("CREATE TABLE foo (i INT, t TEXT)"); 47 execute("CREATE TABLE foo (i INT, t TEXT)");
48 } 48 }
49 49
50 public void test_Upload() throws Exception { 50 public void test_Upload() throws Exception {
51 prepare(); 51 prepare();
52 conn.setUploadHandler(new MyUploadHandler(100)); 52 MyUploadHandler handler = new MyUploadHandler(100);
53 conn.setUploadHandler(handler);
53 update("COPY INTO foo FROM 'banana' ON CLIENT", 100); 54 update("COPY INTO foo FROM 'banana' ON CLIENT", 100);
55 assertEq("handler encountered write error", false, handler.encounteredWriteError());
54 queryInt("SELECT COUNT(*) FROM foo", 100); 56 queryInt("SELECT COUNT(*) FROM foo", 100);
55 } 57 }
56 58
57 public void test_ClientRefusesUpload() throws Exception { 59 public void test_ClientRefusesUpload() throws Exception {
58 prepare(); 60 prepare();
59 conn.setUploadHandler(new MyUploadHandler("immediate error")); 61 MyUploadHandler handler = new MyUploadHandler("immediate error");
62 conn.setUploadHandler(handler);
60 expectError("COPY INTO foo FROM 'banana' ON CLIENT", "immediate error"); 63 expectError("COPY INTO foo FROM 'banana' ON CLIENT", "immediate error");
64 assertEq("handler encountered write error", false, handler.encounteredWriteError());
61 queryInt("SELECT COUNT(*) FROM foo", 0); 65 queryInt("SELECT COUNT(*) FROM foo", 0);
62 } 66 }
63 67
64 public void test_Offset0() throws SQLException, Failure { 68 public void test_Offset0() throws SQLException, Failure {
65 prepare(); 69 prepare();
66 conn.setUploadHandler(new MyUploadHandler(100)); 70 MyUploadHandler handler = new MyUploadHandler(100);
71 conn.setUploadHandler(handler);
67 update("COPY OFFSET 0 INTO foo FROM 'banana' ON CLIENT", 100); 72 update("COPY OFFSET 0 INTO foo FROM 'banana' ON CLIENT", 100);
73 assertEq("handler encountered write error", false, handler.encounteredWriteError());
68 queryInt("SELECT MIN(i) FROM foo", 1); 74 queryInt("SELECT MIN(i) FROM foo", 1);
69 queryInt("SELECT MAX(i) FROM foo", 100); 75 queryInt("SELECT MAX(i) FROM foo", 100);
70 } 76 }
71 77
72 public void test_Offset1() throws SQLException, Failure { 78 public void test_Offset1() throws SQLException, Failure {
73 prepare(); 79 prepare();
74 conn.setUploadHandler(new MyUploadHandler(100)); 80 MyUploadHandler handler = new MyUploadHandler(100);
81 conn.setUploadHandler(handler);
75 update("COPY OFFSET 1 INTO foo FROM 'banana' ON CLIENT", 100); 82 update("COPY OFFSET 1 INTO foo FROM 'banana' ON CLIENT", 100);
83 assertEq("handler encountered write error", false, handler.encounteredWriteError());
76 queryInt("SELECT MIN(i) FROM foo", 1); 84 queryInt("SELECT MIN(i) FROM foo", 1);
77 queryInt("SELECT MAX(i) FROM foo", 100); 85 queryInt("SELECT MAX(i) FROM foo", 100);
78 } 86 }
79 87
80 public void test_Offset5() throws SQLException, Failure { 88 public void test_Offset5() throws SQLException, Failure {
81 prepare(); 89 prepare();
82 conn.setUploadHandler(new MyUploadHandler(100)); 90 MyUploadHandler handler = new MyUploadHandler(100);
91 conn.setUploadHandler(handler);
83 update("COPY OFFSET 5 INTO foo FROM 'banana' ON CLIENT", 96); 92 update("COPY OFFSET 5 INTO foo FROM 'banana' ON CLIENT", 96);
93 assertEq("handler encountered write error", false, handler.encounteredWriteError());
84 queryInt("SELECT MIN(i) FROM foo", 5); 94 queryInt("SELECT MIN(i) FROM foo", 5);
85 queryInt("SELECT MAX(i) FROM foo", 100); 95 queryInt("SELECT MAX(i) FROM foo", 100);
86 } 96 }
87 97
88 public void test_ServerStopsReading() throws SQLException, Failure { 98 public void test_ServerStopsReading() throws SQLException, Failure {
89 prepare(); 99 prepare();
90 conn.setUploadHandler(new MyUploadHandler(100)); 100 MyUploadHandler handler = new MyUploadHandler(100);
91 update("COPY 10 RECORDS INTO foo FROM 'banana' ON CLIENT", 96); 101 conn.setUploadHandler(handler);
102 update("COPY 10 RECORDS INTO foo FROM 'banana' ON CLIENT", 10);
103 assertEq("handler encountered write error", true, handler.encounteredWriteError());
92 // Server stopped reading after 10 rows. Will we stay in sync? 104 // Server stopped reading after 10 rows. Will we stay in sync?
93 queryInt("SELECT COUNT(i) FROM foo", 10); 105 queryInt("SELECT COUNT(i) FROM foo", 10);
94 } 106 }
95 107
96 public void test_Download(int n) throws SQLException, Failure { 108 public void test_Download(int n) throws SQLException, Failure {
123 int n = 4_000_000; 135 int n = 4_000_000;
124 MyUploadHandler handler = new MyUploadHandler(n); 136 MyUploadHandler handler = new MyUploadHandler(n);
125 conn.setUploadHandler(handler); 137 conn.setUploadHandler(handler);
126 handler.setChunkSize(1024 * 1024); 138 handler.setChunkSize(1024 * 1024);
127 update("COPY INTO foo FROM 'banana' ON CLIENT", n); 139 update("COPY INTO foo FROM 'banana' ON CLIENT", n);
140 assertEq("handler encountered write error", false, handler.encounteredWriteError());
128 queryInt("SELECT COUNT(DISTINCT i) FROM foo", n); 141 queryInt("SELECT COUNT(DISTINCT i) FROM foo", n);
129 } 142 }
130 143
131 public void test_LargeDownload() throws SQLException, Failure { 144 public void test_LargeDownload() throws SQLException, Failure {
132 watchDog.setDuration(25_000); 145 watchDog.setDuration(25_000);
181 queryInt("SELECT i FROM foo WHERE t = 'three'", 3); 194 queryInt("SELECT i FROM foo WHERE t = 'three'", 3);
182 } 195 }
183 196
184 public void test_FailUploadLate() throws SQLException, Failure { 197 public void test_FailUploadLate() throws SQLException, Failure {
185 prepare(); 198 prepare();
186 conn.setUploadHandler(new MyUploadHandler(100, 50, "i don't like line 50")); 199 MyUploadHandler handler = new MyUploadHandler(100, 50, "i don't like line 50");
200 conn.setUploadHandler(handler);
187 expectError("COPY INTO foo FROM 'banana' ON CLIENT", "i don't like"); 201 expectError("COPY INTO foo FROM 'banana' ON CLIENT", "i don't like");
202 assertEq("handler encountered write error", false, handler.encounteredWriteError());
188 assertEq("connection is closed", true, conn.isClosed()); 203 assertEq("connection is closed", true, conn.isClosed());
189 } 204 }
190 205
191 // Disabled because it hangs, triggering the watchdog timer 206 // Disabled because it hangs, triggering the watchdog timer
192 public void testx_FailDownloadLate() throws SQLException, Failure { 207 public void testx_FailDownloadLate() throws SQLException, Failure {
200 215
201 static class MyUploadHandler implements MonetUploadHandler { 216 static class MyUploadHandler implements MonetUploadHandler {
202 private final int rows; 217 private final int rows;
203 private final int errorAt; 218 private final int errorAt;
204 private final String errorMessage; 219 private final String errorMessage;
220 private boolean encounteredWriteError;
205 221
206 private int chunkSize = 100; // small number to trigger more bugs 222 private int chunkSize = 100; // small number to trigger more bugs
207 223
208 MyUploadHandler(int rows, int errorAt, String errorMessage) { 224 MyUploadHandler(int rows, int errorAt, String errorMessage) {
209 this.rows = rows; 225 this.rows = rows;
235 for (int i = toSkip; i < rows; i++) { 251 for (int i = toSkip; i < rows; i++) {
236 if (i == errorAt) { 252 if (i == errorAt) {
237 throw new IOException(errorMessage); 253 throw new IOException(errorMessage);
238 } 254 }
239 stream.printf("%d|%d%n", i + 1, i + 1); 255 stream.printf("%d|%d%n", i + 1, i + 1);
240 } 256 if (i % 25 == 0 && stream.checkError()) {
241 } 257 encounteredWriteError = true;
242 258 break;
259 }
260 }
261 }
262
263 public Object encounteredWriteError() {
264 return encounteredWriteError;
265 }
243 } 266 }
244 267
245 static class MyDownloadHandler implements MonetDownloadHandler { 268 static class MyDownloadHandler implements MonetDownloadHandler {
246 private final int errorAtByte; 269 private final int errorAtByte;
247 private final String errorMessage; 270 private final String errorMessage;