|
16 | 16 |
|
17 | 17 | package com.google.cloud.spanner.jdbc;
|
18 | 18 |
|
19 |
| -import static org.hamcrest.CoreMatchers.endsWith; |
20 |
| -import static org.hamcrest.CoreMatchers.equalTo; |
21 |
| -import static org.hamcrest.CoreMatchers.is; |
22 |
| -import static org.hamcrest.CoreMatchers.nullValue; |
23 |
| -import static org.hamcrest.MatcherAssert.assertThat; |
| 19 | +import static com.google.common.truth.Truth.assertThat; |
24 | 20 | import static org.junit.Assert.fail;
|
25 | 21 |
|
26 | 22 | import com.google.cloud.Timestamp;
|
|
53 | 49 | import java.util.List;
|
54 | 50 | import org.junit.AfterClass;
|
55 | 51 | import org.junit.BeforeClass;
|
56 |
| -import org.junit.Rule; |
57 | 52 | import org.junit.Test;
|
58 |
| -import org.junit.rules.ExpectedException; |
59 | 53 | import org.junit.runner.RunWith;
|
60 | 54 | import org.junit.runners.Parameterized;
|
61 | 55 | import org.junit.runners.Parameterized.Parameter;
|
@@ -110,8 +104,6 @@ public void retryFinished(
|
110 | 104 | @Parameter(0)
|
111 | 105 | public boolean retryAbortsInternally;
|
112 | 106 |
|
113 |
| -@Rule public ExpectedException expected = ExpectedException.none(); |
114 |
| - |
115 | 107 | @Parameters(name = "retryAbortsInternally = {0}")
|
116 | 108 | public static Collection<Object[]> data() {
|
117 | 109 | List<Object[]> params = new ArrayList<>();
|
@@ -175,23 +167,25 @@ public void testAutocommitUpdateAborted() throws SQLException {
|
175 | 167 | try (java.sql.Connection connection = createConnection()) {
|
176 | 168 | mockSpanner.abortNextStatement();
|
177 | 169 | int updateCount = connection.createStatement().executeUpdate(UPDATE_STATEMENT.getSql());
|
178 |
| -assertThat(updateCount, is(equalTo(UPDATE_COUNT))); |
| 170 | +assertThat(updateCount).isEqualTo(UPDATE_COUNT); |
179 | 171 | }
|
180 | 172 | }
|
181 | 173 |
|
182 | 174 | @Test
|
183 | 175 | public void testTransactionalUpdateAborted() throws SQLException {
|
184 | 176 | // Updates in transactional mode are automatically retried by default, but this can be switched
|
185 | 177 | // off.
|
186 |
| -if (!retryAbortsInternally) { |
187 |
| -expected.expect(JdbcAbortedException.class); |
188 |
| -} |
189 | 178 | try (java.sql.Connection connection = createConnection()) {
|
190 | 179 | connection.setAutoCommit(false);
|
191 | 180 | mockSpanner.abortNextStatement();
|
192 | 181 | int updateCount = connection.createStatement().executeUpdate(UPDATE_STATEMENT.getSql());
|
193 |
| -assertThat(updateCount, is(equalTo(UPDATE_COUNT))); |
194 |
| -assertThat(getRetryCount(connection), is(equalTo(1))); |
| 182 | +if (!retryAbortsInternally) { |
| 183 | +fail("missing expected exception"); |
| 184 | +} |
| 185 | +assertThat(updateCount).isEqualTo(UPDATE_COUNT); |
| 186 | +assertThat(getRetryCount(connection)).isEqualTo(1); |
| 187 | +} catch (JdbcAbortedException e) { |
| 188 | +assertThat(retryAbortsInternally).isFalse(); |
195 | 189 | }
|
196 | 190 | }
|
197 | 191 |
|
@@ -203,25 +197,27 @@ public void testAutocommitBatchUpdateAborted() throws SQLException {
|
203 | 197 | statement.addBatch(UPDATE_STATEMENT.getSql());
|
204 | 198 | statement.addBatch(UPDATE_STATEMENT.getSql());
|
205 | 199 | int[] updateCounts = statement.executeBatch();
|
206 |
| -assertThat(updateCounts, is(equalTo(new int[] {UPDATE_COUNT, UPDATE_COUNT}))); |
| 200 | +assertThat(updateCounts).asList().containsExactly(UPDATE_COUNT, UPDATE_COUNT); |
207 | 201 | }
|
208 | 202 | }
|
209 | 203 | }
|
210 | 204 |
|
211 | 205 | @Test
|
212 | 206 | public void testTransactionalBatchUpdateAborted() throws SQLException {
|
213 |
| -if (!retryAbortsInternally) { |
214 |
| -expected.expect(JdbcAbortedException.class); |
215 |
| -} |
216 | 207 | try (java.sql.Connection connection = createConnection()) {
|
217 | 208 | connection.setAutoCommit(false);
|
218 | 209 | mockSpanner.abortNextStatement();
|
219 | 210 | try (java.sql.Statement statement = connection.createStatement()) {
|
220 | 211 | statement.addBatch(UPDATE_STATEMENT.getSql());
|
221 | 212 | statement.addBatch(UPDATE_STATEMENT.getSql());
|
222 | 213 | int[] updateCounts = statement.executeBatch();
|
223 |
| -assertThat(updateCounts, is(equalTo(new int[] {UPDATE_COUNT, UPDATE_COUNT}))); |
224 |
| -assertThat(getRetryCount(connection), is(equalTo(1))); |
| 214 | +if (!retryAbortsInternally) { |
| 215 | +fail("missing expected exception"); |
| 216 | +} |
| 217 | +assertThat(updateCounts).asList().containsExactly(UPDATE_COUNT, UPDATE_COUNT); |
| 218 | +assertThat(getRetryCount(connection)).isEqualTo(1); |
| 219 | +} catch (JdbcAbortedException e) { |
| 220 | +assertThat(retryAbortsInternally).isFalse(); |
225 | 221 | }
|
226 | 222 | }
|
227 | 223 | }
|
@@ -233,38 +229,35 @@ public void testAutocommitSelectAborted() throws SQLException {
|
233 | 229 | mockSpanner.abortNextStatement();
|
234 | 230 | try (ResultSet rs = connection.createStatement().executeQuery(SELECT1.getSql())) {
|
235 | 231 | while (rs.next()) {
|
236 |
| -assertThat(rs.getLong(1), is(equalTo(1L))); |
| 232 | +assertThat(rs.getLong(1)).isEqualTo(1L); |
237 | 233 | }
|
238 | 234 | }
|
239 | 235 | }
|
240 | 236 | }
|
241 | 237 |
|
242 | 238 | @Test
|
243 | 239 | public void testTransactionalSelectAborted() throws SQLException {
|
244 |
| -if (!retryAbortsInternally) { |
245 |
| -expected.expect(JdbcAbortedException.class); |
246 |
| -} |
247 | 240 | try (java.sql.Connection connection = createConnection()) {
|
248 | 241 | connection.setAutoCommit(false);
|
249 | 242 | mockSpanner.abortNextStatement();
|
250 | 243 | try (ResultSet rs = connection.createStatement().executeQuery(SELECT1.getSql())) {
|
251 | 244 | while (rs.next()) {
|
252 |
| -assertThat(rs.getLong(1), is(equalTo(1L))); |
| 245 | +if (!retryAbortsInternally) { |
| 246 | +fail("missing expected exception"); |
| 247 | +} |
| 248 | +assertThat(rs.getLong(1)).isEqualTo(1L); |
253 | 249 | }
|
254 | 250 | }
|
255 |
| -assertThat(getRetryCount(connection), is(equalTo(1))); |
| 251 | +assertThat(getRetryCount(connection)).isEqualTo(1); |
| 252 | +} catch (JdbcAbortedException e) { |
| 253 | +assertThat(retryAbortsInternally).isFalse(); |
256 | 254 | }
|
257 | 255 | }
|
258 | 256 |
|
259 | 257 | @Test
|
260 | 258 | public void testTransactionalUpdateWithConcurrentModificationsAborted() throws SQLException {
|
261 |
| -if (retryAbortsInternally) { |
262 |
| -// As the transaction does a random select, the retry will always see different data than the |
263 |
| -// original attempt. |
264 |
| -expected.expect(JdbcAbortedDueToConcurrentModificationException.class); |
265 |
| -} else { |
266 |
| -expected.expect(JdbcAbortedException.class); |
267 |
| -} |
| 259 | +// As the transaction does a random select, the retry will always see different data than the |
| 260 | +// original attempt. |
268 | 261 | try (java.sql.Connection connection = createConnection()) {
|
269 | 262 | connection.setAutoCommit(false);
|
270 | 263 | // Set a random answer.
|
@@ -281,14 +274,15 @@ public void testTransactionalUpdateWithConcurrentModificationsAborted() throws S
|
281 | 274 | // This will abort and start an internal retry.
|
282 | 275 | connection.createStatement().executeUpdate(UPDATE_STATEMENT.getSql());
|
283 | 276 | fail("missing expected aborted exception");
|
| 277 | +} catch (JdbcAbortedDueToConcurrentModificationException e) { |
| 278 | +assertThat(retryAbortsInternally).isTrue(); |
| 279 | +} catch (JdbcAbortedException e) { |
| 280 | +assertThat(retryAbortsInternally).isFalse(); |
284 | 281 | }
|
285 | 282 | }
|
286 | 283 |
|
287 | 284 | @Test
|
288 | 285 | public void testTransactionalUpdateWithErrorOnOriginalAndRetry() throws SQLException {
|
289 |
| -if (!retryAbortsInternally) { |
290 |
| -expected.expect(JdbcAbortedException.class); |
291 |
| -} |
292 | 286 | final String sql = "UPDATE SOMETHING SET OTHER=1";
|
293 | 287 | mockSpanner.putStatementResult(
|
294 | 288 | StatementResult.exception(
|
@@ -298,7 +292,7 @@ public void testTransactionalUpdateWithErrorOnOriginalAndRetry() throws SQLExcep
|
298 | 292 | connection.setAutoCommit(false);
|
299 | 293 | try (ResultSet rs = connection.createStatement().executeQuery(SELECT1.getSql())) {
|
300 | 294 | while (rs.next()) {
|
301 |
| -assertThat(rs.getLong(1), is(equalTo(1L))); |
| 295 | +assertThat(rs.getLong(1)).isEqualTo(1L); |
302 | 296 | }
|
303 | 297 | }
|
304 | 298 | try {
|
@@ -309,16 +303,16 @@ public void testTransactionalUpdateWithErrorOnOriginalAndRetry() throws SQLExcep
|
309 | 303 | }
|
310 | 304 | mockSpanner.abortNextStatement();
|
311 | 305 | connection.commit();
|
| 306 | +if (!retryAbortsInternally) { |
| 307 | +fail("missing expected exception"); |
| 308 | +} |
| 309 | +} catch (JdbcAbortedException e) { |
| 310 | +assertThat(retryAbortsInternally).isFalse(); |
312 | 311 | }
|
313 | 312 | }
|
314 | 313 |
|
315 | 314 | @Test
|
316 | 315 | public void testTransactionalUpdateWithErrorOnRetryAndNotOnOriginal() throws SQLException {
|
317 |
| -if (retryAbortsInternally) { |
318 |
| -expected.expect(JdbcAbortedDueToConcurrentModificationException.class); |
319 |
| -} else { |
320 |
| -expected.expect(JdbcAbortedException.class); |
321 |
| -} |
322 | 316 | final String sql = "UPDATE SOMETHING SET OTHER=1";
|
323 | 317 | try (java.sql.Connection connection = createConnection()) {
|
324 | 318 | connection.setAutoCommit(false);
|
@@ -335,20 +329,17 @@ public void testTransactionalUpdateWithErrorOnRetryAndNotOnOriginal() throws SQL
|
335 | 329 | connection.commit();
|
336 | 330 | fail("missing expected aborted exception");
|
337 | 331 | } catch (JdbcAbortedDueToConcurrentModificationException e) {
|
338 |
| -assertThat( |
339 |
| -e.getDatabaseErrorDuringRetry().getErrorCode(), is(equalTo(ErrorCode.INVALID_ARGUMENT))); |
340 |
| -assertThat(e.getDatabaseErrorDuringRetry().getMessage(), endsWith("test")); |
341 |
| -throw e; |
| 332 | +assertThat(retryAbortsInternally).isTrue(); |
| 333 | +assertThat(e.getDatabaseErrorDuringRetry().getErrorCode()) |
| 334 | +.isEqualTo(ErrorCode.INVALID_ARGUMENT); |
| 335 | +assertThat(e.getDatabaseErrorDuringRetry().getMessage()).endsWith("test"); |
| 336 | +} catch (JdbcAbortedException e) { |
| 337 | +assertThat(retryAbortsInternally).isFalse(); |
342 | 338 | }
|
343 | 339 | }
|
344 | 340 |
|
345 | 341 | @Test
|
346 | 342 | public void testTransactionalUpdateWithErrorOnOriginalAndNotOnRetry() throws SQLException {
|
347 |
| -if (retryAbortsInternally) { |
348 |
| -expected.expect(JdbcAbortedDueToConcurrentModificationException.class); |
349 |
| -} else { |
350 |
| -expected.expect(JdbcAbortedException.class); |
351 |
| -} |
352 | 343 | final String sql = "UPDATE SOMETHING SET OTHER=1";
|
353 | 344 | mockSpanner.putStatementResult(
|
354 | 345 | StatementResult.exception(
|
@@ -358,7 +349,7 @@ public void testTransactionalUpdateWithErrorOnOriginalAndNotOnRetry() throws SQL
|
358 | 349 | connection.setAutoCommit(false);
|
359 | 350 | try (ResultSet rs = connection.createStatement().executeQuery(SELECT1.getSql())) {
|
360 | 351 | while (rs.next()) {
|
361 |
| -assertThat(rs.getLong(1), is(equalTo(1L))); |
| 352 | +assertThat(rs.getLong(1)).isEqualTo(1L); |
362 | 353 | }
|
363 | 354 | }
|
364 | 355 | try {
|
@@ -373,8 +364,10 @@ public void testTransactionalUpdateWithErrorOnOriginalAndNotOnRetry() throws SQL
|
373 | 364 | connection.commit();
|
374 | 365 | fail("missing expected aborted exception");
|
375 | 366 | } catch (JdbcAbortedDueToConcurrentModificationException e) {
|
376 |
| -assertThat(e.getDatabaseErrorDuringRetry(), is(nullValue())); |
377 |
| -throw e; |
| 367 | +assertThat(retryAbortsInternally).isTrue(); |
| 368 | +assertThat(e.getDatabaseErrorDuringRetry()).isNull(); |
| 369 | +} catch (JdbcAbortedException e) { |
| 370 | +assertThat(retryAbortsInternally).isFalse(); |
378 | 371 | }
|
379 | 372 | }
|
380 | 373 | }
|
0 commit comments