1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.dbutils;
18
19 import static org.junit.Assert.fail;
20 import static org.mockito.ArgumentMatchers.any;
21 import static org.mockito.Mockito.doThrow;
22 import static org.mockito.Mockito.mock;
23 import static org.mockito.Mockito.times;
24 import static org.mockito.Mockito.verify;
25 import static org.mockito.Mockito.when;
26
27 import java.sql.Connection;
28 import java.sql.ParameterMetaData;
29 import java.sql.PreparedStatement;
30 import java.sql.ResultSet;
31 import java.sql.SQLException;
32 import java.sql.Statement;
33 import java.util.concurrent.ExecutionException;
34 import java.util.concurrent.Executors;
35 import java.util.concurrent.Future;
36 import java.util.concurrent.TimeUnit;
37
38 import javax.sql.DataSource;
39
40 import org.apache.commons.dbutils.handlers.ArrayHandler;
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.junit.runner.RunWith;
44 import org.mockito.Mock;
45 import org.mockito.junit.MockitoJUnitRunner;
46
47 @SuppressWarnings("boxing")
48 @RunWith(MockitoJUnitRunner.class)
49 public class AsyncQueryRunnerTest {
50 AsyncQueryRunner runner;
51 ArrayHandler handler;
52
53 @Mock DataSource dataSource;
54 @Mock Connection conn;
55 @Mock PreparedStatement prepStmt;
56 @Mock Statement stmt;
57 @Mock ParameterMetaData meta;
58 @Mock ResultSet results;
59
60
61 private void callBatchWithException(final String sql, final Object[][] params) throws Exception {
62 Future<int[]> future = null;
63 boolean caught = false;
64
65 try {
66 future = runner.batch(sql, params);
67
68 future.get();
69
70 verify(prepStmt, times(2)).addBatch();
71 verify(prepStmt, times(1)).executeBatch();
72 verify(prepStmt, times(1)).close();
73 verify(conn, times(1)).close();
74 } catch (final Exception e) {
75 caught = true;
76 }
77
78 if (!caught) {
79 fail("Exception never thrown, but expected");
80 }
81 }
82
83
84
85
86 private void callGoodBatch(final Connection conn, final Object[][] params) throws Exception {
87 when(meta.getParameterCount()).thenReturn(2);
88 final Future<int[]> future = runner.batch(conn, "select * from blah where ? = ?", params);
89
90 future.get();
91
92 verify(prepStmt, times(2)).addBatch();
93 verify(prepStmt, times(1)).executeBatch();
94 verify(prepStmt, times(1)).close();
95 verify(conn, times(0)).close();
96 }
97
98 private void callGoodBatch(final Object[][] params) throws Exception {
99 when(meta.getParameterCount()).thenReturn(2);
100 final Future<int[]> future = runner.batch("select * from blah where ? = ?", params);
101
102 future.get();
103
104 verify(prepStmt, times(2)).addBatch();
105 verify(prepStmt, times(1)).executeBatch();
106 verify(prepStmt, times(1)).close();
107 verify(conn, times(1)).close();
108 }
109
110 private void callGoodQuery() throws Exception {
111 when(meta.getParameterCount()).thenReturn(2);
112 String sql = "select * from blah where ? = ?";
113 runner.query(sql, handler, "unit", "test").get();
114
115 verify(prepStmt, times(1)).executeQuery();
116 verify(results, times(1)).close();
117 verify(prepStmt, times(1)).close();
118 verify(conn, times(1)).close();
119
120
121 sql = "select * from blah";
122 runner.query(sql, handler).get();
123
124 verify(stmt, times(1)).executeQuery(sql);
125 verify(results, times(2)).close();
126 verify(stmt, times(1)).close();
127 verify(conn, times(2)).close();
128 }
129
130
131
132
133 private void callGoodQuery(final Connection conn) throws Exception {
134 when(meta.getParameterCount()).thenReturn(2);
135 String sql = "select * from blah where ? = ?";
136 runner.query(conn, sql, handler, "unit", "test").get();
137
138 verify(prepStmt, times(1)).executeQuery();
139 verify(results, times(1)).close();
140 verify(prepStmt, times(1)).close();
141 verify(conn, times(0)).close();
142
143
144 sql = "select * from blah";
145 runner.query(conn, sql, handler).get();
146
147 verify(stmt, times(1)).executeQuery(sql);
148 verify(results, times(2)).close();
149 verify(stmt, times(1)).close();
150 verify(conn, times(0)).close();
151 }
152
153 private void callGoodUpdate() throws Exception {
154 when(meta.getParameterCount()).thenReturn(2);
155 String sql = "update blah set ? = ?";
156 runner.update(sql, "unit", "test").get();
157
158 verify(prepStmt, times(1)).executeUpdate();
159 verify(prepStmt, times(1)).close();
160 verify(conn, times(1)).close();
161
162
163 when(meta.getParameterCount()).thenReturn(0);
164 sql = "update blah set unit = test";
165 runner.update(sql).get();
166
167 verify(stmt, times(1)).executeUpdate(sql);
168 verify(stmt, times(1)).close();
169 verify(conn, times(2)).close();
170
171
172 when(meta.getParameterCount()).thenReturn(1);
173 runner.update("update blah set unit = ?", "test").get();
174
175 verify(prepStmt, times(2)).executeUpdate();
176 verify(prepStmt, times(2)).close();
177 verify(conn, times(3)).close();
178 }
179
180
181
182
183 private void callGoodUpdate(final Connection conn) throws Exception {
184 when(meta.getParameterCount()).thenReturn(2);
185 String sql = "update blah set ? = ?";
186 runner.update(conn, sql, "unit", "test").get();
187
188 verify(prepStmt, times(1)).executeUpdate();
189 verify(prepStmt, times(1)).close();
190 verify(conn, times(0)).close();
191
192
193 when(meta.getParameterCount()).thenReturn(0);
194 sql = "update blah set unit = test";
195 runner.update(conn, sql).get();
196
197 verify(stmt, times(1)).executeUpdate(sql);
198 verify(stmt, times(1)).close();
199 verify(conn, times(0)).close();
200
201
202 when(meta.getParameterCount()).thenReturn(1);
203 sql = "update blah set unit = ?";
204 runner.update(conn, sql, "test").get();
205
206 verify(prepStmt, times(2)).executeUpdate();
207 verify(prepStmt, times(2)).close();
208 verify(conn, times(0)).close();
209 }
210
211
212
213
214 private void callQueryWithException(final Object... params) throws Exception {
215 boolean caught = false;
216
217 try {
218 when(meta.getParameterCount()).thenReturn(2);
219 runner.query("select * from blah where ? = ?", handler, params).get();
220
221 verify(prepStmt, times(1)).executeQuery();
222 verify(results, times(1)).close();
223 verify(prepStmt, times(1)).close();
224 verify(conn, times(1)).close();
225 } catch (final Exception e) {
226 caught = true;
227 }
228
229 if (!caught) {
230 fail("Exception never thrown, but expected");
231 }
232 }
233
234
235 private void callUpdateWithException(final Object... params) throws Exception {
236 boolean caught = false;
237
238 try {
239 when(meta.getParameterCount()).thenReturn(2);
240 runner.update("select * from blah where ? = ?", params).get();
241
242 verify(prepStmt, times(1)).executeUpdate();
243 verify(prepStmt, times(1)).close();
244 verify(conn, times(1)).close();
245 } catch (final Exception e) {
246 caught = true;
247 }
248
249 if (!caught) {
250 fail("Exception never thrown, but expected");
251 }
252 }
253
254 @Before
255 public void setUp() throws Exception {
256 when(dataSource.getConnection()).thenReturn(conn);
257
258 when(conn.prepareStatement(any(String.class))).thenReturn(prepStmt);
259 when(prepStmt.getParameterMetaData()).thenReturn(meta);
260 when(prepStmt.executeQuery()).thenReturn(results);
261
262 when(conn.createStatement()).thenReturn(stmt);
263 when(stmt.executeQuery(any(String.class))).thenReturn(results);
264
265 when(results.next()).thenReturn(false);
266
267 handler = new ArrayHandler();
268 runner = new AsyncQueryRunner(Executors.newFixedThreadPool(1), new QueryRunner(dataSource));
269 }
270
271 @Test
272 public void testAddBatchException() throws Exception {
273 final String[][] params = { { "unit", "unit" }, { "test", "test" } };
274
275 callBatchWithException("select * from blah where ? = ?", params);
276 }
277
278
279
280
281 @Test(expected=ExecutionException.class)
282 public void testBadPrepareConnection() throws Exception {
283 runner = new AsyncQueryRunner(Executors.newFixedThreadPool(1));
284 runner.update("update blah set unit = test").get();
285 }
286
287 @Test
288 public void testExecuteBatchException() throws Exception {
289 final String[][] params = { { "unit", "unit" }, { "test", "test" } };
290
291 callBatchWithException("select * from blah where ? = ?", params);
292 }
293
294 @Test
295 public void testExecuteQueryException() throws Exception {
296 callQueryWithException(handler, "unit", "test");
297 }
298
299 @Test
300 public void testExecuteUpdateException() throws Exception {
301 doThrow(new SQLException()).when(prepStmt).executeUpdate();
302
303 callUpdateWithException("unit", "test");
304 }
305
306
307 @Test
308 public void testGoodBatch() throws Exception {
309 final String[][] params = { { "unit", "unit" }, { "test", "test" } };
310
311 callGoodBatch(params);
312 }
313
314 @Test
315 public void testGoodBatchDefaultConstructor() throws Exception {
316 runner = new AsyncQueryRunner(Executors.newFixedThreadPool(1));
317 final String[][] params = { { "unit", "unit" }, { "test", "test" } };
318
319 callGoodBatch(conn, params);
320 }
321
322 @SuppressWarnings("deprecation")
323 @Test
324 public void testGoodBatchPmdTrue() throws Exception {
325 runner = new AsyncQueryRunner(dataSource, true, Executors.newFixedThreadPool(1));
326 final String[][] params = { { "unit", "unit" }, { "test", "test" } };
327
328 callGoodBatch(params);
329 }
330
331 @Test
332 public void testGoodQuery() throws Exception {
333 callGoodQuery();
334 }
335
336 @Test
337 public void testGoodQueryDefaultConstructor() throws Exception {
338 runner = new AsyncQueryRunner(Executors.newFixedThreadPool(1));
339 callGoodQuery(conn);
340 }
341
342
343 @SuppressWarnings("deprecation")
344 @Test
345 public void testGoodQueryPmdTrue() throws Exception {
346 runner = new AsyncQueryRunner(true, Executors.newFixedThreadPool(1));
347 callGoodQuery(conn);
348 }
349
350 @Test
351 public void testGoodUpdate() throws Exception {
352 callGoodUpdate();
353 }
354
355 @Test
356 public void testGoodUpdateDefaultConstructor() throws Exception {
357 runner = new AsyncQueryRunner(Executors.newFixedThreadPool(1));
358 callGoodUpdate(conn);
359 }
360
361 @SuppressWarnings("deprecation")
362 @Test
363 public void testGoodUpdatePmdTrue() throws Exception {
364 runner = new AsyncQueryRunner(true, Executors.newFixedThreadPool(1));
365 callGoodUpdate(conn);
366 }
367
368 @Test
369 public void testInsertUsesGivenQueryRunner() throws Exception {
370 final QueryRunner mockQueryRunner = mock(QueryRunner.class
371 , org.mockito.Mockito.withSettings().verboseLogging()
372 );
373 runner = new AsyncQueryRunner(Executors.newSingleThreadExecutor(), mockQueryRunner);
374
375 runner.insert("1", handler);
376 runner.insert("2", handler, "param1");
377 runner.insert(conn, "3", handler);
378 runner.insert(conn, "4", handler, "param1");
379
380
381 TimeUnit.MILLISECONDS.sleep(50);
382
383 verify(mockQueryRunner).insert("1", handler);
384 verify(mockQueryRunner).insert("2", handler, "param1");
385 verify(mockQueryRunner).insert(conn, "3", handler);
386 verify(mockQueryRunner).insert(conn, "4", handler, "param1");
387 }
388
389 @Test
390 public void testNoParamsQuery() throws Exception {
391 callGoodQuery();
392 }
393
394 @Test
395 public void testNoParamsUpdate() throws Exception {
396 callGoodUpdate();
397 }
398
399 @Test(expected=ExecutionException.class)
400 public void testNullConnectionBatch() throws Exception {
401 final String[][] params = { { "unit", "unit" }, { "test", "test" } };
402
403 when(dataSource.getConnection()).thenReturn(null);
404
405 runner.batch("select * from blah where ? = ?", params).get();
406 }
407
408
409 @Test(expected=ExecutionException.class)
410 public void testNullConnectionQuery() throws Exception {
411 when(dataSource.getConnection()).thenReturn(null);
412
413 runner.query("select * from blah where ? = ?", handler, "unit", "test").get();
414 }
415
416 @Test(expected=ExecutionException.class)
417 public void testNullConnectionUpdate() throws Exception {
418 when(dataSource.getConnection()).thenReturn(null);
419
420 runner.update("select * from blah where ? = ?", "unit", "test").get();
421 }
422
423 @Test(expected=ExecutionException.class)
424 public void testNullHandlerQuery() throws Exception {
425 runner.query("select * from blah where ? = ?", null).get();
426 }
427
428 @Test(expected=ExecutionException.class)
429 public void testNullParamsArgBatch() throws Exception {
430 runner.batch("select * from blah where ? = ?", null).get();
431 }
432
433 @Test
434 public void testNullParamsBatch() throws Exception {
435 final String[][] params = { { null, "unit" }, { "test", null } };
436
437 callGoodBatch(params);
438 }
439
440 @Test(expected=ExecutionException.class)
441 public void testNullSqlBatch() throws Exception {
442 final String[][] params = { { "unit", "unit" }, { "test", "test" } };
443
444 runner.batch(null, params).get();
445 }
446
447 @Test(expected=ExecutionException.class)
448 public void testNullSqlQuery() throws Exception {
449 runner.query(null, handler).get();
450 }
451
452 @Test(expected=ExecutionException.class)
453 public void testNullSqlUpdate() throws Exception {
454 runner.update(null).get();
455 }
456
457 @Test
458 public void testTooFewParamsBatch() throws Exception {
459 final String[][] params = { { "unit" }, { "test" } };
460
461 callBatchWithException("select * from blah where ? = ?", params);
462 }
463
464 @Test
465 public void testTooFewParamsQuery() throws Exception {
466 callQueryWithException("unit");
467 }
468
469 @Test
470 public void testTooFewParamsUpdate() throws Exception {
471 callUpdateWithException("unit");
472 }
473
474 @Test
475 public void testTooManyParamsBatch() throws Exception {
476 final String[][] params = { { "unit", "unit", "unit" }, { "test", "test", "test" } };
477
478 callBatchWithException("select * from blah where ? = ?", params);
479 }
480
481 @Test
482 public void testTooManyParamsQuery() throws Exception {
483 callQueryWithException("unit", "test", "fail");
484 }
485
486 @Test
487 public void testTooManyParamsUpdate() throws Exception {
488 callUpdateWithException("unit", "test", "fail");
489 }
490 }