From b1e3e2ca0ea1da7e0c6b93a5548c422acaf820cc Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 29 Apr 2021 03:46:21 +0000 Subject: [PATCH 01/27] chore: release 6.4.1-SNAPSHOT (#1113) :robot: I have created a release \*beep\* \*boop\* --- ### Updating meta-information for bleeding-edge SNAPSHOT release. --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --- google-cloud-spanner-bom/pom.xml | 18 +++++++++--------- google-cloud-spanner/pom.xml | 4 ++-- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- grpc-google-cloud-spanner-v1/pom.xml | 4 ++-- pom.xml | 16 ++++++++-------- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- proto-google-cloud-spanner-v1/pom.xml | 4 ++-- samples/snapshot/pom.xml | 2 +- versions.txt | 14 +++++++------- 11 files changed, 39 insertions(+), 39 deletions(-) diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml index ac147ff00b9..38df5cc9e60 100644 --- a/google-cloud-spanner-bom/pom.xml +++ b/google-cloud-spanner-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner-bom - 6.4.0 + 6.4.1-SNAPSHOT pom com.google.cloud @@ -64,43 +64,43 @@ com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.4.0 + 6.4.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.4.0 + 6.4.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-v1 - 6.4.0 + 6.4.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.4.0 + 6.4.1-SNAPSHOT com.google.cloud google-cloud-spanner - 6.4.0 + 6.4.1-SNAPSHOT com.google.cloud google-cloud-spanner test-jar - 6.4.0 + 6.4.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.4.0 + 6.4.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.4.0 + 6.4.1-SNAPSHOT diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index 8b72aa6415c..014f79bae3e 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner - 6.4.0 + 6.4.1-SNAPSHOT jar Google Cloud Spanner https://github.com/googleapis/java-spanner @@ -11,7 +11,7 @@ com.google.cloud google-cloud-spanner-parent - 6.4.0 + 6.4.1-SNAPSHOT google-cloud-spanner diff --git a/grpc-google-cloud-spanner-admin-database-v1/pom.xml b/grpc-google-cloud-spanner-admin-database-v1/pom.xml index 44850c4bdfc..38bef9b5fb9 100644 --- a/grpc-google-cloud-spanner-admin-database-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.4.0 + 6.4.1-SNAPSHOT grpc-google-cloud-spanner-admin-database-v1 GRPC library for grpc-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.4.0 + 6.4.1-SNAPSHOT diff --git a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml index f0400e4a2de..89afdb4ce23 100644 --- a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.4.0 + 6.4.1-SNAPSHOT grpc-google-cloud-spanner-admin-instance-v1 GRPC library for grpc-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.4.0 + 6.4.1-SNAPSHOT diff --git a/grpc-google-cloud-spanner-v1/pom.xml b/grpc-google-cloud-spanner-v1/pom.xml index 6b608372b25..b043645e76c 100644 --- a/grpc-google-cloud-spanner-v1/pom.xml +++ b/grpc-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.4.0 + 6.4.1-SNAPSHOT grpc-google-cloud-spanner-v1 GRPC library for grpc-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.4.0 + 6.4.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index 69cde61a225..a9bd8bdef57 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-spanner-parent pom - 6.4.0 + 6.4.1-SNAPSHOT Google Cloud Spanner Parent https://github.com/googleapis/java-spanner @@ -71,37 +71,37 @@ com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.4.0 + 6.4.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-v1 - 6.4.0 + 6.4.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.4.0 + 6.4.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.4.0 + 6.4.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.4.0 + 6.4.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.4.0 + 6.4.1-SNAPSHOT com.google.cloud google-cloud-spanner - 6.4.0 + 6.4.1-SNAPSHOT diff --git a/proto-google-cloud-spanner-admin-database-v1/pom.xml b/proto-google-cloud-spanner-admin-database-v1/pom.xml index b5f73bb5285..f2a8f6fad2b 100644 --- a/proto-google-cloud-spanner-admin-database-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.4.0 + 6.4.1-SNAPSHOT proto-google-cloud-spanner-admin-database-v1 PROTO library for proto-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.4.0 + 6.4.1-SNAPSHOT diff --git a/proto-google-cloud-spanner-admin-instance-v1/pom.xml b/proto-google-cloud-spanner-admin-instance-v1/pom.xml index 8ead775de43..8f6a3f994fb 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.4.0 + 6.4.1-SNAPSHOT proto-google-cloud-spanner-admin-instance-v1 PROTO library for proto-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.4.0 + 6.4.1-SNAPSHOT diff --git a/proto-google-cloud-spanner-v1/pom.xml b/proto-google-cloud-spanner-v1/pom.xml index 600c4d886c3..8a0a2fc784b 100644 --- a/proto-google-cloud-spanner-v1/pom.xml +++ b/proto-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.4.0 + 6.4.1-SNAPSHOT proto-google-cloud-spanner-v1 PROTO library for proto-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.4.0 + 6.4.1-SNAPSHOT diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 6556a694bdd..c724f7148dd 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -31,7 +31,7 @@ com.google.cloud google-cloud-spanner - 6.4.0 + 6.4.1-SNAPSHOT diff --git a/versions.txt b/versions.txt index 90c5b350487..3ba665a3015 100644 --- a/versions.txt +++ b/versions.txt @@ -1,10 +1,10 @@ # Format: # module:released-version:current-version -proto-google-cloud-spanner-admin-instance-v1:6.4.0:6.4.0 -proto-google-cloud-spanner-v1:6.4.0:6.4.0 -proto-google-cloud-spanner-admin-database-v1:6.4.0:6.4.0 -grpc-google-cloud-spanner-v1:6.4.0:6.4.0 -grpc-google-cloud-spanner-admin-instance-v1:6.4.0:6.4.0 -grpc-google-cloud-spanner-admin-database-v1:6.4.0:6.4.0 -google-cloud-spanner:6.4.0:6.4.0 \ No newline at end of file +proto-google-cloud-spanner-admin-instance-v1:6.4.0:6.4.1-SNAPSHOT +proto-google-cloud-spanner-v1:6.4.0:6.4.1-SNAPSHOT +proto-google-cloud-spanner-admin-database-v1:6.4.0:6.4.1-SNAPSHOT +grpc-google-cloud-spanner-v1:6.4.0:6.4.1-SNAPSHOT +grpc-google-cloud-spanner-admin-instance-v1:6.4.0:6.4.1-SNAPSHOT +grpc-google-cloud-spanner-admin-database-v1:6.4.0:6.4.1-SNAPSHOT +google-cloud-spanner:6.4.0:6.4.1-SNAPSHOT \ No newline at end of file From fc3335c55eb504827e835b6e5a1d6fc5dea2c124 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Fri, 30 Apr 2021 00:34:38 +0200 Subject: [PATCH 02/27] chore(deps): update dependency com.google.cloud:google-cloud-spanner to v6.4.0 (#1114) --- samples/install-without-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index 45f05d571aa..6e4f935b462 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -32,7 +32,7 @@ com.google.cloud google-cloud-spanner - 6.3.3 + 6.4.0 From 700103058ff916200708da281b78037ea6b5eefa Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Thu, 29 Apr 2021 16:12:04 -0700 Subject: [PATCH 03/27] chore: regenerate README (#1115) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-04-29 22:38:06,075 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-04-29 22:38:07,445 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/f34f77b3-3273-40c0-a696-d71f2b7957c6/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) --- .github/readme/synth.metadata/synth.metadata | 2 +- README.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/readme/synth.metadata/synth.metadata b/.github/readme/synth.metadata/synth.metadata index c863054ea0e..f2a8e5e581d 100644 --- a/.github/readme/synth.metadata/synth.metadata +++ b/.github/readme/synth.metadata/synth.metadata @@ -4,7 +4,7 @@ "git": { "name": ".", "remote": "https://github.com/googleapis/java-spanner.git", - "sha": "1ecbb328428b4d85a69be6a47a354f419cc5aa56" + "sha": "fc3335c55eb504827e835b6e5a1d6fc5dea2c124" } }, { diff --git a/README.md b/README.md index 08a981b4195..f26be8b5449 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ If you are using Maven without BOM, add this to your dependencies: com.google.cloud google-cloud-spanner - 6.3.3 + 6.4.0 ``` @@ -51,12 +51,12 @@ compile 'com.google.cloud:google-cloud-spanner' ``` If you are using Gradle without BOM, add this to your dependencies ```Groovy -compile 'com.google.cloud:google-cloud-spanner:6.3.3' +compile 'com.google.cloud:google-cloud-spanner:6.4.0' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.3.3" +libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.4.0" ``` ## Authentication From 6c24845d2f5c1f0b1f5a40920d164d1ecefac8f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Mon, 3 May 2021 04:35:40 +0200 Subject: [PATCH 04/27] test: retry backup operation 20 times (#1117) The backup operations can still fail because of too many pending operations. It would retry 10 times with waiting 60 seconds between each attempt, but that does not seem to be enough. The max attempts has therefore been increased to 20 and better logging has been created by throwing a custom exception when it happens. The previous log was not visible, because the sample runners are redirecting the standard out to a string. Fixes #1019 --- .../java/com/example/spanner/EncryptionKeyIT.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/samples/snippets/src/test/java/com/example/spanner/EncryptionKeyIT.java b/samples/snippets/src/test/java/com/example/spanner/EncryptionKeyIT.java index d65141b7c02..4faa3967aca 100644 --- a/samples/snippets/src/test/java/com/example/spanner/EncryptionKeyIT.java +++ b/samples/snippets/src/test/java/com/example/spanner/EncryptionKeyIT.java @@ -22,6 +22,7 @@ import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.Spanner; import com.google.cloud.spanner.SpannerException; +import com.google.cloud.spanner.SpannerExceptionFactory; import com.google.cloud.spanner.SpannerOptions; import com.google.common.base.Preconditions; import com.google.common.util.concurrent.Uninterruptibles; @@ -138,8 +139,8 @@ public void testEncryptedDatabaseAndBackupAndRestore() throws Exception { + "/backups/" + backupId + " using encryption key " + key); } - private static class ShouldRetryBackupOperation implements Predicate { - private static final int MAX_ATTEMPTS = 10; + static class ShouldRetryBackupOperation implements Predicate { + private static final int MAX_ATTEMPTS = 20; private int attempts = 0; @Override @@ -148,9 +149,11 @@ public boolean test(SpannerException e) { && e.getMessage().contains("Please retry the operation once the pending")) { attempts++; if (attempts == MAX_ATTEMPTS) { - System.out.printf("Operation failed %d times because of other pending operations. " - + "Giving up operation.\n", attempts); - return false; + // Throw custom exception so it is easier to locate in the log why it went wrong. + throw SpannerExceptionFactory.newSpannerException(ErrorCode.DEADLINE_EXCEEDED, + String.format("Operation failed %d times because of other pending operations. " + + "Giving up operation.\n", attempts), + e); } // Wait one minute before retrying. Uninterruptibles.sleepUninterruptibly(60L, TimeUnit.SECONDS); From 641f04c4ede15b84bf6e9a0916f1ae0f8c11faca Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Mon, 3 May 2021 05:32:45 +0200 Subject: [PATCH 05/27] build(deps): update dependency org.apache.maven.plugins:maven-project-info-reports-plugin to v3.1.2 (#1119) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a9bd8bdef57..3b56b269adb 100644 --- a/pom.xml +++ b/pom.xml @@ -162,7 +162,7 @@ org.apache.maven.plugins maven-project-info-reports-plugin - 3.1.1 + 3.1.2 From 47f59655acaf0fcf5848039e6b4881b80cdceb5c Mon Sep 17 00:00:00 2001 From: Thiago Nunes Date: Mon, 3 May 2021 16:43:09 +1000 Subject: [PATCH 06/27] refactor: fixes various code analyser issues (#1118) * chore: removes final modifier from methods Removes final modifier from private and static methods. * chore: adds diamond operator to generic class call * chore: simplifies boolean expression * chore: removes redundant throws clauses * chore: marks ignored exceptions with comments * chore: anonymous types replaced with lambda calls * chore: uses comparator combinator * chore: lambda replaced with method reference * chore: makes inner class static * chore: replaces Arrays.asList with emptyList * chore: removes redundant initializers * chore: removes redundant toString calls * chore: explicit type arguments can be inferred * chore: removes redundant type casts * chore: replaces StringBuilder with String * chore: removes redundant suppressions * chore: list method replaced with value * chore: uses comparator combinator * chore: uses singletonList instead of asList * chore: removes redundant type casts / parameters * chore: addresses pr comments * chore: removes unnecessary type cast --- .../cloud/spanner/AbstractResultSet.java | 28 +- .../cloud/spanner/AsyncResultSetImpl.java | 13 +- .../google/cloud/spanner/AsyncRunnerImpl.java | 10 +- .../spanner/AsyncTransactionManagerImpl.java | 21 +- .../spanner/DatabaseAdminClientImpl.java | 90 ++-- .../cloud/spanner/DatabaseClientImpl.java | 23 +- .../spanner/InstanceAdminClientImpl.java | 36 +- .../java/com/google/cloud/spanner/KeySet.java | 10 +- .../com/google/cloud/spanner/Operation.java | 10 +- .../google/cloud/spanner/SessionClient.java | 2 +- .../com/google/cloud/spanner/SessionImpl.java | 8 +- .../com/google/cloud/spanner/SessionPool.java | 188 ++----- .../SessionPoolAsyncTransactionManager.java | 95 ++-- .../com/google/cloud/spanner/SpannerImpl.java | 2 +- .../google/cloud/spanner/SpannerOptions.java | 9 +- .../spanner/TransactionContextFutureImpl.java | 2 +- .../cloud/spanner/TransactionRunnerImpl.java | 94 ++-- .../connection/AbstractBaseUnitOfWork.java | 14 +- .../connection/AsyncStatementResultImpl.java | 3 +- .../spanner/connection/ChecksumResultSet.java | 4 +- .../ClientSideStatementValueConverters.java | 18 +- .../spanner/connection/ConnectionImpl.java | 13 +- .../spanner/connection/ConnectionOptions.java | 11 +- .../cloud/spanner/connection/DdlClient.java | 4 +- .../spanner/connection/EmulatorUtil.java | 2 +- .../connection/ReadWriteTransaction.java | 13 +- .../connection/RetriableBatchUpdate.java | 2 +- .../connection/SingleUseTransaction.java | 14 +- .../cloud/spanner/connection/SpannerPool.java | 32 +- .../connection/StatementResultImpl.java | 14 +- .../cloud/spanner/spi/v1/GapicSpannerRpc.java | 103 ++-- .../spi/v1/SpannerMetadataProvider.java | 5 +- .../cloud/spanner/spi/v1/SpannerRpc.java | 2 +- .../spanner/AbstractAsyncTransactionTest.java | 14 +- .../spanner/AsyncResultSetImplStressTest.java | 156 +++--- .../cloud/spanner/AsyncResultSetImplTest.java | 187 +++---- .../google/cloud/spanner/AsyncRunnerTest.java | 54 +- .../AsyncTransactionManagerImplTest.java | 2 +- .../spanner/AsyncTransactionManagerTest.java | 470 ++++++----------- .../com/google/cloud/spanner/BackupTest.java | 14 +- .../cloud/spanner/BatchClientImplTest.java | 6 +- .../spanner/BatchCreateSessionsTest.java | 8 +- .../spanner/DatabaseAdminClientImplTest.java | 21 +- .../spanner/DatabaseAdminClientTest.java | 26 +- .../cloud/spanner/DatabaseAdminGaxTest.java | 22 +- .../cloud/spanner/DatabaseClientImplTest.java | 177 +++---- .../google/cloud/spanner/DatabaseTest.java | 20 +- .../cloud/spanner/GrpcResultSetTest.java | 113 +--- .../cloud/spanner/InlineBeginBenchmark.java | 3 +- .../spanner/InlineBeginTransactionTest.java | 185 +++---- .../spanner/InstanceAdminClientTest.java | 8 +- .../cloud/spanner/InstanceAdminGaxTest.java | 19 +- .../google/cloud/spanner/InstanceTest.java | 4 +- .../IntegrationTestWithClosedSessionsEnv.java | 3 +- .../spanner/IsRetryableInternalErrorTest.java | 1 - .../spanner/IsSslHandshakeExceptionTest.java | 1 - .../spanner/MetricRegistryTestUtils.java | 4 +- .../spanner/MockDatabaseAdminServiceImpl.java | 11 +- .../MockDatabaseAdminServiceImplTest.java | 4 +- .../cloud/spanner/MockSpannerServiceImpl.java | 42 +- .../cloud/spanner/OperationFutureUtil.java | 16 +- .../PartitionedDmlTransactionTest.java | 2 +- .../spanner/RandomResultSetGenerator.java | 2 +- .../google/cloud/spanner/ReadAsyncTest.java | 198 +++---- .../cloud/spanner/ReadFormatTestRunner.java | 4 +- ...adWriteTransactionWithInlineBeginTest.java | 4 +- .../google/cloud/spanner/ResultSetsTest.java | 80 ++- .../RetryOnInvalidatedSessionTest.java | 401 ++++++-------- .../cloud/spanner/SessionClientTest.java | 117 ++-- .../google/cloud/spanner/SessionImplTest.java | 65 +-- .../cloud/spanner/SessionPoolBenchmark.java | 2 +- .../spanner/SessionPoolMaintainerTest.java | 52 +- .../cloud/spanner/SessionPoolStressTest.java | 122 ++--- .../google/cloud/spanner/SessionPoolTest.java | 499 ++++++++---------- .../com/google/cloud/spanner/SpanTest.java | 11 +- .../cloud/spanner/SpannerApiFuturesTest.java | 6 +- .../spanner/SpannerExceptionFactoryTest.java | 6 +- .../cloud/spanner/SpannerGaxRetryTest.java | 12 +- .../google/cloud/spanner/SpannerImplTest.java | 2 +- .../cloud/spanner/SpannerOptionsTest.java | 23 +- .../spanner/SpannerOptionsThreadTest.java | 11 +- .../cloud/spanner/SpannerRetryHelperTest.java | 1 + .../spanner/StandardBenchmarkMockServer.java | 10 +- .../spanner/TransactionContextImplTest.java | 4 +- .../TransactionManagerAbortedTest.java | 18 +- .../spanner/TransactionManagerImplTest.java | 116 ++-- .../spanner/TransactionRunnerImplTest.java | 73 +-- .../google/cloud/spanner/ValueBinderTest.java | 6 +- .../com/google/cloud/spanner/ValueTest.java | 50 +- .../cloud/spanner/connection/AbortedTest.java | 9 +- .../AbstractConnectionImplTest.java | 171 ++---- .../connection/AbstractMockServerTest.java | 14 +- .../AsyncStatementResultImplTest.java | 4 +- .../connection/AutocommitDmlModeTest.java | 13 +- .../ConnectionAsyncApiAbortedTest.java | 131 ++--- .../connection/ConnectionAsyncApiTest.java | 112 ++-- .../connection/ConnectionImplTest.java | 165 +++--- .../connection/ConnectionOptionsTest.java | 15 +- .../spanner/connection/ConnectionTest.java | 20 +- .../spanner/connection/DdlBatchTest.java | 13 +- .../spanner/connection/DdlClientTest.java | 3 +- .../DirectExecuteResultSetTest.java | 3 +- .../spanner/connection/DmlBatchTest.java | 5 +- .../spanner/connection/EmulatorUtilTest.java | 14 +- .../connection/ITAbstractSpannerTest.java | 13 +- .../connection/RandomResultSetGenerator.java | 2 +- .../connection/ReadWriteTransactionTest.java | 32 +- .../ReplaceableForwardingResultSetTest.java | 3 +- .../connection/SingleUseTransactionTest.java | 14 +- .../spanner/connection/SpannerPoolTest.java | 2 +- .../spanner/connection/SqlScriptVerifier.java | 6 +- .../connection/StatementTimeoutTest.java | 15 +- .../it/ITAsyncTransactionRetryTest.java | 290 +++++----- .../cloud/spanner/it/ITAsyncAPITest.java | 97 ++-- .../cloud/spanner/it/ITAsyncExamplesTest.java | 160 +++--- .../google/cloud/spanner/it/ITBackupTest.java | 41 +- .../cloud/spanner/it/ITBatchDmlTest.java | 8 +- .../cloud/spanner/it/ITBatchReadTest.java | 6 +- .../spanner/it/ITCommitTimestampTest.java | 7 +- .../google/cloud/spanner/it/ITDMLTest.java | 27 +- .../cloud/spanner/it/ITDatabaseAdminTest.java | 8 +- .../cloud/spanner/it/ITDatabaseTest.java | 2 +- .../spanner/it/ITDirectPathFallback.java | 18 +- .../spanner/it/ITPitrUpdateDatabaseTest.java | 2 +- .../google/cloud/spanner/it/ITQueryTest.java | 28 +- .../cloud/spanner/it/ITReadOnlyTxnTest.java | 6 +- .../spanner/it/ITSpannerOptionsTest.java | 4 +- .../it/ITTransactionManagerAsyncTest.java | 134 ++--- .../spanner/it/ITTransactionManagerTest.java | 3 +- .../cloud/spanner/it/ITTransactionTest.java | 200 ++++--- .../cloud/spanner/it/ITVPCNegativeTest.java | 4 +- .../google/cloud/spanner/it/ITWriteTest.java | 32 +- .../spanner/spi/v1/GapicSpannerRpcTest.java | 49 +- .../spi/v1/SpannerMetadataProviderTest.java | 6 +- 134 files changed, 2398 insertions(+), 3896 deletions(-) diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractResultSet.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractResultSet.java index 6dd8d485bac..09b824038ee 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractResultSet.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractResultSet.java @@ -32,7 +32,6 @@ import com.google.cloud.spanner.spi.v1.SpannerRpc; import com.google.cloud.spanner.v1.stub.SpannerStubSettings; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Function; import com.google.common.collect.AbstractIterator; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; @@ -225,7 +224,7 @@ protected com.google.protobuf.Value computeNext() { + newValue.getKindCase()); } if (kind == KindCase.STRING_VALUE) { - merged = (String) merged + newValue.getStringValue(); + merged = merged + newValue.getStringValue(); } else { concatLists( (List) merged, newValue.getListValue().getValuesList()); @@ -319,7 +318,7 @@ private void concatLists(List a, List() { - @Override - public Boolean apply(com.google.protobuf.Value input) { - return input.getKindCase() == KindCase.NULL_VALUE ? null : input.getBoolValue(); - } - }); + input -> input.getKindCase() == KindCase.NULL_VALUE ? null : input.getBoolValue()); case INT64: // For int64/float64 types, use custom containers. These avoid wrapper object // creation for non-null arrays. @@ -551,12 +545,7 @@ public Boolean apply(com.google.protobuf.Value input) { case STRING: return Lists.transform( listValue.getValuesList(), - new Function() { - @Override - public String apply(com.google.protobuf.Value input) { - return input.getKindCase() == KindCase.NULL_VALUE ? null : input.getStringValue(); - } - }); + input -> input.getKindCase() == KindCase.NULL_VALUE ? null : input.getStringValue()); case BYTES: { // Materialize list: element conversion is expensive and should happen only once. @@ -1012,12 +1001,9 @@ private static void backoffSleep(Context context, long backoffMillis) throws Spa ImmutableMap.of("Delay", AttributeValue.longAttributeValue(backoffMillis))); final CountDownLatch latch = new CountDownLatch(1); final Context.CancellationListener listener = - new Context.CancellationListener() { - @Override - public void cancelled(Context context) { - // Wakeup on cancellation / DEADLINE_EXCEEDED. - latch.countDown(); - } + ignored -> { + // Wakeup on cancellation / DEADLINE_EXCEEDED. + latch.countDown(); }; context.addListener(listener, DirectExecutor.INSTANCE); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AsyncResultSetImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AsyncResultSetImpl.java index 88800563337..35ed4648af1 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AsyncResultSetImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AsyncResultSetImpl.java @@ -16,7 +16,6 @@ package com.google.cloud.spanner; -import com.google.api.core.ApiAsyncFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.ListenableFutureToApiFuture; @@ -529,18 +528,10 @@ public ApiFuture> toListAsync( Preconditions.checkState(!closed, "This AsyncResultSet has been closed"); Preconditions.checkState( this.state == State.INITIALIZED, "This AsyncResultSet has already been used."); - final SettableApiFuture> res = SettableApiFuture.>create(); + final SettableApiFuture> res = SettableApiFuture.create(); CreateListCallback callback = new CreateListCallback<>(res, transformer); ApiFuture finished = setCallback(executor, callback); - return ApiFutures.transformAsync( - finished, - new ApiAsyncFunction>() { - @Override - public ApiFuture> apply(Void input) throws Exception { - return res; - } - }, - MoreExecutors.directExecutor()); + return ApiFutures.transformAsync(finished, ignored -> res, MoreExecutors.directExecutor()); } } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AsyncRunnerImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AsyncRunnerImpl.java index 8aa040766ea..1ea58b2bc66 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AsyncRunnerImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AsyncRunnerImpl.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkState; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.SettableApiFuture; @@ -79,14 +78,7 @@ private void setCommitResponse() { public ApiFuture getCommitTimestamp() { checkState(commitResponse != null, "runAsync() has not yet been called"); return ApiFutures.transform( - commitResponse, - new ApiFunction() { - @Override - public Timestamp apply(CommitResponse input) { - return input.getCommitTimestamp(); - } - }, - MoreExecutors.directExecutor()); + commitResponse, CommitResponse::getCommitTimestamp, MoreExecutors.directExecutor()); } public ApiFuture getCommitResponse() { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AsyncTransactionManagerImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AsyncTransactionManagerImpl.java index 1d085491192..510bd02bc0e 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AsyncTransactionManagerImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AsyncTransactionManagerImpl.java @@ -16,8 +16,6 @@ package com.google.cloud.spanner; -import com.google.api.core.ApiAsyncFunction; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutureCallback; import com.google.api.core.ApiFutures; @@ -30,7 +28,6 @@ import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; import com.google.common.util.concurrent.MoreExecutors; -import com.google.protobuf.Empty; import io.opencensus.trace.Span; import io.opencensus.trace.Tracer; import io.opencensus.trace.Tracing; @@ -73,7 +70,7 @@ public ApiFuture closeAsync() { if (txn != null) { txn.close(); } - return MoreObjects.firstNonNull(res, ApiFutures.immediateFuture(null)); + return MoreObjects.firstNonNull(res, ApiFutures.immediateFuture(null)); } @Override @@ -154,14 +151,7 @@ public void onSuccess(CommitResponse result) { }, MoreExecutors.directExecutor()); return ApiFutures.transform( - commitResponseFuture, - new ApiFunction() { - @Override - public Timestamp apply(CommitResponse input) { - return input.getCommitTimestamp(); - } - }, - MoreExecutors.directExecutor()); + commitResponseFuture, CommitResponse::getCommitTimestamp, MoreExecutors.directExecutor()); } @Override @@ -172,12 +162,7 @@ public ApiFuture rollbackAsync() { try { return ApiFutures.transformAsync( txn.rollbackAsync(), - new ApiAsyncFunction() { - @Override - public ApiFuture apply(Empty input) throws Exception { - return ApiFutures.immediateFuture(null); - } - }, + ignored -> ApiFutures.immediateFuture(null), MoreExecutors.directExecutor()); } finally { txnState = TransactionState.ROLLED_BACK; diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClientImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClientImpl.java index 30bb581e9a7..4d79ed517da 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClientImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClientImpl.java @@ -16,11 +16,9 @@ package com.google.cloud.spanner; -import com.google.api.core.ApiFunction; import com.google.api.gax.grpc.ProtoOperationTransformers; import com.google.api.gax.longrunning.OperationFuture; import com.google.api.gax.longrunning.OperationFutureImpl; -import com.google.api.gax.longrunning.OperationSnapshot; import com.google.api.gax.paging.Page; import com.google.cloud.Policy; import com.google.cloud.Policy.DefaultMarshaller; @@ -108,22 +106,15 @@ public OperationFuture restoreDatabase(Restor return new OperationFutureImpl<>( rawOperationFuture.getPollingFuture(), rawOperationFuture.getInitialFuture(), - new ApiFunction() { - @Override - public Database apply(OperationSnapshot snapshot) { - return Database.fromProto( + snapshot -> + Database.fromProto( ProtoOperationTransformers.ResponseTransformer.create( com.google.spanner.admin.database.v1.Database.class) .apply(snapshot), - DatabaseAdminClientImpl.this); - } - }, + DatabaseAdminClientImpl.this), ProtoOperationTransformers.MetadataTransformer.create(RestoreDatabaseMetadata.class), - new ApiFunction() { - @Override - public Database apply(Exception e) { - throw SpannerExceptionFactory.newSpannerException(e); - } + e -> { + throw SpannerExceptionFactory.newSpannerException(e); }); } @@ -154,30 +145,24 @@ public OperationFuture createBackup(Backup backupI return new OperationFutureImpl<>( rawOperationFuture.getPollingFuture(), rawOperationFuture.getInitialFuture(), - new ApiFunction() { - @Override - public Backup apply(OperationSnapshot snapshot) { - com.google.spanner.admin.database.v1.Backup proto = - ProtoOperationTransformers.ResponseTransformer.create( - com.google.spanner.admin.database.v1.Backup.class) - .apply(snapshot); - return Backup.fromProto( - com.google.spanner.admin.database.v1.Backup.newBuilder(proto) - .setName(proto.getName()) - .setExpireTime(proto.getExpireTime()) - .setVersionTime(proto.getVersionTime()) - .setState(proto.getState()) - .setEncryptionInfo(proto.getEncryptionInfo()) - .build(), - DatabaseAdminClientImpl.this); - } + snapshot -> { + com.google.spanner.admin.database.v1.Backup proto = + ProtoOperationTransformers.ResponseTransformer.create( + com.google.spanner.admin.database.v1.Backup.class) + .apply(snapshot); + return Backup.fromProto( + com.google.spanner.admin.database.v1.Backup.newBuilder(proto) + .setName(proto.getName()) + .setExpireTime(proto.getExpireTime()) + .setVersionTime(proto.getVersionTime()) + .setState(proto.getState()) + .setEncryptionInfo(proto.getEncryptionInfo()) + .build(), + DatabaseAdminClientImpl.this); }, ProtoOperationTransformers.MetadataTransformer.create(CreateBackupMetadata.class), - new ApiFunction() { - @Override - public Backup apply(Exception e) { - throw SpannerExceptionFactory.newSpannerException(e); - } + e -> { + throw SpannerExceptionFactory.newSpannerException(e); }); } @@ -311,22 +296,15 @@ public OperationFuture createDatabase( return new OperationFutureImpl<>( rawOperationFuture.getPollingFuture(), rawOperationFuture.getInitialFuture(), - new ApiFunction() { - @Override - public Database apply(OperationSnapshot snapshot) { - return Database.fromProto( + snapshot -> + Database.fromProto( ProtoOperationTransformers.ResponseTransformer.create( com.google.spanner.admin.database.v1.Database.class) .apply(snapshot), - DatabaseAdminClientImpl.this); - } - }, + DatabaseAdminClientImpl.this), ProtoOperationTransformers.MetadataTransformer.create(CreateDatabaseMetadata.class), - new ApiFunction() { - @Override - public Database apply(Exception e) { - throw SpannerExceptionFactory.newSpannerException(e); - } + e -> { + throw SpannerExceptionFactory.newSpannerException(e); }); } @@ -350,19 +328,13 @@ public OperationFuture updateDatabaseDdl( return new OperationFutureImpl<>( rawOperationFuture.getPollingFuture(), rawOperationFuture.getInitialFuture(), - new ApiFunction() { - @Override - public Void apply(OperationSnapshot snapshot) { - ProtoOperationTransformers.ResponseTransformer.create(Empty.class).apply(snapshot); - return null; - } + snapshot -> { + ProtoOperationTransformers.ResponseTransformer.create(Empty.class).apply(snapshot); + return null; }, ProtoOperationTransformers.MetadataTransformer.create(UpdateDatabaseDdlMetadata.class), - new ApiFunction() { - @Override - public Void apply(Exception e) { - throw SpannerExceptionFactory.newSpannerException(e); - } + e -> { + throw SpannerExceptionFactory.newSpannerException(e); }); } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseClientImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseClientImpl.java index 55002d405f7..e2121910ad8 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseClientImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseClientImpl.java @@ -64,13 +64,7 @@ public CommitResponse writeWithOptions( throws SpannerException { Span span = tracer.spanBuilder(READ_WRITE_TRANSACTION).startSpan(); try (Scope s = tracer.withSpan(span)) { - return runWithSessionRetry( - new Function() { - @Override - public CommitResponse apply(Session session) { - return session.writeWithOptions(mutations, options); - } - }); + return runWithSessionRetry(session -> session.writeWithOptions(mutations, options)); } catch (RuntimeException e) { TraceUtil.setWithFailure(span, e); throw e; @@ -91,12 +85,7 @@ public CommitResponse writeAtLeastOnceWithOptions( Span span = tracer.spanBuilder(READ_WRITE_TRANSACTION).startSpan(); try (Scope s = tracer.withSpan(span)) { return runWithSessionRetry( - new Function() { - @Override - public CommitResponse apply(Session session) { - return session.writeAtLeastOnceWithOptions(mutations, options); - } - }); + session -> session.writeAtLeastOnceWithOptions(mutations, options)); } catch (RuntimeException e) { TraceUtil.setWithFailure(span, e); throw e; @@ -221,13 +210,7 @@ public AsyncTransactionManager transactionManagerAsync(TransactionOption... opti public long executePartitionedUpdate(final Statement stmt, final UpdateOption... options) { Span span = tracer.spanBuilder(PARTITION_DML_TRANSACTION).startSpan(); try (Scope s = tracer.withSpan(span)) { - return runWithSessionRetry( - new Function() { - @Override - public Long apply(Session session) { - return session.executePartitionedUpdate(stmt, options); - } - }); + return runWithSessionRetry(session -> session.executePartitionedUpdate(stmt, options)); } catch (RuntimeException e) { TraceUtil.endSpanWithFailure(span, e); throw e; diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/InstanceAdminClientImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/InstanceAdminClientImpl.java index 409f9a31adf..4f25393b634 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/InstanceAdminClientImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/InstanceAdminClientImpl.java @@ -16,11 +16,9 @@ package com.google.cloud.spanner; -import com.google.api.core.ApiFunction; import com.google.api.gax.grpc.ProtoOperationTransformers; import com.google.api.gax.longrunning.OperationFuture; import com.google.api.gax.longrunning.OperationFutureImpl; -import com.google.api.gax.longrunning.OperationSnapshot; import com.google.api.gax.paging.Page; import com.google.api.pathtemplate.PathTemplate; import com.google.cloud.Policy; @@ -106,23 +104,16 @@ public OperationFuture createInstance(Instance return new OperationFutureImpl<>( rawOperationFuture.getPollingFuture(), rawOperationFuture.getInitialFuture(), - new ApiFunction() { - @Override - public Instance apply(OperationSnapshot snapshot) { - return Instance.fromProto( + snapshot -> + Instance.fromProto( ProtoOperationTransformers.ResponseTransformer.create( com.google.spanner.admin.instance.v1.Instance.class) .apply(snapshot), InstanceAdminClientImpl.this, - dbClient); - } - }, + dbClient), ProtoOperationTransformers.MetadataTransformer.create(CreateInstanceMetadata.class), - new ApiFunction() { - @Override - public Instance apply(Exception e) { - throw SpannerExceptionFactory.newSpannerException(e); - } + e -> { + throw SpannerExceptionFactory.newSpannerException(e); }); } @@ -175,23 +166,16 @@ public OperationFuture updateInstance( return new OperationFutureImpl<>( rawOperationFuture.getPollingFuture(), rawOperationFuture.getInitialFuture(), - new ApiFunction() { - @Override - public Instance apply(OperationSnapshot snapshot) { - return Instance.fromProto( + snapshot -> + Instance.fromProto( ProtoOperationTransformers.ResponseTransformer.create( com.google.spanner.admin.instance.v1.Instance.class) .apply(snapshot), InstanceAdminClientImpl.this, - dbClient); - } - }, + dbClient), ProtoOperationTransformers.MetadataTransformer.create(UpdateInstanceMetadata.class), - new ApiFunction() { - @Override - public Instance apply(Exception e) { - throw SpannerExceptionFactory.newSpannerException(e); - } + e -> { + throw SpannerExceptionFactory.newSpannerException(e); }); } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/KeySet.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/KeySet.java index 1f132bcaaed..76c60aac9bb 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/KeySet.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/KeySet.java @@ -47,7 +47,7 @@ private KeySet(boolean all, ImmutableList keys, ImmutableList ran * as there are columns in the primary or index key with this this key set is used. */ public static KeySet singleKey(Key key) { - return new KeySet(false, ImmutableList.of(key), ImmutableList.of()); + return new KeySet(false, ImmutableList.of(key), ImmutableList.of()); } /** @@ -55,7 +55,7 @@ public static KeySet singleKey(Key key) { * ranges. */ public static KeySet range(KeyRange range) { - return new KeySet(false, ImmutableList.of(), ImmutableList.of(range)); + return new KeySet(false, ImmutableList.of(), ImmutableList.of(range)); } /** @@ -68,7 +68,7 @@ public static KeySet prefixRange(Key prefix) { /** Creates a key set that will retrieve all rows of a table or index. */ public static KeySet all() { - return new KeySet(true, ImmutableList.of(), ImmutableList.of()); + return new KeySet(true, ImmutableList.of(), ImmutableList.of()); } /** Returns a new builder that can be used to construct a key set. */ @@ -124,8 +124,8 @@ public Builder setAll() { public KeySet build() { return new KeySet( all, - keys != null ? keys.build() : ImmutableList.of(), - ranges != null ? ranges.build() : ImmutableList.of()); + keys != null ? keys.build() : ImmutableList.of(), + ranges != null ? ranges.build() : ImmutableList.of()); } } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Operation.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Operation.java index a536a97ffd8..bd238d3ef8b 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Operation.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Operation.java @@ -100,7 +100,7 @@ private static Operation pending( static Operation create( SpannerRpc rpc, com.google.longrunning.Operation proto, Parser parser) { - return Operation.create(rpc, proto, parser, CurrentMillisClock.getDefaultClock()); + return Operation.create(rpc, proto, parser, CurrentMillisClock.getDefaultClock()); } static Operation create( @@ -109,13 +109,13 @@ static Operation create( String name = proto.getName(); if (proto.getDone()) { if (proto.getResultCase() == ResultCase.ERROR) { - return Operation.failed(rpc, name, proto.getError(), metadata, parser, clock); + return Operation.failed(rpc, name, proto.getError(), metadata, parser, clock); } else { - return Operation.successful( + return Operation.successful( rpc, name, metadata, parser.parseResult(proto.getResponse()), parser, clock); } } else { - return Operation.pending(rpc, name, metadata, parser, clock); + return Operation.pending(rpc, name, metadata, parser, clock); } } @@ -125,7 +125,7 @@ public Operation reload() throws SpannerException { return this; } com.google.longrunning.Operation proto = rpc.getOperation(name); - return Operation.create(rpc, proto, parser); + return Operation.create(rpc, proto, parser); } /** diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionClient.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionClient.java index 7afb896ba59..cc9681b44d5 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionClient.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionClient.java @@ -125,7 +125,7 @@ private BatchCreateSessionsRunnable( @Override public void run() { - List sessions = null; + List sessions; int remainingSessionsToCreate = sessionCount; Span span = SpannerImpl.tracer.spanBuilder(SpannerImpl.BATCH_CREATE_SESSIONS).startSpan(); try (Scope s = SpannerImpl.tracer.withSpan(span)) { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java index 5674133c2b6..e981f96eb33 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java @@ -59,13 +59,7 @@ class SessionImpl implements Session { private static final Tracer tracer = Tracing.getTracer(); /** Keep track of running transactions on this session per thread. */ - static final ThreadLocal hasPendingTransaction = - new ThreadLocal() { - @Override - protected Boolean initialValue() { - return false; - } - }; + static final ThreadLocal hasPendingTransaction = ThreadLocal.withInitial(() -> false); static void throwIfTransactionsPending() { if (hasPendingTransaction.get() == Boolean.TRUE) { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPool.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPool.java index a1259c331fb..47f2c338994 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPool.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPool.java @@ -39,7 +39,6 @@ import static com.google.cloud.spanner.SpannerExceptionFactory.newSpannerException; import static com.google.common.base.Preconditions.checkState; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.SettableApiFuture; @@ -69,7 +68,6 @@ import com.google.common.util.concurrent.SettableFuture; import com.google.protobuf.Empty; import io.opencensus.common.Scope; -import io.opencensus.common.ToLongFunction; import io.opencensus.metrics.DerivedLongCumulative; import io.opencensus.metrics.DerivedLongGauge; import io.opencensus.metrics.LabelValue; @@ -579,14 +577,11 @@ private AsyncSessionPoolResultSet(SessionNotFoundHandler handler, AsyncResultSet public ApiFuture setCallback(Executor executor, final ReadyCallback callback) { return super.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - return callback.cursorReady(resultSet); - } catch (SessionNotFoundException e) { - throw handler.handleSessionNotFound(e); - } + resultSet -> { + try { + return callback.cursorReady(resultSet); + } catch (SessionNotFoundException e) { + throw handler.handleSessionNotFound(e); } }); } @@ -668,11 +663,8 @@ public ApiFuture readRowAsync(String table, Key key, Iterable co return ApiFutures.catching( AbstractReadContext.consumeSingleRowAsync(rs), SessionNotFoundException.class, - new ApiFunction() { - @Override - public Struct apply(SessionNotFoundException input) { - throw handler.handleSessionNotFound(input); - } + input -> { + throw handler.handleSessionNotFound(input); }, MoreExecutors.directExecutor()); } @@ -699,11 +691,8 @@ public ApiFuture readRowUsingIndexAsync( return ApiFutures.catching( AbstractReadContext.consumeSingleRowAsync(rs), SessionNotFoundException.class, - new ApiFunction() { - @Override - public Struct apply(SessionNotFoundException input) { - throw handler.handleSessionNotFound(input); - } + input -> { + throw handler.handleSessionNotFound(input); }, MoreExecutors.directExecutor()); } @@ -728,11 +717,8 @@ public ApiFuture executeUpdateAsync(Statement statement, UpdateOption... o return ApiFutures.catching( delegate.executeUpdateAsync(statement, options), SessionNotFoundException.class, - new ApiFunction() { - @Override - public Long apply(SessionNotFoundException input) { - throw handler.handleSessionNotFound(input); - } + input -> { + throw handler.handleSessionNotFound(input); }, MoreExecutors.directExecutor()); } @@ -752,11 +738,8 @@ public ApiFuture batchUpdateAsync( return ApiFutures.catching( delegate.batchUpdateAsync(statements, options), SessionNotFoundException.class, - new ApiFunction() { - @Override - public long[] apply(SessionNotFoundException input) { - throw handler.handleSessionNotFound(input); - } + input -> { + throw handler.handleSessionNotFound(input); }, MoreExecutors.directExecutor()); } @@ -1047,14 +1030,7 @@ private void setCommitResponse(AsyncRunner delegate) { public ApiFuture getCommitTimestamp() { checkState(commitResponse != null, "runAsync() has not yet been called"); return ApiFutures.transform( - commitResponse, - new ApiFunction() { - @Override - public Timestamp apply(CommitResponse input) { - return input.getCommitTimestamp(); - } - }, - MoreExecutors.directExecutor()); + commitResponse, CommitResponse::getCommitTimestamp, MoreExecutors.directExecutor()); } @Override @@ -1141,12 +1117,9 @@ public CommitResponse writeAtLeastOnceWithOptions( public ReadContext singleUse() { try { return new AutoClosingReadContext<>( - new Function() { - @Override - public ReadContext apply(PooledSessionFuture session) { - PooledSession ps = session.get(); - return ps.delegate.singleUse(); - } + session -> { + PooledSession ps = session.get(); + return ps.delegate.singleUse(); }, SessionPool.this, this, @@ -1161,12 +1134,9 @@ public ReadContext apply(PooledSessionFuture session) { public ReadContext singleUse(final TimestampBound bound) { try { return new AutoClosingReadContext<>( - new Function() { - @Override - public ReadContext apply(PooledSessionFuture session) { - PooledSession ps = session.get(); - return ps.delegate.singleUse(bound); - } + session -> { + PooledSession ps = session.get(); + return ps.delegate.singleUse(bound); }, SessionPool.this, this, @@ -1180,12 +1150,9 @@ public ReadContext apply(PooledSessionFuture session) { @Override public ReadOnlyTransaction singleUseReadOnlyTransaction() { return internalReadOnlyTransaction( - new Function() { - @Override - public ReadOnlyTransaction apply(PooledSessionFuture session) { - PooledSession ps = session.get(); - return ps.delegate.singleUseReadOnlyTransaction(); - } + session -> { + PooledSession ps = session.get(); + return ps.delegate.singleUseReadOnlyTransaction(); }, true); } @@ -1193,12 +1160,9 @@ public ReadOnlyTransaction apply(PooledSessionFuture session) { @Override public ReadOnlyTransaction singleUseReadOnlyTransaction(final TimestampBound bound) { return internalReadOnlyTransaction( - new Function() { - @Override - public ReadOnlyTransaction apply(PooledSessionFuture session) { - PooledSession ps = session.get(); - return ps.delegate.singleUseReadOnlyTransaction(bound); - } + session -> { + PooledSession ps = session.get(); + return ps.delegate.singleUseReadOnlyTransaction(bound); }, true); } @@ -1206,12 +1170,9 @@ public ReadOnlyTransaction apply(PooledSessionFuture session) { @Override public ReadOnlyTransaction readOnlyTransaction() { return internalReadOnlyTransaction( - new Function() { - @Override - public ReadOnlyTransaction apply(PooledSessionFuture session) { - PooledSession ps = session.get(); - return ps.delegate.readOnlyTransaction(); - } + session -> { + PooledSession ps = session.get(); + return ps.delegate.readOnlyTransaction(); }, false); } @@ -1219,12 +1180,9 @@ public ReadOnlyTransaction apply(PooledSessionFuture session) { @Override public ReadOnlyTransaction readOnlyTransaction(final TimestampBound bound) { return internalReadOnlyTransaction( - new Function() { - @Override - public ReadOnlyTransaction apply(PooledSessionFuture session) { - PooledSession ps = session.get(); - return ps.delegate.readOnlyTransaction(bound); - } + session -> { + PooledSession ps = session.get(); + return ps.delegate.readOnlyTransaction(bound); }, false); } @@ -2409,62 +2367,26 @@ private void initMetricsCollection(MetricRegistry metricRegistry, List() { - @Override - public long applyAsLong(SessionPool sessionPool) { - return sessionPool.maxSessionsInUse; - } - }); + labelValues, this, sessionPool -> sessionPool.maxSessionsInUse); // The value of a maxSessions is observed from a callback function. This function is invoked // whenever metrics are collected. maxAllowedSessionsMetric.removeTimeSeries(labelValues); maxAllowedSessionsMetric.createTimeSeries( - labelValues, - options, - new ToLongFunction() { - @Override - public long applyAsLong(SessionPoolOptions options) { - return options.getMaxSessions(); - } - }); + labelValues, options, SessionPoolOptions::getMaxSessions); // The value of a numWaiterTimeouts is observed from a callback function. This function is // invoked whenever metrics are collected. sessionsTimeouts.removeTimeSeries(labelValues); - sessionsTimeouts.createTimeSeries( - labelValues, - this, - new ToLongFunction() { - @Override - public long applyAsLong(SessionPool sessionPool) { - return sessionPool.getNumWaiterTimeouts(); - } - }); + sessionsTimeouts.createTimeSeries(labelValues, this, SessionPool::getNumWaiterTimeouts); numAcquiredSessionsMetric.removeTimeSeries(labelValues); numAcquiredSessionsMetric.createTimeSeries( - labelValues, - this, - new ToLongFunction() { - @Override - public long applyAsLong(SessionPool sessionPool) { - return sessionPool.numSessionsAcquired; - } - }); + labelValues, this, sessionPool -> sessionPool.numSessionsAcquired); numReleasedSessionsMetric.removeTimeSeries(labelValues); numReleasedSessionsMetric.createTimeSeries( - labelValues, - this, - new ToLongFunction() { - @Override - public long applyAsLong(SessionPool sessionPool) { - return sessionPool.numSessionsReleased; - } - }); + labelValues, this, sessionPool -> sessionPool.numSessionsReleased); List labelValuesWithBeingPreparedType = new ArrayList<>(labelValues); labelValuesWithBeingPreparedType.add(NUM_SESSIONS_BEING_PREPARED); @@ -2472,39 +2394,20 @@ public long applyAsLong(SessionPool sessionPool) { numSessionsInPoolMetric.createTimeSeries( labelValuesWithBeingPreparedType, this, - new ToLongFunction() { - @Override - public long applyAsLong(SessionPool sessionPool) { - // TODO: Remove metric. - return 0L; - } - }); + // TODO: Remove metric. + ignored -> 0L); List labelValuesWithInUseType = new ArrayList<>(labelValues); labelValuesWithInUseType.add(NUM_IN_USE_SESSIONS); numSessionsInPoolMetric.removeTimeSeries(labelValuesWithInUseType); numSessionsInPoolMetric.createTimeSeries( - labelValuesWithInUseType, - this, - new ToLongFunction() { - @Override - public long applyAsLong(SessionPool sessionPool) { - return sessionPool.numSessionsInUse; - } - }); + labelValuesWithInUseType, this, sessionPool -> sessionPool.numSessionsInUse); List labelValuesWithReadType = new ArrayList<>(labelValues); labelValuesWithReadType.add(NUM_READ_SESSIONS); numSessionsInPoolMetric.removeTimeSeries(labelValuesWithReadType); numSessionsInPoolMetric.createTimeSeries( - labelValuesWithReadType, - this, - new ToLongFunction() { - @Override - public long applyAsLong(SessionPool sessionPool) { - return sessionPool.sessions.size(); - } - }); + labelValuesWithReadType, this, sessionPool -> sessionPool.sessions.size()); List labelValuesWithWriteType = new ArrayList<>(labelValues); labelValuesWithWriteType.add(NUM_WRITE_SESSIONS); @@ -2512,12 +2415,7 @@ public long applyAsLong(SessionPool sessionPool) { numSessionsInPoolMetric.createTimeSeries( labelValuesWithWriteType, this, - new ToLongFunction() { - @Override - public long applyAsLong(SessionPool sessionPool) { - // TODO: Remove metric. - return 0L; - } - }); + // TODO: Remove metric. + ignored -> 0L); } } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPoolAsyncTransactionManager.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPoolAsyncTransactionManager.java index 6b7b4b3afc5..b6442fd2182 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPoolAsyncTransactionManager.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPoolAsyncTransactionManager.java @@ -16,8 +16,6 @@ package com.google.cloud.spanner; -import com.google.api.core.ApiAsyncFunction; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutureCallback; import com.google.api.core.ApiFutures; @@ -185,34 +183,31 @@ public ApiFuture commitAsync() { } return ApiFutures.transformAsync( delegate, - new ApiAsyncFunction() { - @Override - public ApiFuture apply(AsyncTransactionManagerImpl input) throws Exception { - final SettableApiFuture res = SettableApiFuture.create(); - ApiFutures.addCallback( - input.commitAsync(), - new ApiFutureCallback() { - @Override - public void onFailure(Throwable t) { - synchronized (lock) { - if (t instanceof AbortedException) { - txnState = TransactionState.ABORTED; - abortedException = (AbortedException) t; - } else { - txnState = TransactionState.COMMIT_FAILED; - } + input -> { + final SettableApiFuture res = SettableApiFuture.create(); + ApiFutures.addCallback( + input.commitAsync(), + new ApiFutureCallback() { + @Override + public void onFailure(Throwable t) { + synchronized (lock) { + if (t instanceof AbortedException) { + txnState = TransactionState.ABORTED; + abortedException = (AbortedException) t; + } else { + txnState = TransactionState.COMMIT_FAILED; } - res.setException(t); } + res.setException(t); + } - @Override - public void onSuccess(Timestamp result) { - res.set(result); - } - }, - MoreExecutors.directExecutor()); - return res; - } + @Override + public void onSuccess(Timestamp result) { + res.set(result); + } + }, + MoreExecutors.directExecutor()); + return res; }, MoreExecutors.directExecutor()); } @@ -227,13 +222,10 @@ public ApiFuture rollbackAsync() { } return ApiFutures.transformAsync( delegate, - new ApiAsyncFunction() { - @Override - public ApiFuture apply(AsyncTransactionManagerImpl input) throws Exception { - ApiFuture res = input.rollbackAsync(); - res.addListener(() -> session.close(), MoreExecutors.directExecutor()); - return res; - } + input -> { + ApiFuture res = input.rollbackAsync(); + res.addListener(() -> session.close(), MoreExecutors.directExecutor()); + return res; }, MoreExecutors.directExecutor()); } @@ -251,26 +243,17 @@ public TransactionContextFuture resetForRetryAsync() { ApiFutures.transform( ApiFutures.transformAsync( delegate, - new ApiAsyncFunction() { - @Override - public ApiFuture apply(AsyncTransactionManagerImpl input) - throws Exception { - if (restartedAfterSessionNotFound) { - restartedAfterSessionNotFound = false; - return input.beginAsync(); - } - return input.resetForRetryAsync(); + input -> { + if (restartedAfterSessionNotFound) { + restartedAfterSessionNotFound = false; + return input.beginAsync(); } + return input.resetForRetryAsync(); }, MoreExecutors.directExecutor()), - new ApiFunction() { - - @Override - public TransactionContext apply(TransactionContext input) { - return new SessionPool.SessionPoolTransactionContext( - SessionPoolAsyncTransactionManager.this, input); - } - }, + input -> + new SessionPool.SessionPoolTransactionContext( + SessionPoolAsyncTransactionManager.this, input), MoreExecutors.directExecutor())); } @@ -288,14 +271,6 @@ public ApiFuture getCommitResponse() { "commit can only be invoked if the transaction was successfully committed"); } return ApiFutures.transformAsync( - delegate, - new ApiAsyncFunction() { - @Override - public ApiFuture apply(AsyncTransactionManagerImpl input) - throws Exception { - return input.getCommitResponse(); - } - }, - MoreExecutors.directExecutor()); + delegate, AsyncTransactionManagerImpl::getCommitResponse, MoreExecutors.directExecutor()); } } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerImpl.java index f16382e8355..b8255f1d65e 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerImpl.java @@ -244,7 +244,7 @@ public void close() { } void close(long timeout, TimeUnit unit) { - List> closureFutures = null; + List> closureFutures; synchronized (this) { checkClosed(); closedException = new ClosedException(); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java index 60f33273e31..62cfa336e9e 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java @@ -1004,7 +1004,6 @@ public Builder setEmulatorHost(String emulatorHost) { return this; } - @SuppressWarnings("rawtypes") @Override public SpannerOptions build() { // Set the host of emulator has been set. @@ -1015,13 +1014,7 @@ public SpannerOptions build() { this.setHost(emulatorHost); // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid // needing certificates. - this.setChannelConfigurator( - new ApiFunction() { - @Override - public ManagedChannelBuilder apply(ManagedChannelBuilder builder) { - return builder.usePlaintext(); - } - }); + this.setChannelConfigurator(ManagedChannelBuilder::usePlaintext); // As we are using plain text, we should never send any credentials. this.setCredentials(NoCredentials.getInstance()); } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionContextFutureImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionContextFutureImpl.java index 3bfcdd4a334..266b75eb139 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionContextFutureImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionContextFutureImpl.java @@ -91,7 +91,7 @@ class AsyncTransactionStatementImpl extends ForwardingApiFuture ApiFuture input, final AsyncTransactionFunction function, Executor executor) { - this(SettableApiFuture.create(), txnFuture, input, function, executor); + this(SettableApiFuture.create(), txnFuture, input, function, executor); } AsyncTransactionStatementImpl( diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionRunnerImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionRunnerImpl.java index 9d21c72410e..2484b9d3c6d 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionRunnerImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionRunnerImpl.java @@ -21,7 +21,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.SettableApiFuture; @@ -44,7 +43,6 @@ import com.google.spanner.v1.ExecuteSqlRequest; import com.google.spanner.v1.ExecuteSqlRequest.QueryMode; import com.google.spanner.v1.RequestOptions; -import com.google.spanner.v1.ResultSet; import com.google.spanner.v1.RollbackRequest; import com.google.spanner.v1.Transaction; import com.google.spanner.v1.TransactionOptions; @@ -575,7 +573,7 @@ public SpannerException onError(SpannerException e, boolean withBeginTransaction if (exceptionToThrow.getErrorCode() == ErrorCode.ABORTED) { long delay = -1L; if (exceptionToThrow instanceof AbortedException) { - delay = ((AbortedException) exceptionToThrow).getRetryDelayInMillis(); + delay = exceptionToThrow.getRetryDelayInMillis(); } if (delay == -1L) { txnLogger.log( @@ -671,35 +669,29 @@ public ApiFuture executeUpdateAsync(Statement statement, UpdateOption... o ApiFuture updateCount = ApiFutures.transform( resultSet, - new ApiFunction() { - @Override - public Long apply(ResultSet input) { - if (!input.hasStats()) { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.INVALID_ARGUMENT, - "DML response missing stats possibly due to non-DML statement as input"); - } - if (builder.getTransaction().hasBegin() - && !(input.getMetadata().hasTransaction() - && input.getMetadata().getTransaction().getId() != ByteString.EMPTY)) { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.FAILED_PRECONDITION, NO_TRANSACTION_RETURNED_MSG); - } - // For standard DML, using the exact row count. - return input.getStats().getRowCountExact(); + input -> { + if (!input.hasStats()) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.INVALID_ARGUMENT, + "DML response missing stats possibly due to non-DML statement as input"); } + if (builder.getTransaction().hasBegin() + && !(input.getMetadata().hasTransaction() + && input.getMetadata().getTransaction().getId() != ByteString.EMPTY)) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.FAILED_PRECONDITION, NO_TRANSACTION_RETURNED_MSG); + } + // For standard DML, using the exact row count. + return input.getStats().getRowCountExact(); }, MoreExecutors.directExecutor()); updateCount = ApiFutures.catching( updateCount, Throwable.class, - new ApiFunction() { - @Override - public Long apply(Throwable input) { - SpannerException e = SpannerExceptionFactory.asSpannerException(input); - throw onError(e, builder.getTransaction().hasBegin()); - } + input -> { + SpannerException e = SpannerExceptionFactory.asSpannerException(input); + throw onError(e, builder.getTransaction().hasBegin()); }, MoreExecutors.directExecutor()); updateCount.addListener( @@ -787,42 +779,36 @@ public ApiFuture batchUpdateAsync( ApiFuture updateCounts = ApiFutures.transform( response, - new ApiFunction() { - @Override - public long[] apply(ExecuteBatchDmlResponse batchDmlResponse) { - long[] results = new long[batchDmlResponse.getResultSetsCount()]; - for (int i = 0; i < batchDmlResponse.getResultSetsCount(); ++i) { - results[i] = batchDmlResponse.getResultSets(i).getStats().getRowCountExact(); - if (batchDmlResponse.getResultSets(i).getMetadata().hasTransaction()) { - onTransactionMetadata( - batchDmlResponse.getResultSets(i).getMetadata().getTransaction(), - builder.getTransaction().hasBegin()); - } - } - // If one of the DML statements was aborted, we should throw an aborted exception. - // In all other cases, we should throw a BatchUpdateException. - if (batchDmlResponse.getStatus().getCode() == Code.ABORTED_VALUE) { - throw createAbortedExceptionForBatchDml(batchDmlResponse); - } else if (batchDmlResponse.getStatus().getCode() != 0) { - throw newSpannerBatchUpdateException( - ErrorCode.fromRpcStatus(batchDmlResponse.getStatus()), - batchDmlResponse.getStatus().getMessage(), - results); + batchDmlResponse -> { + long[] results = new long[batchDmlResponse.getResultSetsCount()]; + for (int i = 0; i < batchDmlResponse.getResultSetsCount(); ++i) { + results[i] = batchDmlResponse.getResultSets(i).getStats().getRowCountExact(); + if (batchDmlResponse.getResultSets(i).getMetadata().hasTransaction()) { + onTransactionMetadata( + batchDmlResponse.getResultSets(i).getMetadata().getTransaction(), + builder.getTransaction().hasBegin()); } - return results; } + // If one of the DML statements was aborted, we should throw an aborted exception. + // In all other cases, we should throw a BatchUpdateException. + if (batchDmlResponse.getStatus().getCode() == Code.ABORTED_VALUE) { + throw createAbortedExceptionForBatchDml(batchDmlResponse); + } else if (batchDmlResponse.getStatus().getCode() != 0) { + throw newSpannerBatchUpdateException( + ErrorCode.fromRpcStatus(batchDmlResponse.getStatus()), + batchDmlResponse.getStatus().getMessage(), + results); + } + return results; }, MoreExecutors.directExecutor()); updateCounts = ApiFutures.catching( updateCounts, Throwable.class, - new ApiFunction() { - @Override - public long[] apply(Throwable input) { - SpannerException e = SpannerExceptionFactory.asSpannerException(input); - throw onError(e, builder.getTransaction().hasBegin()); - } + input -> { + SpannerException e = SpannerExceptionFactory.asSpannerException(input); + throw onError(e, builder.getTransaction().hasBegin()); }, MoreExecutors.directExecutor()); updateCounts.addListener(this::decreaseAsyncOperations, MoreExecutors.directExecutor()); @@ -932,7 +918,7 @@ private T runInternal(final TransactionCallable txCallable) { "Attempt", AttributeValue.longAttributeValue(attempt.longValue()))); shouldRollback = false; if (e instanceof AbortedException) { - throw (AbortedException) e; + throw e; } throw SpannerExceptionFactory.newSpannerException( ErrorCode.ABORTED, e.getMessage(), e); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractBaseUnitOfWork.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractBaseUnitOfWork.java index 3fb3fae8e5d..0e9ca972092 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractBaseUnitOfWork.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractBaseUnitOfWork.java @@ -16,7 +16,6 @@ package com.google.cloud.spanner.connection; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.gax.grpc.GrpcCallContext; @@ -140,8 +139,8 @@ ApiFuture executeStatementAsync( callable, InterceptorsUsage.INVOKE_INTERCEPTORS, applyStatementTimeoutToMethod == null - ? Collections.>emptySet() - : ImmutableList.>of(applyStatementTimeoutToMethod)); + ? Collections.emptySet() + : ImmutableList.of(applyStatementTimeoutToMethod)); } ApiFuture executeStatementAsync( @@ -228,12 +227,9 @@ public ApiCallContext configure( ApiFutures.catching( f, Throwable.class, - new ApiFunction() { - @Override - public T apply(Throwable input) { - input.addSuppressed(caller); - throw SpannerExceptionFactory.asSpannerException(input); - } + input -> { + input.addSuppressed(caller); + throw SpannerExceptionFactory.asSpannerException(input); }, MoreExecutors.directExecutor()); synchronized (this) { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AsyncStatementResultImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AsyncStatementResultImpl.java index 7d0b0fc3b5e..930a611327c 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AsyncStatementResultImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AsyncStatementResultImpl.java @@ -46,8 +46,7 @@ static AsyncStatementResult of( clientSideStatementResult.getClientSideStatementType()); } else { return new AsyncStatementResultImpl( - clientSideStatementResult.getClientSideStatementType(), - ApiFutures.immediateFuture(null)); + clientSideStatementResult.getClientSideStatementType(), ApiFutures.immediateFuture(null)); } } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java index f2d1ba548e4..01431f7a61a 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java @@ -93,7 +93,7 @@ class ChecksumResultSet extends ReplaceableForwardingResultSet implements Retria /** Simple {@link Callable} for calling {@link ResultSet#next()} */ private final class NextCallable implements Callable { @Override - public Boolean call() throws Exception { + public Boolean call() { transaction .getStatementExecutor() .invokeInterceptors( @@ -342,7 +342,7 @@ private void funnelValue(Code type, T value, PrimitiveSink into) { into.putDouble((Double) value); break; case NUMERIC: - String stringRepresentation = ((BigDecimal) value).toString(); + String stringRepresentation = value.toString(); into.putInt(stringRepresentation.length()); into.putUnencodedChars(stringRepresentation); break; diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ClientSideStatementValueConverters.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ClientSideStatementValueConverters.java index 8dd0a10a4dc..fba857ead42 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ClientSideStatementValueConverters.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ClientSideStatementValueConverters.java @@ -38,14 +38,7 @@ private static final class CaseInsensitiveEnumMap> { /** Create an map using the name of the enum elements as keys. */ private CaseInsensitiveEnumMap(Class elementType) { - this( - elementType, - new Function() { - @Override - public String apply(E input) { - return input.name(); - } - }); + this(elementType, Enum::name); } /** Create a map using the specific function to get the key per enum value. */ @@ -231,14 +224,7 @@ public String convert(String value) { static class TransactionModeConverter implements ClientSideStatementValueConverter { private final CaseInsensitiveEnumMap values = - new CaseInsensitiveEnumMap<>( - TransactionMode.class, - new Function() { - @Override - public String apply(TransactionMode input) { - return input.getStatementString(); - } - }); + new CaseInsensitiveEnumMap<>(TransactionMode.class, TransactionMode::getStatementString); public TransactionModeConverter(String allowedValues) {} diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java index 6f956640c8d..345c881d294 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java @@ -18,7 +18,6 @@ import static com.google.cloud.spanner.SpannerApiFutures.get; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.cloud.Timestamp; @@ -238,8 +237,7 @@ static UnitOfWorkType of(TransactionMode transactionMode) { Preconditions.checkNotNull(spannerPool); Preconditions.checkNotNull(ddlClient); Preconditions.checkNotNull(dbClient); - this.statementExecutor = - new StatementExecutor(Collections.emptyList()); + this.statementExecutor = new StatementExecutor(Collections.emptyList()); this.spannerPool = spannerPool; this.options = options; this.spanner = spannerPool.getSpanner(options, this); @@ -287,14 +285,7 @@ public ApiFuture closeAsync() { leakedException = null; spannerPool.removeConnection(options, this); return ApiFutures.transform( - ApiFutures.allAsList(futures), - new ApiFunction, Void>() { - @Override - public Void apply(List input) { - return null; - } - }, - MoreExecutors.directExecutor()); + ApiFutures.allAsList(futures), ignored -> null, MoreExecutors.directExecutor()); } return ApiFutures.immediateFuture(null); } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java index 8e04494f6b9..9c1e4073908 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java @@ -246,7 +246,7 @@ public String[] getValidValues() { private static final Set INTERNAL_PROPERTIES = Collections.unmodifiableSet( new HashSet<>( - Arrays.asList( + Collections.singletonList( ConnectionProperty.createStringProperty(USER_AGENT_PROPERTY_NAME, "")))); private static final Set INTERNAL_VALID_PROPERTIES = Sets.union(VALID_PROPERTIES, INTERNAL_PROPERTIES); @@ -671,12 +671,12 @@ static String parseOptimizerVersion(String uri) { @VisibleForTesting static boolean parseReturnCommitStats(String uri) { String value = parseUriProperty(uri, "returnCommitStats"); - return value != null ? Boolean.parseBoolean(value) : false; + return Boolean.parseBoolean(value); } static boolean parseAutoConfigEmulator(String uri) { String value = parseUriProperty(uri, "autoConfigEmulator"); - return value != null ? Boolean.parseBoolean(value) : false; + return Boolean.parseBoolean(value); } @VisibleForTesting @@ -710,14 +710,13 @@ static String checkValidProperties(String uri) { } } if (lenient) { - return String.format( - "Invalid properties found in connection URI: %s", invalidProperties.toString()); + return String.format("Invalid properties found in connection URI: %s", invalidProperties); } else { Preconditions.checkArgument( invalidProperties.isEmpty(), String.format( "Invalid properties found in connection URI. Add lenient=true to the connection string to ignore unknown properties. Invalid properties: %s", - invalidProperties.toString())); + invalidProperties)); return null; } } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlClient.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlClient.java index 2a901950334..f3c9cdba037 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlClient.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlClient.java @@ -21,7 +21,7 @@ import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; -import java.util.Arrays; +import java.util.Collections; import java.util.List; /** @@ -81,7 +81,7 @@ private DdlClient(Builder builder) { /** Execute a single DDL statement. */ OperationFuture executeDdl(String ddl) { - return executeDdl(Arrays.asList(ddl)); + return executeDdl(Collections.singletonList(ddl)); } /** Execute a list of DDL statements as one operation. */ diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/EmulatorUtil.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/EmulatorUtil.java index 9ffa36c0a54..ee291642031 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/EmulatorUtil.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/EmulatorUtil.java @@ -71,7 +71,7 @@ static void maybeCreateInstanceAndDatabase(Spanner spanner, DatabaseId databaseI .createDatabase( databaseId.getInstanceId().getInstance(), databaseId.getDatabase(), - ImmutableList.of()) + ImmutableList.of()) .get(); } catch (ExecutionException executionException) { SpannerException spannerException = (SpannerException) executionException.getCause(); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java index feb8fa29943..6bf3b120a05 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java @@ -45,7 +45,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.util.concurrent.MoreExecutors; import com.google.spanner.v1.SpannerGrpc; -import io.grpc.MethodDescriptor; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -342,7 +341,7 @@ public ApiFuture executeQueryAsync( }, // ignore interceptors here as they are invoked in the Callable. InterceptorsUsage.IGNORE_INTERCEPTORS, - ImmutableList.>of(SpannerGrpc.getExecuteStreamingSqlMethod())); + ImmutableList.of(SpannerGrpc.getExecuteStreamingSqlMethod())); } else { res = super.executeQueryAsync(statement, analyzeMode, options); } @@ -397,7 +396,7 @@ public ApiFuture executeUpdateAsync(final ParsedStatement update) { }, // ignore interceptors here as they are invoked in the Callable. InterceptorsUsage.IGNORE_INTERCEPTORS, - ImmutableList.>of(SpannerGrpc.getExecuteSqlMethod())); + ImmutableList.of(SpannerGrpc.getExecuteSqlMethod())); } else { res = executeStatementAsync( @@ -480,7 +479,7 @@ public ApiFuture executeBatchUpdateAsync(Iterable updat }, // ignore interceptors here as they are invoked in the Callable. InterceptorsUsage.IGNORE_INTERCEPTORS, - ImmutableList.>of(SpannerGrpc.getExecuteBatchDmlMethod())); + ImmutableList.of(SpannerGrpc.getExecuteBatchDmlMethod())); } else { res = executeStatementAsync( @@ -535,7 +534,7 @@ public ApiFuture writeAsync(Iterable mutations) { private final Callable commitCallable = new Callable() { @Override - public Void call() throws Exception { + public Void call() { checkAborted(); get(txContextFuture).buffer(mutations); txManager.commit(); @@ -579,7 +578,7 @@ public ApiFuture commitAsync() { } }, InterceptorsUsage.IGNORE_INTERCEPTORS, - ImmutableList.>of(SpannerGrpc.getCommitMethod())); + ImmutableList.of(SpannerGrpc.getCommitMethod())); } else { res = executeStatementAsync( @@ -837,7 +836,7 @@ private void invokeTransactionRetryListenersOnFinish(RetryResult result) { private final Callable rollbackCallable = new Callable() { @Override - public Void call() throws Exception { + public Void call() { try { if (state != UnitOfWorkState.ABORTED) { // Make sure the transaction has actually started before we try to rollback. diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/RetriableBatchUpdate.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/RetriableBatchUpdate.java index 6fa07d748f7..74925a2e3f7 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/RetriableBatchUpdate.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/RetriableBatchUpdate.java @@ -44,7 +44,7 @@ final class RetriableBatchUpdate implements RetriableStatement { @Override public void retry(AbortedException aborted) throws AbortedException { - long[] newCount = null; + long[] newCount; try { transaction .getStatementExecutor() diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SingleUseTransaction.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SingleUseTransaction.java index 61f9bedb28e..5fdaf877d83 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SingleUseTransaction.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SingleUseTransaction.java @@ -37,14 +37,12 @@ import com.google.cloud.spanner.TransactionRunner; import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; import com.google.cloud.spanner.connection.StatementParser.StatementType; -import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.spanner.admin.database.v1.DatabaseAdminGrpc; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; import com.google.spanner.v1.SpannerGrpc; -import io.grpc.MethodDescriptor; import java.util.concurrent.Callable; /** @@ -356,8 +354,7 @@ private ApiFuture executeTransactionalUpdateAsync(final ParsedStatement up return executeStatementAsync( update, callable, - ImmutableList.>of( - SpannerGrpc.getExecuteSqlMethod(), SpannerGrpc.getCommitMethod())); + ImmutableList.of(SpannerGrpc.getExecuteSqlMethod(), SpannerGrpc.getCommitMethod())); } private ApiFuture executePartitionedUpdateAsync(final ParsedStatement update) { @@ -385,14 +382,7 @@ private ApiFuture executeTransactionalBatchUpdateAsync( try { long[] res = transaction.batchUpdate( - Iterables.transform( - updates, - new Function() { - @Override - public Statement apply(ParsedStatement input) { - return input.getStatement(); - } - })); + Iterables.transform(updates, ParsedStatement::getStatement)); state = UnitOfWorkState.COMMITTED; return res; } catch (Throwable t) { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java index 976f69e5934..3d433adf87d 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java @@ -16,7 +16,6 @@ package com.google.cloud.spanner.connection; -import com.google.api.core.ApiFunction; import com.google.cloud.NoCredentials; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.SessionPoolOptions; @@ -41,7 +40,6 @@ import java.util.Objects; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; @@ -64,12 +62,9 @@ public class SpannerPool { private static final Logger logger = Logger.getLogger(SpannerPool.class.getName()); private static final Function DEFAULT_CLOSE_FUNCTION = - new Function() { - @Override - public Void apply(Spanner spanner) { - spanner.close(); - return null; - } + spanner -> { + spanner.close(); + return null; }; /** @@ -305,13 +300,10 @@ private void initialize() { if (this.closeSpannerAfterMillisecondsUnused > 0) { this.closerService = Executors.newSingleThreadScheduledExecutor( - new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread thread = new Thread(r, "close-unused-spanners-worker"); - thread.setDaemon(true); - return thread; - } + runnable -> { + Thread thread = new Thread(runnable, "close-unused-spanners-worker"); + thread.setDaemon(true); + return thread; }); this.closerService.scheduleAtFixedRate( new CloseUnusedSpannersRunnable(), @@ -322,7 +314,6 @@ public Thread newThread(Runnable r) { initialized = true; } - @SuppressWarnings("rawtypes") @VisibleForTesting Spanner createSpanner(SpannerPoolKey key, ConnectionOptions options) { SpannerOptions.Builder builder = SpannerOptions.newBuilder(); @@ -339,14 +330,7 @@ Spanner createSpanner(SpannerPoolKey key, ConnectionOptions options) { // Credentials may not be sent over a plain text channel. builder.setCredentials(NoCredentials.getInstance()); // Set a custom channel configurator to allow http instead of https. - builder.setChannelConfigurator( - new ApiFunction() { - @Override - public ManagedChannelBuilder apply(ManagedChannelBuilder input) { - input.usePlaintext(); - return input; - } - }); + builder.setChannelConfigurator(ManagedChannelBuilder::usePlaintext); } if (options.getConfigurator() != null) { options.getConfigurator().configure(builder); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementResultImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementResultImpl.java index 37e8d7e5a07..58a1f7ae1c0 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementResultImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementResultImpl.java @@ -24,7 +24,7 @@ import com.google.cloud.spanner.Struct; import com.google.cloud.spanner.Type; import com.google.cloud.spanner.Type.StructField; -import java.util.Arrays; +import java.util.Collections; /** Implementation of {@link StatementResult} */ class StatementResultImpl implements StatementResult { @@ -77,7 +77,7 @@ static StatementResult resultSet( return of( ResultSets.forRows( Type.struct(StructField.of(name, Type.bool())), - Arrays.asList(Struct.newBuilder().set(name).to(value).build())), + Collections.singletonList(Struct.newBuilder().set(name).to(value).build())), clientSideStatementType); } @@ -90,7 +90,7 @@ static StatementResult resultSet( return of( ResultSets.forRows( Type.struct(StructField.of(name, Type.int64())), - Arrays.asList(Struct.newBuilder().set(name).to(value).build())), + Collections.singletonList(Struct.newBuilder().set(name).to(value).build())), clientSideStatementType); } @@ -103,7 +103,7 @@ static StatementResult resultSet( return of( ResultSets.forRows( Type.struct(StructField.of(name, Type.array(Type.int64()))), - Arrays.asList(Struct.newBuilder().set(name).toInt64Array(values).build())), + Collections.singletonList(Struct.newBuilder().set(name).toInt64Array(values).build())), clientSideStatementType); } @@ -116,7 +116,7 @@ static StatementResult resultSet( return of( ResultSets.forRows( Type.struct(StructField.of(name, Type.string())), - Arrays.asList(Struct.newBuilder().set(name).to(value).build())), + Collections.singletonList(Struct.newBuilder().set(name).to(value).build())), clientSideStatementType); } @@ -130,7 +130,7 @@ static StatementResult resultSet( return of( ResultSets.forRows( Type.struct(StructField.of(name, Type.string())), - Arrays.asList(Struct.newBuilder().set(name).to(value.toString()).build())), + Collections.singletonList(Struct.newBuilder().set(name).to(value.toString()).build())), clientSideStatementType); } @@ -143,7 +143,7 @@ static StatementResult resultSet( return of( ResultSets.forRows( Type.struct(StructField.of(name, Type.timestamp())), - Arrays.asList(Struct.newBuilder().set(name).to(value).build())), + Collections.singletonList(Struct.newBuilder().set(name).to(value).build())), clientSideStatementType); } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java index 3f13af45bb4..29ee44bede3 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java @@ -658,7 +658,7 @@ private final class OperationFutureCallable call() throws Exception { + public OperationFuture call() { acquireAdministrativeRequestsRateLimiter(); return runWithRetryOnAdministrativeRequestsExceeded( @@ -701,8 +701,7 @@ private interface OperationsLister { private Operation mostRecentOperation( OperationsLister lister, Function getStartTimeFunction, - Timestamp initialCallTime) - throws InvalidProtocolBufferException { + Timestamp initialCallTime) { Operation res = null; Timestamp currMaxStartTime = null; String nextPageToken = null; @@ -981,38 +980,30 @@ public OperationFuture createDatabase( request, DatabaseAdminGrpc.getCreateDatabaseMethod(), instanceName, - new OperationsLister() { - @Override - public Paginated listOperations(String nextPageToken) { - return listDatabaseOperations( + nextPageToken -> + listDatabaseOperations( instanceName, 0, String.format( "(metadata.@type:type.googleapis.com/%s) AND (name:%s/operations/)", CreateDatabaseMetadata.getDescriptor().getFullName(), String.format("%s/databases/%s", instanceName, databaseId)), - nextPageToken); - } - }, - new Function() { - @Override - public Timestamp apply(Operation input) { - if (input.getDone() && input.hasResponse()) { - try { - Timestamp createTime = - input.getResponse().unpack(Database.class).getCreateTime(); - if (Timestamp.getDefaultInstance().equals(createTime)) { - // Create time was not returned by the server (proto objects never return - // null, instead they return the default instance). Return null from this - // method to indicate that there is no known create time. - return null; - } - } catch (InvalidProtocolBufferException e) { + nextPageToken), + input -> { + if (input.getDone() && input.hasResponse()) { + try { + Timestamp createTime = input.getResponse().unpack(Database.class).getCreateTime(); + if (Timestamp.getDefaultInstance().equals(createTime)) { + // Create time was not returned by the server (proto objects never return + // null, instead they return the default instance). Return null from this + // method to indicate that there is no known create time. return null; } + } catch (InvalidProtocolBufferException e) { + return null; } - return null; } + return null; }); return RetryHelper.runWithRetries( callable, @@ -1152,31 +1143,24 @@ public OperationFuture createBackup( request, DatabaseAdminGrpc.getCreateBackupMethod(), instanceName, - new OperationsLister() { - @Override - public Paginated listOperations(String nextPageToken) { - return listBackupOperations( + nextPageToken -> + listBackupOperations( instanceName, 0, String.format( "(metadata.@type:type.googleapis.com/%s) AND (metadata.name:%s)", CreateBackupMetadata.getDescriptor().getFullName(), String.format("%s/backups/%s", instanceName, backupId)), - nextPageToken); - } - }, - new Function() { - @Override - public Timestamp apply(Operation input) { - try { - return input - .getMetadata() - .unpack(CreateBackupMetadata.class) - .getProgress() - .getStartTime(); - } catch (InvalidProtocolBufferException e) { - return null; - } + nextPageToken), + input -> { + try { + return input + .getMetadata() + .unpack(CreateBackupMetadata.class) + .getProgress() + .getStartTime(); + } catch (InvalidProtocolBufferException e) { + return null; } }); return RetryHelper.runWithRetries( @@ -1211,31 +1195,24 @@ public OperationFuture restoreDatabase(final requestBuilder.build(), DatabaseAdminGrpc.getRestoreDatabaseMethod(), databaseInstanceName, - new OperationsLister() { - @Override - public Paginated listOperations(String nextPageToken) { - return listDatabaseOperations( + nextPageToken -> + listDatabaseOperations( databaseInstanceName, 0, String.format( "(metadata.@type:type.googleapis.com/%s) AND (metadata.name:%s)", RestoreDatabaseMetadata.getDescriptor().getFullName(), String.format("%s/databases/%s", databaseInstanceName, databaseId)), - nextPageToken); - } - }, - new Function() { - @Override - public Timestamp apply(Operation input) { - try { - return input - .getMetadata() - .unpack(RestoreDatabaseMetadata.class) - .getProgress() - .getStartTime(); - } catch (InvalidProtocolBufferException e) { - return null; - } + nextPageToken), + input -> { + try { + return input + .getMetadata() + .unpack(RestoreDatabaseMetadata.class) + .getProgress() + .getStartTime(); + } catch (InvalidProtocolBufferException e) { + return null; } }); return RetryHelper.runWithRetries( diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerMetadataProvider.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerMetadataProvider.java index 7bbe6a31a1e..7f9a32765e0 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerMetadataProvider.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerMetadataProvider.java @@ -18,7 +18,7 @@ import com.google.common.collect.ImmutableMap; import io.grpc.Metadata; import io.grpc.Metadata.Key; -import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.regex.Matcher; @@ -61,7 +61,8 @@ Map> newExtraHeaders( return ImmutableMap.>builder() .put( resourceHeaderKey, - Arrays.asList(getResourceHeaderValue(resourceTokenTemplate, defaultResourceToken))) + Collections.singletonList( + getResourceHeaderValue(resourceTokenTemplate, defaultResourceToken))) .build(); } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java index 9f411ebcc33..cce92e0f378 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java @@ -123,7 +123,7 @@ final class Paginated { public Paginated(@Nullable Iterable results, @Nullable String nextPageToken) { // The generated HTTP client has null members when no results are present, rather than an // empty list. Implicitly convert to an empty list to minimize the risk of NPEs. - this.results = (results == null) ? ImmutableList.of() : results; + this.results = (results == null) ? ImmutableList.of() : results; this.nextPageToken = (nextPageToken == null || nextPageToken.isEmpty()) ? null : nextPageToken; } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractAsyncTransactionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractAsyncTransactionTest.java index bf76ea4f392..2296b2d4d6a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractAsyncTransactionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractAsyncTransactionTest.java @@ -30,7 +30,6 @@ import static com.google.cloud.spanner.MockSpannerTestUtil.UPDATE_COUNT; import static com.google.cloud.spanner.MockSpannerTestUtil.UPDATE_STATEMENT; -import com.google.api.core.ApiFunction; import com.google.cloud.NoCredentials; import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult; import io.grpc.ManagedChannelBuilder; @@ -89,19 +88,12 @@ public static void teardown() throws Exception { } @Before - public void before() throws Exception { + public void before() { String endpoint = address.getHostString() + ":" + server.getPort(); spanner = SpannerOptions.newBuilder() .setProjectId(TEST_PROJECT) - .setChannelConfigurator( - new ApiFunction() { - @Override - public ManagedChannelBuilder apply(ManagedChannelBuilder input) { - input.usePlaintext(); - return input; - } - }) + .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) .setHost("https://" + endpoint) .setCredentials(NoCredentials.getInstance()) .setSessionPoolOption(SessionPoolOptions.newBuilder().setFailOnSessionLeak().build()) @@ -122,7 +114,7 @@ public ManagedChannelBuilder apply(ManagedChannelBuilder input) { } @After - public void after() throws Exception { + public void after() { spanner.close(); spannerWithEmptySessionPool.close(); mockSpanner.removeAllExecutionTimes(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncResultSetImplStressTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncResultSetImplStressTest.java index ae59b480423..ea01fecc269 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncResultSetImplStressTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncResultSetImplStressTest.java @@ -24,9 +24,7 @@ import com.google.api.gax.core.ExecutorProvider; import com.google.cloud.spanner.AsyncResultSet.CallbackResponse; import com.google.cloud.spanner.AsyncResultSet.CursorState; -import com.google.cloud.spanner.AsyncResultSet.ReadyCallback; import com.google.cloud.spanner.Type.StructField; -import com.google.common.base.Function; import com.google.common.collect.ImmutableList; import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.ThreadFactoryBuilder; @@ -170,20 +168,13 @@ private static ScheduledExecutorService createExecService(int threadCount) { } @Test - public void toList() throws Exception { + public void toList() { ExecutorProvider executorProvider = SpannerOptions.createDefaultAsyncExecutorProvider(); for (int bufferSize = 1; bufferSize < resultSetSize * 2; bufferSize *= 2) { for (int i = 0; i < TEST_RUNS; i++) { try (AsyncResultSetImpl impl = new AsyncResultSetImpl(executorProvider, createResultSet(), bufferSize)) { - List list = - impl.toList( - new Function() { - @Override - public Row apply(StructReader input) { - return Row.create(input); - } - }); + List list = impl.toList(Row::create); assertThat(list).containsExactlyElementsIn(createExpectedRows()); } } @@ -191,21 +182,14 @@ public Row apply(StructReader input) { } @Test - public void toListWithErrors() throws Exception { + public void toListWithErrors() { ExecutorProvider executorProvider = SpannerOptions.createDefaultAsyncExecutorProvider(); for (int bufferSize = 1; bufferSize < resultSetSize * 2; bufferSize *= 2) { for (int i = 0; i < TEST_RUNS; i++) { try (AsyncResultSetImpl impl = new AsyncResultSetImpl( executorProvider, createResultSetWithErrors(1.0 / resultSetSize), bufferSize)) { - List list = - impl.toList( - new Function() { - @Override - public Row apply(StructReader input) { - return Row.create(input); - } - }); + List list = impl.toList(Row::create); assertThat(list).containsExactlyElementsIn(createExpectedRows()); } catch (SpannerException e) { assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); @@ -224,15 +208,7 @@ public void asyncToList() throws Exception { for (int i = 0; i < TEST_RUNS; i++) { try (AsyncResultSet impl = new AsyncResultSetImpl(executorProvider, createResultSet(), bufferSize)) { - futures.add( - impl.toListAsync( - new Function() { - @Override - public Row apply(StructReader input) { - return Row.create(input); - } - }, - executor)); + futures.add(impl.toListAsync(Row::create, executor)); } } List> lists = ApiFutures.allAsList(futures).get(); @@ -256,26 +232,23 @@ public void consume() throws Exception { final SettableApiFuture> future = SettableApiFuture.create(); try (AsyncResultSetImpl impl = new AsyncResultSetImpl(executorProvider, createResultSet(), bufferSize)) { - final ImmutableList.Builder builder = ImmutableList.builder(); + final ImmutableList.Builder builder = ImmutableList.builder(); impl.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - // Randomly do something with the received data or not. Not calling tryNext() in - // the onDataReady is not 'normal', but users may do it, and the result set - // should be able to handle that. - if (random.nextBoolean()) { - CursorState state; - while ((state = resultSet.tryNext()) == CursorState.OK) { - builder.add(Row.create(resultSet)); - } - if (state == CursorState.DONE) { - future.set(builder.build()); - } + resultSet -> { + // Randomly do something with the received data or not. Not calling tryNext() in + // the onDataReady is not 'normal', but users may do it, and the result set + // should be able to handle that. + if (random.nextBoolean()) { + CursorState state; + while ((state = resultSet.tryNext()) == CursorState.OK) { + builder.add(Row.create(resultSet)); + } + if (state == CursorState.DONE) { + future.set(builder.build()); } - return CallbackResponse.CONTINUE; } + return CallbackResponse.CONTINUE; }); assertThat(future.get()).containsExactlyElementsIn(createExpectedRows()); } @@ -299,23 +272,20 @@ public void returnDoneBeforeEnd() throws Exception { ApiFuture res = impl.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return random.nextBoolean() - ? CallbackResponse.DONE - : CallbackResponse.CONTINUE; - case OK: - return random.nextInt(resultSetSize) <= 2 - ? CallbackResponse.DONE - : CallbackResponse.CONTINUE; - default: - throw new IllegalStateException(); - } + resultSet -> { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return random.nextBoolean() + ? CallbackResponse.DONE + : CallbackResponse.CONTINUE; + case OK: + return random.nextInt(resultSetSize) <= 2 + ? CallbackResponse.DONE + : CallbackResponse.CONTINUE; + default: + throw new IllegalStateException(); } }); assertThat(res.get(10L, TimeUnit.SECONDS)).isNull(); @@ -342,25 +312,22 @@ public void pauseResume() throws Exception { try (AsyncResultSetImpl impl = new AsyncResultSetImpl(executorProvider, createResultSet(), bufferSize)) { resultSets.add(impl); - final ImmutableList.Builder builder = ImmutableList.builder(); + final ImmutableList.Builder builder = ImmutableList.builder(); impl.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - CursorState state; - while ((state = resultSet.tryNext()) == CursorState.OK) { - builder.add(Row.create(resultSet)); - // Randomly request the iterator to pause. - if (random.nextBoolean()) { - return CallbackResponse.PAUSE; - } - } - if (state == CursorState.DONE) { - future.set(builder.build()); + resultSet -> { + CursorState state; + while ((state = resultSet.tryNext()) == CursorState.OK) { + builder.add(Row.create(resultSet)); + // Randomly request the iterator to pause. + if (random.nextBoolean()) { + return CallbackResponse.PAUSE; } - return CallbackResponse.CONTINUE; } + if (state == CursorState.DONE) { + future.set(builder.build()); + } + return CallbackResponse.CONTINUE; }); } } @@ -404,29 +371,26 @@ public void cancel() throws Exception { try (AsyncResultSetImpl impl = new AsyncResultSetImpl(executorProvider, createResultSet(), bufferSize)) { resultSets.add(impl); - final ImmutableList.Builder builder = ImmutableList.builder(); + final ImmutableList.Builder builder = ImmutableList.builder(); impl.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - CursorState state; - while ((state = resultSet.tryNext()) == CursorState.OK) { - builder.add(Row.create(resultSet)); - // Randomly request the iterator to pause. - if (random.nextBoolean()) { - return CallbackResponse.PAUSE; - } - } - if (state == CursorState.DONE) { - future.set(builder.build()); + resultSet -> { + try { + CursorState state; + while ((state = resultSet.tryNext()) == CursorState.OK) { + builder.add(Row.create(resultSet)); + // Randomly request the iterator to pause. + if (random.nextBoolean()) { + return CallbackResponse.PAUSE; } - return CallbackResponse.CONTINUE; - } catch (SpannerException e) { - future.setException(e); - throw e; } + if (state == CursorState.DONE) { + future.set(builder.build()); + } + return CallbackResponse.CONTINUE; + } catch (SpannerException e) { + future.setException(e); + throw e; } }); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncResultSetImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncResultSetImplTest.java index 682802d85eb..28a46d8951d 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncResultSetImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncResultSetImplTest.java @@ -72,16 +72,19 @@ public void close() { rs.setCallback(mock(Executor.class), mock(ReadyCallback.class)); fail("missing expected exception"); } catch (IllegalStateException e) { + // Expected exception } try { rs.toList(mock(Function.class)); fail("missing expected exception"); } catch (IllegalStateException e) { + // Expected exception } try { rs.toListAsync(mock(Function.class), mock(Executor.class)); fail("missing expected exception"); } catch (IllegalStateException e) { + // Expected exception } // The following methods are allowed on a closed result set. @@ -117,14 +120,7 @@ public void toList() { when(delegate.getCurrentRowAsStruct()).thenReturn(mock(Struct.class)); try (AsyncResultSetImpl rs = new AsyncResultSetImpl(simpleProvider, delegate, AsyncResultSetImpl.DEFAULT_BUFFER_SIZE)) { - List list = - rs.toList( - new Function() { - @Override - public Object apply(StructReader input) { - return new Object(); - } - }); + List list = rs.toList(ignored -> new Object()); assertThat(list).hasSize(3); } } @@ -138,13 +134,7 @@ public void toListPropagatesError() { ErrorCode.INVALID_ARGUMENT, "invalid query")); try (AsyncResultSetImpl rs = new AsyncResultSetImpl(simpleProvider, delegate, AsyncResultSetImpl.DEFAULT_BUFFER_SIZE)) { - rs.toList( - new Function() { - @Override - public Object apply(StructReader input) { - return new Object(); - } - }); + rs.toList(ignored -> new Object()); fail("missing expected exception"); } catch (SpannerException e) { assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); @@ -160,15 +150,7 @@ public void toListAsync() throws InterruptedException, ExecutionException { when(delegate.getCurrentRowAsStruct()).thenReturn(mock(Struct.class)); try (AsyncResultSetImpl rs = new AsyncResultSetImpl(simpleProvider, delegate, AsyncResultSetImpl.DEFAULT_BUFFER_SIZE)) { - ApiFuture> future = - rs.toListAsync( - new Function() { - @Override - public Object apply(StructReader input) { - return new Object(); - } - }, - executor); + ApiFuture> future = rs.toListAsync(ignored -> new Object(), executor); assertThat(future.get()).hasSize(3); } executor.shutdown(); @@ -184,15 +166,7 @@ public void toListAsyncPropagatesError() throws InterruptedException { ErrorCode.INVALID_ARGUMENT, "invalid query")); try (AsyncResultSetImpl rs = new AsyncResultSetImpl(simpleProvider, delegate, AsyncResultSetImpl.DEFAULT_BUFFER_SIZE)) { - rs.toListAsync( - new Function() { - @Override - public Object apply(StructReader input) { - return new Object(); - } - }, - executor) - .get(); + rs.toListAsync(ignored -> new Object(), executor).get(); fail("missing expected exception"); } catch (ExecutionException e) { assertThat(e.getCause()).isInstanceOf(SpannerException.class); @@ -216,19 +190,16 @@ public void withCallback() throws InterruptedException { new AsyncResultSetImpl(simpleProvider, delegate, AsyncResultSetImpl.DEFAULT_BUFFER_SIZE)) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - callbackCounter.incrementAndGet(); - CursorState state; - while ((state = resultSet.tryNext()) == CursorState.OK) { - rowCounter.incrementAndGet(); - } - if (state == CursorState.DONE) { - finishedLatch.countDown(); - } - return CallbackResponse.CONTINUE; + resultSet -> { + callbackCounter.incrementAndGet(); + CursorState state; + while ((state = resultSet.tryNext()) == CursorState.OK) { + rowCounter.incrementAndGet(); } + if (state == CursorState.DONE) { + finishedLatch.countDown(); + } + return CallbackResponse.CONTINUE; }); } finishedLatch.await(); @@ -251,17 +222,14 @@ public void callbackReceivesError() throws InterruptedException { new AsyncResultSetImpl(simpleProvider, delegate, AsyncResultSetImpl.DEFAULT_BUFFER_SIZE)) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - resultSet.tryNext(); - receivedErr.push(new Exception("missing expected exception")); - } catch (SpannerException e) { - receivedErr.push(e); - } - return CallbackResponse.DONE; + resultSet -> { + try { + resultSet.tryNext(); + receivedErr.push(new Exception("missing expected exception")); + } catch (SpannerException e) { + receivedErr.push(e); } + return CallbackResponse.DONE; }); } Exception e = receivedErr.take(); @@ -287,19 +255,16 @@ public void callbackReceivesErrorHalfwayThrough() throws InterruptedException { new AsyncResultSetImpl(simpleProvider, delegate, AsyncResultSetImpl.DEFAULT_BUFFER_SIZE)) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - if (resultSet.tryNext() != CursorState.DONE) { - rowCount.incrementAndGet(); - return CallbackResponse.CONTINUE; - } - } catch (SpannerException e) { - receivedErr.push(e); + resultSet -> { + try { + if (resultSet.tryNext() != CursorState.DONE) { + rowCount.incrementAndGet(); + return CallbackResponse.CONTINUE; } - return CallbackResponse.DONE; + } catch (SpannerException e) { + receivedErr.push(e); } + return CallbackResponse.DONE; }); } Exception e = receivedErr.take(); @@ -323,23 +288,20 @@ public void pauseResume() throws InterruptedException { new AsyncResultSetImpl(simpleProvider, delegate, AsyncResultSetImpl.DEFAULT_BUFFER_SIZE)) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - callbackCounter.incrementAndGet(); - CursorState state = resultSet.tryNext(); - if (state == CursorState.OK) { - try { - queue.put(new Object()); - } catch (InterruptedException e) { - // Finish early if an error occurs. - return CallbackResponse.DONE; - } - return CallbackResponse.PAUSE; + resultSet -> { + callbackCounter.incrementAndGet(); + CursorState state = resultSet.tryNext(); + if (state == CursorState.OK) { + try { + queue.put(new Object()); + } catch (InterruptedException e) { + // Finish early if an error occurs. + return CallbackResponse.DONE; } - finished.set(true); - return CallbackResponse.DONE; + return CallbackResponse.PAUSE; } + finished.set(true); + return CallbackResponse.DONE; }); int rowCounter = 0; while (!finished.get()) { @@ -368,32 +330,29 @@ public void cancel() throws InterruptedException { new AsyncResultSetImpl(simpleProvider, delegate, AsyncResultSetImpl.DEFAULT_BUFFER_SIZE)) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - callbackCounter.incrementAndGet(); - try { - CursorState state = resultSet.tryNext(); - if (state == CursorState.OK) { - try { - queue.put(new Object()); - } catch (InterruptedException e) { - // Finish early if an error occurs. - return CallbackResponse.DONE; - } - } - // Pause after 2 rows to make sure that no more data is consumed until the cancel - // call has been received. - return callbackCounter.get() == 2 - ? CallbackResponse.PAUSE - : CallbackResponse.CONTINUE; - } catch (SpannerException e) { - if (e.getErrorCode() == ErrorCode.CANCELLED) { - finished.set(true); + resultSet -> { + callbackCounter.incrementAndGet(); + try { + CursorState state = resultSet.tryNext(); + if (state == CursorState.OK) { + try { + queue.put(new Object()); + } catch (InterruptedException e) { + // Finish early if an error occurs. + return CallbackResponse.DONE; } } - return CallbackResponse.DONE; + // Pause after 2 rows to make sure that no more data is consumed until the cancel + // call has been received. + return callbackCounter.get() == 2 + ? CallbackResponse.PAUSE + : CallbackResponse.CONTINUE; + } catch (SpannerException e) { + if (e.getErrorCode() == ErrorCode.CANCELLED) { + finished.set(true); + } } + return CallbackResponse.DONE; }); int rowCounter = 0; while (!finished.get()) { @@ -423,12 +382,9 @@ public void callbackReturnsError() throws InterruptedException { new AsyncResultSetImpl(simpleProvider, delegate, AsyncResultSetImpl.DEFAULT_BUFFER_SIZE)) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - callbackCounter.incrementAndGet(); - throw new RuntimeException("async test"); - } + resultSet -> { + callbackCounter.incrementAndGet(); + throw new RuntimeException("async test"); }); rs.getResult().get(); fail("missing expected exception"); @@ -451,14 +407,9 @@ public void callbackReturnsDoneBeforeEnd_shouldStopIteration() throws Exception new AsyncResultSetImpl(simpleProvider, delegate, AsyncResultSetImpl.DEFAULT_BUFFER_SIZE)) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - // Not calling resultSet.tryNext() means that it will also never return DONE. - // Instead the callback indicates that it does not want any more rows. - return CallbackResponse.DONE; - } - }); + // Not calling resultSet.tryNext() means that it will also never return DONE. + // Instead the callback indicates that it does not want any more rows. + ignored -> CallbackResponse.DONE); rs.getResult().get(10L, TimeUnit.SECONDS); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncRunnerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncRunnerTest.java index 085128c9ab0..8caa3feffb7 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncRunnerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncRunnerTest.java @@ -21,16 +21,13 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.SettableApiFuture; import com.google.cloud.Timestamp; import com.google.cloud.spanner.AsyncResultSet.CallbackResponse; -import com.google.cloud.spanner.AsyncResultSet.ReadyCallback; import com.google.cloud.spanner.MockSpannerServiceImpl.SimulatedExecutionTime; import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult; -import com.google.common.base.Function; import com.google.common.collect.ImmutableList; import com.google.common.util.concurrent.MoreExecutors; import com.google.spanner.v1.BatchCreateSessionsRequest; @@ -473,27 +470,24 @@ public void closeTransactionBeforeEndOfAsyncQuery() throws Exception { READ_TABLE_NAME, KeySet.all(), READ_COLUMN_NAMES, Options.bufferRows(1))) { rs.setCallback( Executors.newSingleThreadExecutor(), - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - dataReceived.countDown(); - try { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - finished.set(true); - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - dataChecked.await(); - results.put(resultSet.getString(0)); - } + resultSet -> { + dataReceived.countDown(); + try { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + finished.set(true); + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + dataChecked.await(); + results.put(resultSet.getString(0)); } - } catch (Throwable t) { - finished.setException(t); - return CallbackResponse.DONE; } + } catch (Throwable t) { + finished.setException(t); + return CallbackResponse.DONE; } }); } @@ -531,12 +525,7 @@ public void asyncRunnerReadRow() throws Exception { txn -> ApiFutures.transform( txn.readRowAsync(READ_TABLE_NAME, Key.of(1L), READ_COLUMN_NAMES), - new ApiFunction() { - @Override - public String apply(Struct input) { - return input.getString("Value"); - } - }, + input -> input.getString("Value"), MoreExecutors.directExecutor()), executor); assertThat(val.get()).isEqualTo("v1"); @@ -549,14 +538,7 @@ public void asyncRunnerRead() throws Exception { runner.runAsync( txn -> txn.readAsync(READ_TABLE_NAME, KeySet.all(), READ_COLUMN_NAMES) - .toListAsync( - new Function() { - @Override - public String apply(StructReader input) { - return input.getString("Value"); - } - }, - MoreExecutors.directExecutor()), + .toListAsync(input -> input.getString("Value"), MoreExecutors.directExecutor()), executor); assertThat(val.get()).containsExactly("v1", "v2", "v3"); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerImplTest.java index c60363e7932..aebc99ee96f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerImplTest.java @@ -40,7 +40,7 @@ public void testCommitReturnsCommitStats() { new AsyncTransactionManagerImpl(session, mock(Span.class), Options.commitStats())) { when(session.newTransaction(Options.fromTransactionOptions(Options.commitStats()))) .thenReturn(transaction); - when(transaction.ensureTxnAsync()).thenReturn(ApiFutures.immediateFuture(null)); + when(transaction.ensureTxnAsync()).thenReturn(ApiFutures.immediateFuture(null)); Timestamp commitTimestamp = Timestamp.ofTimeMicroseconds(1); CommitResponse response = mock(CommitResponse.class); when(response.getCommitTimestamp()).thenReturn(commitTimestamp); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java index b5fa3ee5813..82b46bdee45 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java @@ -40,8 +40,6 @@ import com.google.cloud.spanner.Options.ReadOption; import com.google.cloud.spanner.SessionPool.SessionPoolTransactionContext; import com.google.cloud.spanner.TransactionRunnerImpl.TransactionContextImpl; -import com.google.common.base.Function; -import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Range; @@ -97,22 +95,13 @@ public static AsyncTransactionFunction readAsync( final KeySet keys, final Iterable columns, final ReadOption... options) { - return new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, I input) throws Exception { - return ApiFutures.immediateFuture(txn.readAsync(table, keys, columns, options)); - } - }; + return (transaction, ignored) -> + ApiFutures.immediateFuture(transaction.readAsync(table, keys, columns, options)); } public static AsyncTransactionFunction readRowAsync( final String table, final Key key, final Iterable columns) { - return new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, I input) throws Exception { - return txn.readRowAsync(table, key, columns); - } - }; + return (transaction, ignored) -> transaction.readRowAsync(table, key, columns); } public static AsyncTransactionFunction buffer(Mutation mutation) { @@ -120,71 +109,62 @@ public static AsyncTransactionFunction buffer(Mutation mutation) { } public static AsyncTransactionFunction buffer(final Iterable mutations) { - return new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, I input) throws Exception { - txn.buffer(mutations); - return ApiFutures.immediateFuture(null); - } + return (transaction, ignored) -> { + transaction.buffer(mutations); + return ApiFutures.immediateFuture(null); }; } public static AsyncTransactionFunction executeUpdateAsync(Statement statement) { - return executeUpdateAsync(SettableApiFuture.create(), statement); + return executeUpdateAsync(SettableApiFuture.create(), statement); } public static AsyncTransactionFunction executeUpdateAsync( final SettableApiFuture result, final Statement statement) { - return new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, I input) throws Exception { - ApiFuture updateCount = txn.executeUpdateAsync(statement); - ApiFutures.addCallback( - updateCount, - new ApiFutureCallback() { - @Override - public void onFailure(Throwable t) { - result.setException(t); - } + return (transaction, ignored) -> { + ApiFuture updateCount = transaction.executeUpdateAsync(statement); + ApiFutures.addCallback( + updateCount, + new ApiFutureCallback() { + @Override + public void onFailure(Throwable t) { + result.setException(t); + } - @Override - public void onSuccess(Long input) { - result.set(input); - } - }, - MoreExecutors.directExecutor()); - return updateCount; - } + @Override + public void onSuccess(Long input) { + result.set(input); + } + }, + MoreExecutors.directExecutor()); + return updateCount; }; } public static AsyncTransactionFunction batchUpdateAsync( final Statement... statements) { - return batchUpdateAsync(SettableApiFuture.create(), statements); + return batchUpdateAsync(SettableApiFuture.create(), statements); } public static AsyncTransactionFunction batchUpdateAsync( final SettableApiFuture result, final Statement... statements) { - return new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, I input) throws Exception { - ApiFuture updateCounts = txn.batchUpdateAsync(Arrays.asList(statements)); - ApiFutures.addCallback( - updateCounts, - new ApiFutureCallback() { - @Override - public void onFailure(Throwable t) { - result.setException(t); - } + return (transaction, ignored) -> { + ApiFuture updateCounts = transaction.batchUpdateAsync(Arrays.asList(statements)); + ApiFutures.addCallback( + updateCounts, + new ApiFutureCallback() { + @Override + public void onFailure(Throwable t) { + result.setException(t); + } - @Override - public void onSuccess(long[] input) { - result.set(input); - } - }, - MoreExecutors.directExecutor()); - return updateCounts; - } + @Override + public void onSuccess(long[] input) { + result.set(input); + } + }, + MoreExecutors.directExecutor()); + return updateCounts; }; } } @@ -202,15 +182,12 @@ public void asyncTransactionManager_shouldRollbackOnCloseAsync() throws Exceptio // The mock server should already have the Rollback request, as we are waiting for the returned // ApiFuture to be done. mockSpanner.waitForRequestsToContain( - new Predicate() { - @Override - public boolean apply(AbstractMessage input) { - if (input instanceof RollbackRequest) { - RollbackRequest request = (RollbackRequest) input; - return request.getTransactionId().equals(selector.getId()); - } - return false; + input -> { + if (input instanceof RollbackRequest) { + RollbackRequest request = (RollbackRequest) input; + return request.getTransactionId().equals(selector.getId()); } + return false; }, 0L); } @@ -225,8 +202,7 @@ public void testAsyncTransactionManager_returnsCommitStats() throws Exception { CommitTimestampFuture commitTimestamp = transaction .then( - AsyncTransactionManagerHelper.buffer( - Mutation.delete("FOO", Key.of("foo"))), + AsyncTransactionManagerHelper.buffer(Mutation.delete("FOO", Key.of("foo"))), executor) .commitAsync(); assertNotNull(commitTimestamp.get()); @@ -251,7 +227,7 @@ public void asyncTransactionManagerUpdate() throws Exception { try { CommitTimestampFuture commitTimestamp = txn.then( - AsyncTransactionManagerHelper.executeUpdateAsync( + AsyncTransactionManagerHelper.executeUpdateAsync( updateCount, UPDATE_STATEMENT), executor) .commitAsync(); @@ -276,7 +252,7 @@ public void asyncTransactionManagerIsNonBlocking() throws Exception { try { CommitTimestampFuture commitTimestamp = txn.then( - AsyncTransactionManagerHelper.executeUpdateAsync( + AsyncTransactionManagerHelper.executeUpdateAsync( updateCount, UPDATE_STATEMENT), executor) .commitAsync(); @@ -299,8 +275,7 @@ public void asyncTransactionManagerInvalidUpdate() throws Exception { try { CommitTimestampFuture commitTimestamp = txn.then( - AsyncTransactionManagerHelper.executeUpdateAsync( - INVALID_UPDATE_STATEMENT), + AsyncTransactionManagerHelper.executeUpdateAsync(INVALID_UPDATE_STATEMENT), executor) .commitAsync(); commitTimestamp.get(); @@ -330,19 +305,15 @@ public void asyncTransactionManagerCommitAborted() throws Exception { attempt.incrementAndGet(); CommitTimestampFuture commitTimestamp = txn.then( - AsyncTransactionManagerHelper.executeUpdateAsync( + AsyncTransactionManagerHelper.executeUpdateAsync( updateCount, UPDATE_STATEMENT), executor) .then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Long input) - throws Exception { - if (attempt.get() == 1) { - mockSpanner.abortTransaction(txn); - } - return ApiFutures.immediateFuture(null); + (transaction, ignored) -> { + if (attempt.get() == 1) { + mockSpanner.abortTransaction(transaction); } + return ApiFutures.immediateFuture(null); }, executor) .commitAsync(); @@ -367,30 +338,26 @@ public void asyncTransactionManagerFireAndForgetInvalidUpdate() throws Exception try { CommitTimestampFuture ts = txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - // This fire-and-forget update statement should not fail the transaction. - // The exception will however cause the transaction to be retried, as the - // statement will not return a transaction id. - txn.executeUpdateAsync(INVALID_UPDATE_STATEMENT); - ApiFutures.addCallback( - txn.executeUpdateAsync(UPDATE_STATEMENT), - new ApiFutureCallback() { - @Override - public void onFailure(Throwable t) { - updateCount.setException(t); - } + (transaction, ignored) -> { + // This fire-and-forget update statement should not fail the transaction. + // The exception will however cause the transaction to be retried, as the + // statement will not return a transaction id. + transaction.executeUpdateAsync(INVALID_UPDATE_STATEMENT); + ApiFutures.addCallback( + transaction.executeUpdateAsync(UPDATE_STATEMENT), + new ApiFutureCallback() { + @Override + public void onFailure(Throwable t) { + updateCount.setException(t); + } - @Override - public void onSuccess(Long result) { - updateCount.set(result); - } - }, - MoreExecutors.directExecutor()); - return updateCount; - } + @Override + public void onSuccess(Long result) { + updateCount.set(result); + } + }, + MoreExecutors.directExecutor()); + return updateCount; }, executor) .commitAsync(); @@ -423,30 +390,18 @@ public void asyncTransactionManagerChain() throws Exception { while (true) { try { CommitTimestampFuture ts = - txn.then( - AsyncTransactionManagerHelper.executeUpdateAsync(UPDATE_STATEMENT), - executor) + txn.then(AsyncTransactionManagerHelper.executeUpdateAsync(UPDATE_STATEMENT), executor) .then( - AsyncTransactionManagerHelper.readRowAsync( + AsyncTransactionManagerHelper.readRowAsync( READ_TABLE_NAME, Key.of(1L), READ_COLUMN_NAMES), executor) .then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Struct input) - throws Exception { - return ApiFutures.immediateFuture(input.getString("Value")); - } - }, + (ignored, input) -> ApiFutures.immediateFuture(input.getString("Value")), executor) .then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, String input) - throws Exception { - assertThat(input).isEqualTo("v1"); - return ApiFutures.immediateFuture(null); - } + (ignored, input) -> { + assertThat(input).isEqualTo("v1"); + return ApiFutures.immediateFuture(null); }, executor) .commitAsync(); @@ -467,16 +422,11 @@ public void asyncTransactionManagerChainWithErrorInTheMiddle() throws Exception try { CommitTimestampFuture ts = txn.then( - AsyncTransactionManagerHelper.executeUpdateAsync( - INVALID_UPDATE_STATEMENT), + AsyncTransactionManagerHelper.executeUpdateAsync(INVALID_UPDATE_STATEMENT), executor) .then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Long input) - throws Exception { - throw new IllegalStateException("this should not be executed"); - } + (ignored1, ignored2) -> { + throw new IllegalStateException("this should not be executed"); }, executor) .commitAsync(); @@ -507,25 +457,20 @@ public void asyncTransactionManagerUpdateAborted() throws Exception { try { CommitTimestampFuture ts = txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - if (attempt.incrementAndGet() == 1) { - // Abort the first attempt. - mockSpanner.abortNextStatement(); - } else { - // Set the result of the update statement back to 1 row. - mockSpanner.putStatementResult( - StatementResult.update(UPDATE_STATEMENT, UPDATE_COUNT)); - } - return ApiFutures.immediateFuture(null); + (ignored1, ignored2) -> { + if (attempt.incrementAndGet() == 1) { + // Abort the first attempt. + mockSpanner.abortNextStatement(); + } else { + // Set the result of the update statement back to 1 row. + mockSpanner.putStatementResult( + StatementResult.update(UPDATE_STATEMENT, UPDATE_COUNT)); } + return ApiFutures.immediateFuture(null); }, executor) .then( - AsyncTransactionManagerHelper.executeUpdateAsync(UPDATE_STATEMENT), - executor) + AsyncTransactionManagerHelper.executeUpdateAsync(UPDATE_STATEMENT), executor) .commitAsync(); assertThat(ts.get()).isNotNull(); break; @@ -548,22 +493,18 @@ public void asyncTransactionManagerUpdateAbortedWithoutGettingResult() throws Ex try { CommitTimestampFuture ts = txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - if (attempt.incrementAndGet() == 1) { - mockSpanner.abortNextStatement(); - } - // This update statement will be aborted, but the error will not - // propagated to the transaction runner and cause the transaction to - // retry. Instead, the commit call will do that. - txn.executeUpdateAsync(UPDATE_STATEMENT); - // Resolving this future will not resolve the result of the entire - // transaction. The transaction result will be resolved when the commit - // has actually finished successfully. - return ApiFutures.immediateFuture(null); + (transaction, ignored) -> { + if (attempt.incrementAndGet() == 1) { + mockSpanner.abortNextStatement(); } + // This update statement will be aborted, but the error will not + // propagated to the transaction runner and cause the transaction to + // retry. Instead, the commit call will do that. + transaction.executeUpdateAsync(UPDATE_STATEMENT); + // Resolving this future will not resolve the result of the entire + // transaction. The transaction result will be resolved when the commit + // has actually finished successfully. + return ApiFutures.immediateFuture(null); }, executor) .commitAsync(); @@ -599,9 +540,7 @@ public void asyncTransactionManagerCommitFails() throws Exception { TransactionContextFuture txn = mgr.beginAsync(); while (true) { try { - txn.then( - AsyncTransactionManagerHelper.executeUpdateAsync(UPDATE_STATEMENT), - executor) + txn.then(AsyncTransactionManagerHelper.executeUpdateAsync(UPDATE_STATEMENT), executor) .commitAsync() .get(); fail("missing expected exception"); @@ -625,15 +564,11 @@ public void asyncTransactionManagerWaitsUntilAsyncUpdateHasFinished() throws Exc while (true) { try { txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - // Shoot-and-forget update. The commit will still wait for this request to - // finish. - txn.executeUpdateAsync(UPDATE_STATEMENT); - return ApiFutures.immediateFuture(null); - } + (transaction, input) -> { + // Shoot-and-forget update. The commit will still wait for this request to + // finish. + transaction.executeUpdateAsync(UPDATE_STATEMENT); + return ApiFutures.immediateFuture(null); }, executor) .commitAsync() @@ -657,7 +592,7 @@ public void asyncTransactionManagerBatchUpdate() throws Exception { while (true) { try { txn.then( - AsyncTransactionManagerHelper.batchUpdateAsync( + AsyncTransactionManagerHelper.batchUpdateAsync( result, UPDATE_STATEMENT, UPDATE_STATEMENT), executor) .commitAsync() @@ -681,7 +616,7 @@ public void asyncTransactionManagerIsNonBlockingWithBatchUpdate() throws Excepti try { CommitTimestampFuture ts = txn.then( - AsyncTransactionManagerHelper.batchUpdateAsync(res, UPDATE_STATEMENT), + AsyncTransactionManagerHelper.batchUpdateAsync(res, UPDATE_STATEMENT), executor) .commitAsync(); mockSpanner.unfreeze(); @@ -703,7 +638,7 @@ public void asyncTransactionManagerInvalidBatchUpdate() throws Exception { while (true) { try { txn.then( - AsyncTransactionManagerHelper.batchUpdateAsync( + AsyncTransactionManagerHelper.batchUpdateAsync( result, UPDATE_STATEMENT, INVALID_UPDATE_STATEMENT), executor) .commitAsync() @@ -730,18 +665,14 @@ public void asyncTransactionManagerFireAndForgetInvalidBatchUpdate() throws Exce while (true) { try { txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - txn.batchUpdateAsync( - ImmutableList.of(UPDATE_STATEMENT, INVALID_UPDATE_STATEMENT)); - return ApiFutures.immediateFuture(null); - } + (transaction, ignored) -> { + transaction.batchUpdateAsync( + ImmutableList.of(UPDATE_STATEMENT, INVALID_UPDATE_STATEMENT)); + return ApiFutures.immediateFuture(null); }, executor) .then( - AsyncTransactionManagerHelper.batchUpdateAsync( + AsyncTransactionManagerHelper.batchUpdateAsync( result, UPDATE_STATEMENT, UPDATE_STATEMENT), executor) .commitAsync() @@ -769,17 +700,13 @@ public void asyncTransactionManagerBatchUpdateAborted() throws Exception { while (true) { try { txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - if (attempt.incrementAndGet() == 1) { - return txn.batchUpdateAsync( - ImmutableList.of(UPDATE_STATEMENT, UPDATE_ABORTED_STATEMENT)); - } else { - return txn.batchUpdateAsync( - ImmutableList.of(UPDATE_STATEMENT, UPDATE_STATEMENT)); - } + (transaction, ignored) -> { + if (attempt.incrementAndGet() == 1) { + return transaction.batchUpdateAsync( + ImmutableList.of(UPDATE_STATEMENT, UPDATE_ABORTED_STATEMENT)); + } else { + return transaction.batchUpdateAsync( + ImmutableList.of(UPDATE_STATEMENT, UPDATE_STATEMENT)); } }, executor) @@ -811,16 +738,12 @@ public void asyncTransactionManagerBatchUpdateAbortedBeforeFirstStatement() thro while (true) { try { txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - if (attempt.incrementAndGet() == 1) { - mockSpanner.abortNextStatement(); - } - return txn.batchUpdateAsync( - ImmutableList.of(UPDATE_STATEMENT, UPDATE_STATEMENT)); + (transaction, ignored) -> { + if (attempt.incrementAndGet() == 1) { + mockSpanner.abortNextStatement(); } + return transaction.batchUpdateAsync( + ImmutableList.of(UPDATE_STATEMENT, UPDATE_STATEMENT)); }, executor) .commitAsync() @@ -854,33 +777,25 @@ public void asyncTransactionManagerWithBatchUpdateCommitAborted() throws Excepti final SettableApiFuture result = SettableApiFuture.create(); try { txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - if (attempt.get() > 0) { - // Set the result of the update statement back to 1 row. - mockSpanner.putStatementResult( - StatementResult.update(UPDATE_STATEMENT, UPDATE_COUNT)); - } - return ApiFutures.immediateFuture(null); + (ignored1, ignored2) -> { + if (attempt.get() > 0) { + // Set the result of the update statement back to 1 row. + mockSpanner.putStatementResult( + StatementResult.update(UPDATE_STATEMENT, UPDATE_COUNT)); } + return ApiFutures.immediateFuture(null); }, executor) .then( - AsyncTransactionManagerHelper.batchUpdateAsync( + AsyncTransactionManagerHelper.batchUpdateAsync( result, UPDATE_STATEMENT, UPDATE_STATEMENT), executor) .then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, long[] input) - throws Exception { - if (attempt.incrementAndGet() == 1) { - mockSpanner.abortTransaction(txn); - } - return ApiFutures.immediateFuture(null); + (transaction, ignored) -> { + if (attempt.incrementAndGet() == 1) { + mockSpanner.abortTransaction(transaction); } + return ApiFutures.immediateFuture(null); }, executor) .commitAsync() @@ -913,22 +828,19 @@ public void asyncTransactionManagerBatchUpdateAbortedWithoutGettingResult() thro while (true) { try { txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - if (attempt.incrementAndGet() == 1) { - mockSpanner.abortNextStatement(); - } - // This update statement will be aborted, but the error will not propagated to - // the transaction manager and cause the transaction to retry. Instead, the - // commit call will do that. Depending on the timing, that will happen - // directly in the transaction manager if the ABORTED error has already been - // returned by the batch update call before the commit call starts. Otherwise, - // the backend will return an ABORTED error for the commit call. - txn.batchUpdateAsync(ImmutableList.of(UPDATE_STATEMENT, UPDATE_STATEMENT)); - return ApiFutures.immediateFuture(null); + (transaction, ignored) -> { + if (attempt.incrementAndGet() == 1) { + mockSpanner.abortNextStatement(); } + // This update statement will be aborted, but the error will not propagated + // to the transaction manager and cause the transaction to retry. Instead, + // the commit call will do that. Depending on the timing, that will happen + // directly in the transaction manager if the ABORTED error has already been + // returned by the batch update call before the commit call starts. + // Otherwise, the backend will return an ABORTED error for the commit call. + transaction.batchUpdateAsync( + ImmutableList.of(UPDATE_STATEMENT, UPDATE_STATEMENT)); + return ApiFutures.immediateFuture(null); }, executor) .commitAsync() @@ -975,7 +887,7 @@ public void asyncTransactionManagerWithBatchUpdateCommitFails() throws Exception while (true) { try { txn.then( - AsyncTransactionManagerHelper.batchUpdateAsync( + AsyncTransactionManagerHelper.batchUpdateAsync( UPDATE_STATEMENT, UPDATE_STATEMENT), executor) .commitAsync() @@ -1004,13 +916,9 @@ public void asyncTransactionManagerWaitsUntilAsyncBatchUpdateHasFinished() throw while (true) { try { txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - txn.batchUpdateAsync(ImmutableList.of(UPDATE_STATEMENT)); - return ApiFutures.immediateFuture(null); - } + (transaction, ignored) -> { + transaction.batchUpdateAsync(ImmutableList.of(UPDATE_STATEMENT)); + return ApiFutures.immediateFuture(null); }, executor) .commitAsync() @@ -1037,17 +945,11 @@ public void asyncTransactionManagerReadRow() throws Exception { val = step = txn.then( - AsyncTransactionManagerHelper.readRowAsync( + AsyncTransactionManagerHelper.readRowAsync( READ_TABLE_NAME, Key.of(1L), READ_COLUMN_NAMES), executor) .then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Struct input) - throws Exception { - return ApiFutures.immediateFuture(input.getString("Value")); - } - }, + (ignored, input) -> ApiFutures.immediateFuture(input.getString("Value")), executor); step.commitAsync().get(); break; @@ -1068,21 +970,11 @@ public void asyncTransactionManagerRead() throws Exception { try { res = txn.then( - new AsyncTransactionFunction>() { - @Override - public ApiFuture> apply(TransactionContext txn, Void input) - throws Exception { - return txn.readAsync(READ_TABLE_NAME, KeySet.all(), READ_COLUMN_NAMES) + (transaction, ignored) -> + transaction + .readAsync(READ_TABLE_NAME, KeySet.all(), READ_COLUMN_NAMES) .toListAsync( - new Function() { - @Override - public String apply(StructReader input) { - return input.getString("Value"); - } - }, - MoreExecutors.directExecutor()); - } - }, + input -> input.getString("Value"), MoreExecutors.directExecutor()), executor); // Commit the transaction. res.commitAsync().get(); @@ -1108,28 +1000,19 @@ public void asyncTransactionManagerQuery() throws Exception { final String column = "FirstName"; CommitTimestampFuture commitTimestamp = txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - return txn.readRowAsync( - "Singers", Key.of(singerId), Collections.singleton(column)); - } - }, + (transaction, ignored) -> + transaction.readRowAsync( + "Singers", Key.of(singerId), Collections.singleton(column)), executor) .then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Struct input) - throws Exception { - String name = input.getString(column); - txn.buffer( - Mutation.newUpdateBuilder("Singers") - .set(column) - .to(name.toUpperCase()) - .build()); - return ApiFutures.immediateFuture(null); - } + (transaction, input) -> { + String name = input.getString(column); + transaction.buffer( + Mutation.newUpdateBuilder("Singers") + .set(column) + .to(name.toUpperCase()) + .build()); + return ApiFutures.immediateFuture(null); }, executor) .commitAsync(); @@ -1152,12 +1035,7 @@ public void asyncTransactionManager_shouldPropagateStatementFailure() TransactionContextFuture txnContextFuture = transactionManager.beginAsync(); AsyncTransactionStep updateFuture = txnContextFuture.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) throws Exception { - return txn.executeUpdateAsync(INVALID_UPDATE_STATEMENT); - } - }, + (transaction, ignored) -> transaction.executeUpdateAsync(INVALID_UPDATE_STATEMENT), executor); final SettableApiFuture res = SettableApiFuture.create(); ApiFutures.addCallback( diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BackupTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BackupTest.java index f2b479b6660..f5053fc8c99 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BackupTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BackupTest.java @@ -34,15 +34,13 @@ import com.google.cloud.spanner.encryption.EncryptionInfo; import com.google.rpc.Code; import com.google.rpc.Status; -import java.util.Arrays; +import java.util.Collections; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; @RunWith(JUnit4.class) public class BackupTest { @@ -67,13 +65,7 @@ public class BackupTest { public void setUp() { initMocks(this); when(dbClient.newBackupBuilder(Mockito.any(BackupId.class))) - .thenAnswer( - new Answer() { - @Override - public Builder answer(InvocationOnMock invocation) { - return new Backup.Builder(dbClient, (BackupId) invocation.getArguments()[0]); - } - }); + .thenAnswer(invocation -> new Builder(dbClient, (BackupId) invocation.getArguments()[0])); } @Test @@ -288,7 +280,7 @@ public void testIAMPermissions() { dbClient .newBackupBuilder(BackupId.of("test-project", "test-instance", "test-backup")) .build(); - Iterable permissions = Arrays.asList("read"); + Iterable permissions = Collections.singletonList("read"); backup.testIAMPermissions(permissions); verify(dbClient).testBackupIAMPermissions("test-instance", "test-backup", permissions); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BatchClientImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BatchClientImplTest.java index f53a3ac406b..91fbac83e6f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BatchClientImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BatchClientImplTest.java @@ -31,7 +31,6 @@ import com.google.cloud.spanner.spi.v1.SpannerRpc; import com.google.protobuf.ByteString; import com.google.protobuf.util.Timestamps; -import com.google.spanner.v1.BeginTransactionRequest; import com.google.spanner.v1.Session; import com.google.spanner.v1.Transaction; import java.util.Collections; @@ -71,7 +70,7 @@ public void setUp() { when(spannerOptions.getRetrySettings()).thenReturn(RetrySettings.newBuilder().build()); when(spannerOptions.getClock()).thenReturn(NanoClock.getDefaultClock()); when(spannerOptions.getSpannerRpcV1()).thenReturn(gapicRpc); - when(spannerOptions.getSessionLabels()).thenReturn(Collections.emptyMap()); + when(spannerOptions.getSessionLabels()).thenReturn(Collections.emptyMap()); GrpcTransportOptions transportOptions = mock(GrpcTransportOptions.class); when(transportOptions.getExecutorFactory()).thenReturn(mock(ExecutorFactory.class)); when(spannerOptions.getTransportOptions()).thenReturn(transportOptions); @@ -89,8 +88,7 @@ public void testBatchReadOnlyTxnWithBound() throws Exception { com.google.protobuf.Timestamp timestamp = Timestamps.parse(TIMESTAMP); Transaction txnMetadata = Transaction.newBuilder().setId(TXN_ID).setReadTimestamp(timestamp).build(); - when(gapicRpc.beginTransaction(Mockito.any(), optionsCaptor.capture())) - .thenReturn(txnMetadata); + when(gapicRpc.beginTransaction(Mockito.any(), optionsCaptor.capture())).thenReturn(txnMetadata); BatchReadOnlyTransaction batchTxn = client.batchReadOnlyTransaction(TimestampBound.strong()); assertThat(batchTxn.getBatchTransactionId().getSessionId()).isEqualTo(SESSION_NAME); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BatchCreateSessionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BatchCreateSessionsTest.java index 7dac8c8bfed..c252bb19238 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BatchCreateSessionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BatchCreateSessionsTest.java @@ -140,7 +140,7 @@ public void testCreatedMinSessions() throws InterruptedException { public void testClosePoolWhileInitializing() throws InterruptedException { int minSessions = 10_000; int maxSessions = 10_000; - DatabaseClientImpl client = null; + DatabaseClientImpl client; // Freeze the server to prevent it from creating sessions before we want to. mockSpanner.freeze(); try (Spanner spanner = createSpanner(minSessions, maxSessions)) { @@ -175,7 +175,7 @@ public void testSpannerReturnsAllAvailableSessionsAndThenNoSessions() // After this the server will return an error when batchCreateSessions is called. // This error is not propagated to the client. int maxServerSessions = 550; - DatabaseClientImpl client = null; + DatabaseClientImpl client; mockSpanner.setMaxTotalSessions(maxServerSessions); try (Spanner spanner = createSpanner(minSessions, maxSessions)) { // Create a database client which will create a session pool. @@ -210,8 +210,8 @@ public void testSpannerReturnsAllAvailableSessionsAndThenNoSessions() public void testSpannerReturnsResourceExhausted() throws InterruptedException { int minSessions = 100; int maxSessions = 1000; - int expectedSessions = minSessions; - DatabaseClientImpl client = null; + int expectedSessions; + DatabaseClientImpl client; // Make the first BatchCreateSessions return an error. mockSpanner.addException(Status.RESOURCE_EXHAUSTED.asRuntimeException()); try (Spanner spanner = createSpanner(minSessions, maxSessions)) { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java index b7828476296..fe8fb709912 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java @@ -160,12 +160,12 @@ public void createDatabase() throws Exception { when(rpc.createDatabase( INSTANCE_NAME, "CREATE DATABASE `" + DB_ID + "`", - Collections.emptyList(), + Collections.emptyList(), new com.google.cloud.spanner.Database( DatabaseId.of(DB_NAME), State.UNSPECIFIED, client))) .thenReturn(rawOperationFuture); OperationFuture op = - client.createDatabase(INSTANCE_ID, DB_ID, Collections.emptyList()); + client.createDatabase(INSTANCE_ID, DB_ID, Collections.emptyList()); assertThat(op.isDone()).isTrue(); assertThat(op.get().getId().getName()).isEqualTo(DB_NAME); } @@ -184,13 +184,10 @@ public void createEncryptedDatabase() throws Exception { getEncryptedDatabaseProto(), CreateDatabaseMetadata.getDefaultInstance()); when(rpc.createDatabase( - INSTANCE_NAME, - "CREATE DATABASE `" + DB_ID + "`", - Collections.emptyList(), - database)) + INSTANCE_NAME, "CREATE DATABASE `" + DB_ID + "`", Collections.emptyList(), database)) .thenReturn(rawOperationFuture); OperationFuture op = - client.createDatabase(database, Collections.emptyList()); + client.createDatabase(database, Collections.emptyList()); assertThat(op.isDone()).isTrue(); assertThat(op.get().getId().getName()).isEqualTo(DB_NAME); } @@ -244,9 +241,9 @@ public void getDatabaseDdl() { public void listDatabases() { String pageToken = "token"; when(rpc.listDatabases(INSTANCE_NAME, 1, null)) - .thenReturn(new Paginated<>(ImmutableList.of(getDatabaseProto()), pageToken)); + .thenReturn(new Paginated<>(ImmutableList.of(getDatabaseProto()), pageToken)); when(rpc.listDatabases(INSTANCE_NAME, 1, pageToken)) - .thenReturn(new Paginated<>(ImmutableList.of(getAnotherDatabaseProto()), "")); + .thenReturn(new Paginated<>(ImmutableList.of(getAnotherDatabaseProto()), "")); List dbs = Lists.newArrayList(client.listDatabases(INSTANCE_ID, Options.pageSize(1)).iterateAll()); assertThat(dbs.get(0).getId().getName()).isEqualTo(DB_NAME); @@ -273,7 +270,7 @@ public void listDatabasesError() { public void listDatabaseErrorWithToken() { String pageToken = "token"; when(rpc.listDatabases(INSTANCE_NAME, 1, null)) - .thenReturn(new Paginated<>(ImmutableList.of(getDatabaseProto()), pageToken)); + .thenReturn(new Paginated<>(ImmutableList.of(getDatabaseProto()), pageToken)); when(rpc.listDatabases(INSTANCE_NAME, 1, pageToken)) .thenThrow( SpannerExceptionFactory.newSpannerException(ErrorCode.INVALID_ARGUMENT, "Test error")); @@ -469,9 +466,9 @@ public void getBackup() { public void listBackups() { String pageToken = "token"; when(rpc.listBackups(INSTANCE_NAME, 1, null, null)) - .thenReturn(new Paginated<>(ImmutableList.of(getBackupProto()), pageToken)); + .thenReturn(new Paginated<>(ImmutableList.of(getBackupProto()), pageToken)); when(rpc.listBackups(INSTANCE_NAME, 1, null, pageToken)) - .thenReturn(new Paginated<>(ImmutableList.of(getAnotherBackupProto()), "")); + .thenReturn(new Paginated<>(ImmutableList.of(getAnotherBackupProto()), "")); List backups = Lists.newArrayList(client.listBackups(INSTANCE_ID, Options.pageSize(1)).iterateAll()); assertThat(backups.get(0).getId().getName()).isEqualTo(BK_NAME); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java index 8b0f61c12ac..a417b12d94c 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java @@ -20,7 +20,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; -import com.google.api.core.ApiFunction; import com.google.api.gax.longrunning.OperationFuture; import com.google.api.gax.longrunning.OperationSnapshot; import com.google.api.gax.longrunning.OperationTimedPollAlgorithm; @@ -108,7 +107,6 @@ public static void stopServer() throws Exception { server.awaitTermination(); } - @SuppressWarnings("rawtypes") @Before public void setUp() { mockDatabaseAdmin.reset(); @@ -196,13 +194,7 @@ public void setUp() { spanner = builder .setHost("http://localhost:" + server.getPort()) - .setChannelConfigurator( - new ApiFunction() { - @Override - public ManagedChannelBuilder apply(ManagedChannelBuilder input) { - return input.usePlaintext(); - } - }) + .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) .setCredentials(NoCredentials.getInstance()) .setProjectId(PROJECT_ID) .build() @@ -589,7 +581,7 @@ public void instanceListBackupsWithFilter() .containsExactly(backupWithLargestSize); // All backups with a create time after a certain timestamp and that are also ready. ts = backup2.getProto().getCreateTime().toString(); - filter = String.format("create_time >= \"%s\" AND state:READY", ts.toString()); + filter = String.format("create_time >= \"%s\" AND state:READY", ts); mockDatabaseAdmin.addFilterMatches(filter, backup2.getId().getName()); assertThat(instance.listBackups(Options.filter(filter)).iterateAll()).containsExactly(backup2); } @@ -647,7 +639,7 @@ public void dbClientListDatabaseOperations() // + restores a database --> 2 operations. assertThat(client.listDatabaseOperations(INSTANCE_ID).iterateAll()).hasSize(3); // Create another database which should also create another operation. - client.createDatabase(INSTANCE_ID, "other-database", Collections.emptyList()).get(); + client.createDatabase(INSTANCE_ID, "other-database", Collections.emptyList()).get(); assertThat(client.listDatabaseOperations(INSTANCE_ID).iterateAll()).hasSize(4); // Restore a backup. This should create 2 database operations: One to restore the database and // one to optimize it. @@ -664,7 +656,7 @@ public void instanceListDatabaseOperations() .newInstanceBuilder(InstanceId.of(PROJECT_ID, INSTANCE_ID)) .build(); assertThat(instance.listDatabaseOperations().iterateAll()).hasSize(3); - instance.createDatabase("other-database", Collections.emptyList()).get(); + instance.createDatabase("other-database", Collections.emptyList()).get(); assertThat(instance.listDatabaseOperations().iterateAll()).hasSize(4); client .newBackupBuilder(BackupId.of(PROJECT_ID, INSTANCE_ID, BCK_ID)) @@ -709,11 +701,11 @@ public void databaseListDatabaseOperations() assertThat(database.listDatabaseOperations().iterateAll()).hasSize(1); // Create another database which should also create another operation, but for a different // database. - client.createDatabase(INSTANCE_ID, "other-database", Collections.emptyList()).get(); + client.createDatabase(INSTANCE_ID, "other-database", Collections.emptyList()).get(); assertThat(database.listDatabaseOperations().iterateAll()).hasSize(1); // Update the database DDL. This should create an operation for this database. OperationFuture op = - database.updateDdl(Arrays.asList("DROP TABLE FOO"), null); + database.updateDdl(Collections.singletonList("DROP TABLE FOO"), null); mockDatabaseAdmin.addFilterMatches("name:databases/" + DB_ID, op.getName()); assertThat(database.listDatabaseOperations().iterateAll()).hasSize(2); } @@ -808,7 +800,7 @@ public void getAndSetIAMPolicy() { public void testDatabaseIAMPermissions() { Iterable permissions = client.testDatabaseIAMPermissions( - INSTANCE_ID, DB_ID, Arrays.asList("spanner.databases.select")); + INSTANCE_ID, DB_ID, Collections.singletonList("spanner.databases.select")); assertThat(permissions).containsExactly("spanner.databases.select"); } @@ -890,7 +882,7 @@ public void retryCreateDatabaseSlowResponse() throws Exception { SimulatedExecutionTime.ofException(Status.DEADLINE_EXCEEDED.asRuntimeException())); final String databaseId = "other-database-id"; OperationFuture op = - client.createDatabase(INSTANCE_ID, databaseId, Collections.emptyList()); + client.createDatabase(INSTANCE_ID, databaseId, Collections.emptyList()); Database database = op.get(); assertThat(database.getId().getName()) .isEqualTo( @@ -908,7 +900,7 @@ public void retryCreateDatabaseSlowStartup() throws Exception { SimulatedExecutionTime.ofException(Status.DEADLINE_EXCEEDED.asRuntimeException())); final String databaseId = "other-database-id"; OperationFuture op = - client.createDatabase(INSTANCE_ID, databaseId, Collections.emptyList()); + client.createDatabase(INSTANCE_ID, databaseId, Collections.emptyList()); Database database = op.get(); assertThat(database.getId().getName()) .isEqualTo( diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminGaxTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminGaxTest.java index aaf851fb0a1..0af51744abd 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminGaxTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminGaxTest.java @@ -16,13 +16,10 @@ package com.google.cloud.spanner; -import com.google.api.core.ApiFunction; import com.google.api.gax.grpc.testing.LocalChannelProvider; import com.google.api.gax.longrunning.OperationFuture; import com.google.api.gax.paging.Page; import com.google.api.gax.retrying.RetrySettings; -import com.google.api.gax.rpc.UnaryCallSettings; -import com.google.api.gax.rpc.UnaryCallSettings.Builder; import com.google.cloud.NoCredentials; import com.google.cloud.spanner.admin.database.v1.MockDatabaseAdminImpl; import com.google.common.base.Throwables; @@ -41,8 +38,8 @@ import io.grpc.inprocess.InProcessServerBuilder; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledThreadPoolExecutor; @@ -246,12 +243,9 @@ public void setUp() throws Exception { builder .getDatabaseAdminStubSettingsBuilder() .applyToAllUnaryMethods( - new ApiFunction, Void>() { - @Override - public Void apply(Builder input) { - input.setRetrySettings(retrySettingsToUse); - return null; - } + input -> { + input.setRetrySettings(retrySettingsToUse); + return null; }); if (!builder .getDatabaseAdminStubSettingsBuilder() @@ -323,7 +317,8 @@ public void listDatabasesTest() { } for (int i = 0; i < 2; i++) { ListDatabasesResponse.Builder builder = - ListDatabasesResponse.newBuilder().addAllDatabases(Arrays.asList(databases.get(i))); + ListDatabasesResponse.newBuilder() + .addAllDatabases(Collections.singletonList(databases.get(i))); if (i < (databases.size() - 1)) { builder.setNextPageToken(String.format(nextPageToken, i)); } @@ -393,7 +388,10 @@ public void updateDatabaseDdlTest() throws Exception { for (int i = 0; i < 2; i++) { OperationFuture actualResponse = client.updateDatabaseDdl( - INSTANCE, "DATABASE", Arrays.asList("CREATE TABLE FOO"), "updateDatabaseDdlTest"); + INSTANCE, + "DATABASE", + Collections.singletonList("CREATE TABLE FOO"), + "updateDatabaseDdlTest"); try { actualResponse.get(); } catch (ExecutionException e) { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java index 10defc73d60..ed0af902a98 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java @@ -40,8 +40,6 @@ import com.google.cloud.Timestamp; import com.google.cloud.spanner.AbstractResultSet.GrpcStreamIterator; import com.google.cloud.spanner.AsyncResultSet.CallbackResponse; -import com.google.cloud.spanner.AsyncResultSet.ReadyCallback; -import com.google.cloud.spanner.AsyncTransactionManager.AsyncTransactionFunction; import com.google.cloud.spanner.AsyncTransactionManager.TransactionContextFuture; import com.google.cloud.spanner.MockSpannerServiceImpl.SimulatedExecutionTime; import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult; @@ -68,7 +66,7 @@ import io.grpc.inprocess.InProcessServerBuilder; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -177,7 +175,7 @@ public void testWrite() { spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); Timestamp timestamp = client.write( - Arrays.asList( + Collections.singletonList( Mutation.newInsertBuilder("FOO").set("ID").to(1L).set("NAME").to("Bar").build())); assertNotNull(timestamp); @@ -193,7 +191,7 @@ public void testWriteWithOptions() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); client.writeWithOptions( - Arrays.asList( + Collections.singletonList( Mutation.newInsertBuilder("FOO").set("ID").to(1L).set("NAME").to("Bar").build()), Options.priority(RpcPriority.HIGH)); @@ -210,7 +208,7 @@ public void testWriteWithCommitStats() { spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); CommitResponse response = client.writeWithOptions( - Arrays.asList( + Collections.singletonList( Mutation.newInsertBuilder("FOO").set("ID").to(1L).set("NAME").to("Bar").build()), Options.commitStats()); assertNotNull(response); @@ -224,7 +222,7 @@ public void testWriteAtLeastOnce() { spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); Timestamp timestamp = client.writeAtLeastOnce( - Arrays.asList( + Collections.singletonList( Mutation.newInsertBuilder("FOO").set("ID").to(1L).set("NAME").to("Bar").build())); assertNotNull(timestamp); } @@ -235,7 +233,7 @@ public void testWriteAtLeastOnceWithCommitStats() { spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); CommitResponse response = client.writeAtLeastOnceWithOptions( - Arrays.asList( + Collections.singletonList( Mutation.newInsertBuilder("FOO").set("ID").to(1L).set("NAME").to("Bar").build()), Options.commitStats()); assertNotNull(response); @@ -256,7 +254,7 @@ public void testWriteAtLeastOnceWithOptions() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); client.writeAtLeastOnceWithOptions( - Arrays.asList( + Collections.singletonList( Mutation.newInsertBuilder("FOO").set("ID").to(1L).set("NAME").to("Bar").build()), Options.priority(RpcPriority.LOW)); @@ -274,7 +272,7 @@ public void writeAtLeastOnceWithTagOptions() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); client.writeAtLeastOnceWithOptions( - Arrays.asList( + Collections.singletonList( Mutation.newInsertBuilder("FOO").set("ID").to(1L).set("NAME").to("Bar").build()), Options.tag("app=spanner,env=test")); @@ -414,7 +412,8 @@ public void testBatchUpdateWithTag() { runner.run( transaction -> transaction.batchUpdate( - Arrays.asList(UPDATE_STATEMENT), Options.tag("app=spanner,env=test,action=batch"))); + Collections.singletonList(UPDATE_STATEMENT), + Options.tag("app=spanner,env=test,action=batch"))); List requests = mockSpanner.getRequestsOfType(ExecuteBatchDmlRequest.class); @@ -515,13 +514,9 @@ public void testAsyncTransactionManagerCommitWithTag() { get( transaction .then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - txn.buffer(Mutation.delete("TEST", KeySet.all())); - return ApiFutures.immediateFuture(null); - } + (txn, input) -> { + txn.buffer(Mutation.delete("TEST", KeySet.all())); + return ApiFutures.immediateFuture(null); }, executor) .commitAsync()); @@ -574,19 +569,16 @@ public void singleUseAsync() throws Exception { res = rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case OK: - rowCount.incrementAndGet(); - break; - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - } + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case OK: + rowCount.incrementAndGet(); + break; + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; } } }); @@ -596,7 +588,7 @@ public CallbackResponse cursorReady(AsyncResultSet resultSet) { } @Test - public void singleUseAsyncWithoutCallback() throws Exception { + public void singleUseAsyncWithoutCallback() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); int rowCount = 0; @@ -652,19 +644,16 @@ public void singleUseBoundAsync() throws Exception { res = rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case OK: - rowCount.incrementAndGet(); - break; - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - } + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case OK: + rowCount.incrementAndGet(); + break; + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; } } }); @@ -858,7 +847,7 @@ public void testRunAsync_returnsCommitStats() { runner.runAsync( txn -> { txn.buffer(Mutation.delete("FOO", Key.of("foo"))); - return ApiFutures.immediateFuture(null); + return ApiFutures.immediateFuture(null); }, executor); assertNull(get(result)); @@ -906,7 +895,7 @@ public void runAsyncWithException() throws Exception { } @Test - public void testTransactionManager() throws Exception { + public void testTransactionManager() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); try (TransactionManager manager = client.transactionManager()) { @@ -918,14 +907,14 @@ public void testTransactionManager() throws Exception { assertNotNull(manager.getCommitTimestamp()); break; } catch (AbortedException e) { - transaction = manager.resetForRetry(); + manager.resetForRetry(); } } } } @Test - public void testTransactionManager_returnsCommitStats() throws InterruptedException { + public void testTransactionManager_returnsCommitStats() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); try (TransactionManager manager = client.transactionManager(Options.commitStats())) { @@ -939,7 +928,7 @@ public void testTransactionManager_returnsCommitStats() throws InterruptedExcept assertEquals(1L, manager.getCommitResponse().getCommitStats().getMutationCount()); break; } catch (AbortedException e) { - transaction = manager.resetForRetry(); + manager.resetForRetry(); } } } @@ -961,7 +950,7 @@ public void transactionManagerIsNonBlocking() throws Exception { break; } catch (AbortedException e) { Thread.sleep(e.getRetryDelayInMillis()); - tx = txManager.resetForRetry(); + txManager.resetForRetry(); } } } @@ -979,24 +968,21 @@ public void transactionManagerExecuteQueryAsync() throws Exception { try (AsyncResultSet rs = tx.executeQueryAsync(SELECT1)) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - while (true) { - switch (resultSet.tryNext()) { - case OK: - rowCount.incrementAndGet(); - break; - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - } + resultSet -> { + try { + while (true) { + switch (resultSet.tryNext()) { + case OK: + rowCount.incrementAndGet(); + break; + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; } - } catch (Throwable t) { - return CallbackResponse.DONE; } + } catch (Throwable t) { + return CallbackResponse.DONE; } }); } @@ -1004,7 +990,7 @@ public CallbackResponse cursorReady(AsyncResultSet resultSet) { break; } catch (AbortedException e) { Thread.sleep(e.getRetryDelayInMillis()); - tx = txManager.resetForRetry(); + txManager.resetForRetry(); } } } @@ -1373,11 +1359,13 @@ public void testDatabaseOrInstanceIsDeletedAndThenRecreated() throws Exception { while (rs.next()) {} fail("missing expected exception"); } catch (DatabaseNotFoundException | InstanceNotFoundException e) { + // Expected exception } try { dbClient.readWriteTransaction().run(transaction -> null); fail("missing expected exception"); } catch (DatabaseNotFoundException | InstanceNotFoundException e) { + // Expected exception } // Now simulate that the database has been re-created. The database client should still @@ -1390,11 +1378,13 @@ public void testDatabaseOrInstanceIsDeletedAndThenRecreated() throws Exception { while (rs.next()) {} fail("missing expected exception"); } catch (DatabaseNotFoundException | InstanceNotFoundException e) { + // Expected exception } try { dbClient.readWriteTransaction().run(transaction -> null); fail("missing expected exception"); } catch (DatabaseNotFoundException | InstanceNotFoundException e) { + // Expected exception } assertThat(mockSpanner.getRequests()).isEmpty(); // Now get a new database client. Normally multiple calls to Spanner#getDatabaseClient will @@ -1682,28 +1672,25 @@ public void testAsyncQuery() throws Exception { resultSetClosed = rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - while (true) { - switch (rs.tryNext()) { - case DONE: - finished.set(true); - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - receivedResults.add(resultSet.getCurrentRowAsStruct()); - break; - default: - throw new IllegalStateException("Unknown cursor state"); - } + asyncResultSet -> { + try { + while (true) { + switch (rs.tryNext()) { + case DONE: + finished.set(true); + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + receivedResults.add(asyncResultSet.getCurrentRowAsStruct()); + break; + default: + throw new IllegalStateException("Unknown cursor state"); } - } catch (Throwable t) { - finished.setException(t); - return CallbackResponse.DONE; } + } catch (Throwable t) { + finished.setException(t); + return CallbackResponse.DONE; } }); } @@ -1736,7 +1723,7 @@ public void testClientIdReusedOnDatabaseNotFound() { assertThat(client.clientId).isEqualTo(prevClientId); } prevClientId = client.clientId; - client.singleUse().readRow("MyTable", Key.of(0), Arrays.asList("MyColumn")); + client.singleUse().readRow("MyTable", Key.of(0), Collections.singletonList("MyColumn")); } catch (Exception e) { // ignore } @@ -2041,7 +2028,7 @@ public void testBatchUpdateWithPriority() { runner.run( transaction -> transaction.batchUpdate( - Arrays.asList(UPDATE_STATEMENT), Options.priority(RpcPriority.HIGH))); + Collections.singletonList(UPDATE_STATEMENT), Options.priority(RpcPriority.HIGH))); List requests = mockSpanner.getRequestsOfType(ExecuteBatchDmlRequest.class); @@ -2128,13 +2115,9 @@ public void testAsyncTransactionManagerCommitWithPriority() { get( transaction .then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - txn.buffer(Mutation.delete("TEST", KeySet.all())); - return ApiFutures.immediateFuture(null); - } + (txn, input) -> { + txn.buffer(Mutation.delete("TEST", KeySet.all())); + return ApiFutures.immediateFuture(null); }, executor) .commitAsync()); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseTest.java index 7b3b533874b..e29b457cc93 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseTest.java @@ -31,7 +31,6 @@ import com.google.rpc.Code; import com.google.rpc.Status; import com.google.spanner.admin.database.v1.EncryptionInfo; -import java.util.Arrays; import java.util.Collections; import java.util.List; import org.junit.Before; @@ -40,8 +39,6 @@ import org.junit.runners.JUnit4; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; /** Unit tests for {@link com.google.cloud.spanner.Database}. */ @RunWith(JUnit4.class) @@ -72,20 +69,11 @@ public void setUp() { initMocks(this); when(dbClient.newBackupBuilder(Mockito.any(BackupId.class))) .thenAnswer( - new Answer() { - @Override - public Backup.Builder answer(InvocationOnMock invocation) { - return new Backup.Builder(dbClient, (BackupId) invocation.getArguments()[0]); - } - }); + invocation -> new Backup.Builder(dbClient, (BackupId) invocation.getArguments()[0])); when(dbClient.newDatabaseBuilder(Mockito.any(DatabaseId.class))) .thenAnswer( - new Answer() { - @Override - public Database.Builder answer(InvocationOnMock invocation) throws Throwable { - return new Database.Builder(dbClient, (DatabaseId) invocation.getArguments()[0]); - } - }); + invocation -> + new Database.Builder(dbClient, (DatabaseId) invocation.getArguments()[0])); } @Test @@ -175,7 +163,7 @@ public void testIAMPermissions() { Database database = new Database( DatabaseId.of("test-project", "test-instance", "test-database"), State.READY, dbClient); - Iterable permissions = Arrays.asList("read"); + Iterable permissions = Collections.singletonList("read"); database.testIAMPermissions(permissions); verify(dbClient).testDatabaseIAMPermissions("test-instance", "test-database", permissions); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GrpcResultSetTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GrpcResultSetTest.java index 74eff109379..25c8b8dc35d 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GrpcResultSetTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GrpcResultSetTest.java @@ -38,6 +38,7 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import javax.annotation.Nullable; @@ -277,98 +278,58 @@ public void multiResponseChunkingBytes() { @Test public void multiResponseChunkingBoolArray() { - List beforeValue = Arrays.asList(true); + List beforeValue = Collections.singletonList(true); List chunkedValue = Arrays.asList(false, null, true, true, true, null, null, false); - List afterValue = Arrays.asList(true); + List afterValue = Collections.singletonList(true); doArrayTest( beforeValue, chunkedValue, afterValue, Type.bool(), - new Function, com.google.protobuf.Value>() { - @Override - public com.google.protobuf.Value apply(List input) { - return Value.boolArray(input).toProto(); - } - }, - new Function>() { - @Override - public List apply(StructReader input) { - return input.getBooleanList(0); - } - }); + input -> Value.boolArray(input).toProto(), + input -> input.getBooleanList(0)); } @Test public void multiResponseChunkingInt64Array() { - List beforeValue = Arrays.asList(10L); + List beforeValue = Collections.singletonList(10L); List chunkedValue = Arrays.asList(1L, 2L, null, null, 5L, null, 7L, 8L); - List afterValue = Arrays.asList(20L); + List afterValue = Collections.singletonList(20L); doArrayTest( beforeValue, chunkedValue, afterValue, Type.int64(), - new Function, com.google.protobuf.Value>() { - @Override - public com.google.protobuf.Value apply(List input) { - return Value.int64Array(input).toProto(); - } - }, - new Function>() { - @Override - public List apply(StructReader input) { - return input.getLongList(0); - } - }); + input -> Value.int64Array(input).toProto(), + input -> input.getLongList(0)); } @Test public void multiResponseChunkingFloat64Array() { - List beforeValue = Arrays.asList(10.0); + List beforeValue = Collections.singletonList(10.0); List chunkedValue = Arrays.asList(null, 2.0, 3.0, 4.0, null, 6.0, 7.0, null); - List afterValue = Arrays.asList(20.0); + List afterValue = Collections.singletonList(20.0); doArrayTest( beforeValue, chunkedValue, afterValue, Type.float64(), - new Function, com.google.protobuf.Value>() { - @Override - public com.google.protobuf.Value apply(List input) { - return Value.float64Array(input).toProto(); - } - }, - new Function>() { - @Override - public List apply(StructReader input) { - return input.getDoubleList(0); - } - }); + input -> Value.float64Array(input).toProto(), + input -> input.getDoubleList(0)); } @Test public void multiResponseChunkingStringArray() { - List beforeValue = Arrays.asList("before"); + List beforeValue = Collections.singletonList("before"); List chunkedValue = Arrays.asList("a", "b", null, "d", null, "f", null, "h"); - List afterValue = Arrays.asList("after"); + List afterValue = Collections.singletonList("after"); doArrayTest( beforeValue, chunkedValue, afterValue, Type.string(), - new Function, com.google.protobuf.Value>() { - @Override - public com.google.protobuf.Value apply(List input) { - return Value.stringArray(input).toProto(); - } - }, - new Function>() { - @Override - public List apply(StructReader input) { - return input.getStringList(0); - } - }); + input -> Value.stringArray(input).toProto(), + input -> input.getStringList(0)); } private static ByteArray b(String data) { @@ -377,27 +338,17 @@ private static ByteArray b(String data) { @Test public void multiResponseChunkingBytesArray() { - List beforeValue = Arrays.asList(b("before")); + List beforeValue = Collections.singletonList(b("before")); List chunkedValue = Arrays.asList(b("a"), b("b"), null, b("d"), null, b("f"), null, b("h")); - List afterValue = Arrays.asList(b("after")); + List afterValue = Collections.singletonList(b("after")); doArrayTest( beforeValue, chunkedValue, afterValue, Type.bytes(), - new Function, com.google.protobuf.Value>() { - @Override - public com.google.protobuf.Value apply(List input) { - return Value.bytesArray(input).toProto(); - } - }, - new Function>() { - @Override - public List apply(StructReader input) { - return input.getBytesList(0); - } - }); + input -> Value.bytesArray(input).toProto(), + input -> input.getBytesList(0)); } private static Struct s(String a, long b) { @@ -409,28 +360,18 @@ public void multiResponseChunkingStructArray() { final Type elementType = Type.struct( Type.StructField.of("a", Type.string()), Type.StructField.of("b", Type.int64())); - List beforeValue = Arrays.asList(s("before", 10)); + List beforeValue = Collections.singletonList(s("before", 10)); List chunkedValue = Arrays.asList( s("a", 1), s("b", 2), s("c", 3), null, s(null, 5), null, s("g", 7), s("h", 8)); - List afterValue = Arrays.asList(s("after", 20)); + List afterValue = Collections.singletonList(s("after", 20)); doArrayTest( beforeValue, chunkedValue, afterValue, elementType, - new Function, com.google.protobuf.Value>() { - @Override - public com.google.protobuf.Value apply(List input) { - return Value.structArray(elementType, input).toProto(); - } - }, - new Function>() { - @Override - public List apply(StructReader input) { - return input.getStructList(0); - } - }); + input -> Value.structArray(elementType, input).toProto(), + input -> input.getStructList(0)); } @Test @@ -606,7 +547,7 @@ public void serialization() { Value.struct(s(null, 30)), Value.struct(structType, null), Value.structArray(structType, Arrays.asList(s("def", 10), null)), - Value.structArray(structType, Arrays.asList((Struct) null)), + Value.structArray(structType, Collections.singletonList(null)), Value.structArray(structType, null)); } @@ -618,7 +559,7 @@ public void nestedStructSerialization() { Type.StructField.of("a", Type.string()), Type.StructField.of("b", Type.int64()))); Struct nestedStruct = s("1", 2L); - Value struct = Value.structArray(structType, Arrays.asList(nestedStruct)); + Value struct = Value.structArray(structType, Collections.singletonList(nestedStruct)); verifySerialization( new Function() { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InlineBeginBenchmark.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InlineBeginBenchmark.java index d8c46a2171d..1448ebbc96a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InlineBeginBenchmark.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InlineBeginBenchmark.java @@ -25,7 +25,6 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningScheduledExecutorService; import com.google.common.util.concurrent.MoreExecutors; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Random; @@ -123,7 +122,7 @@ SpannerOptions createBenchmarkServerOptions(TransportChannelProvider channelProv .build(); } - SpannerOptions createRealServerOptions() throws IOException { + SpannerOptions createRealServerOptions() { return SpannerOptions.newBuilder() .setSessionPoolOption( SessionPoolOptions.newBuilder().setWriteSessionsFraction(writeFraction).build()) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InlineBeginTransactionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InlineBeginTransactionTest.java index fb18f317251..6ee90f4e475 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InlineBeginTransactionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InlineBeginTransactionTest.java @@ -20,15 +20,12 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -import com.google.api.core.ApiAsyncFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.SettableApiFuture; import com.google.api.gax.grpc.testing.LocalChannelProvider; import com.google.cloud.NoCredentials; import com.google.cloud.spanner.AsyncResultSet.CallbackResponse; -import com.google.cloud.spanner.AsyncResultSet.ReadyCallback; -import com.google.cloud.spanner.AsyncTransactionManager.AsyncTransactionFunction; import com.google.cloud.spanner.AsyncTransactionManager.AsyncTransactionStep; import com.google.cloud.spanner.AsyncTransactionManager.CommitTimestampFuture; import com.google.cloud.spanner.AsyncTransactionManager.TransactionContextFuture; @@ -58,6 +55,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; @@ -66,7 +64,6 @@ import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.After; import org.junit.AfterClass; @@ -175,7 +172,7 @@ public static void stopServer() throws InterruptedException { } @Before - public void setUp() throws IOException { + public void setUp() { mockSpanner.reset(); mockSpanner.removeAllExecutionTimes(); // Create a Spanner instance that will inline BeginTransaction calls. It also has no prepared @@ -191,7 +188,7 @@ public void setUp() throws IOException { } @After - public void tearDown() throws Exception { + public void tearDown() { spanner.close(); mockSpanner.reset(); mockSpanner.clearRequests(); @@ -259,19 +256,16 @@ public void testInlinedBeginAsyncTxWithQuery() throws InterruptedException, Exec try (AsyncResultSet rs = txn.executeQueryAsync(SELECT1)) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - res.set(resultSet.getLong(0)); - default: - throw new IllegalStateException(); - } + resultSet -> { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + res.set(resultSet.getLong(0)); + default: + throw new IllegalStateException(); } }); } @@ -354,13 +348,7 @@ public void testAsyncTransactionManagerInlinedBeginTx() while (true) { AsyncTransactionStep updateCount = txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - return txn.executeUpdateAsync(UPDATE_STATEMENT); - } - }, + (transaction, ignored) -> transaction.executeUpdateAsync(UPDATE_STATEMENT), executor); CommitTimestampFuture commitTimestamp = updateCount.commitAsync(); try { @@ -388,25 +376,15 @@ public void testAsyncTransactionManagerInlinedBeginTxAborted() try { AsyncTransactionStep updateCount = txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - return txn.executeUpdateAsync(UPDATE_STATEMENT); - } - }, + (transaction, ignored) -> transaction.executeUpdateAsync(UPDATE_STATEMENT), executor); if (first) { // Abort the transaction after the statement has been executed to ensure that the // transaction has actually been started before the test tries to abort it. updateCount.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Long input) - throws Exception { - mockSpanner.abortAllTransactions(); - return ApiFutures.immediateFuture(null); - } + (ignored1, ignored2) -> { + mockSpanner.abortAllTransactions(); + return ApiFutures.immediateFuture(null); }, MoreExecutors.directExecutor()); first = false; @@ -434,13 +412,9 @@ public void testAsyncTransactionManagerInlinedBeginTxWithOnlyMutations() while (true) { try { txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - txn.buffer(Mutation.newInsertBuilder("FOO").set("ID").to(1L).build()); - return ApiFutures.immediateFuture(null); - } + (transaction, ignored) -> { + transaction.buffer(Mutation.newInsertBuilder("FOO").set("ID").to(1L).build()); + return ApiFutures.immediateFuture(null); }, executor) .commitAsync() @@ -457,8 +431,7 @@ public ApiFuture apply(TransactionContext txn, Void input) } @Test - public void testAsyncTransactionManagerInlinedBeginTxWithError() - throws InterruptedException, ExecutionException { + public void testAsyncTransactionManagerInlinedBeginTxWithError() throws InterruptedException { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); try (AsyncTransactionManager txMgr = client.transactionManagerAsync()) { @@ -467,22 +440,11 @@ public void testAsyncTransactionManagerInlinedBeginTxWithError() try { AsyncTransactionStep updateCount = txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - return txn.executeUpdateAsync(INVALID_UPDATE_STATEMENT); - } - }, + (transaction, ignored) -> + transaction.executeUpdateAsync(INVALID_UPDATE_STATEMENT), executor) .then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Long input) - throws Exception { - return txn.executeUpdateAsync(UPDATE_STATEMENT); - } - }, + (transaction, ignored) -> transaction.executeUpdateAsync(UPDATE_STATEMENT), executor); try { updateCount.commitAsync().get(); @@ -555,7 +517,7 @@ public void testInlinedBeginFirstUpdateAborts() { boolean firstAttempt = true; @Override - public Long run(TransactionContext transaction) throws Exception { + public Long run(TransactionContext transaction) { if (firstAttempt) { firstAttempt = false; mockSpanner.putStatementResult( @@ -587,7 +549,7 @@ public void testInlinedBeginFirstQueryAborts() { boolean firstAttempt = true; @Override - public Long run(TransactionContext transaction) throws Exception { + public Long run(TransactionContext transaction) { if (firstAttempt) { firstAttempt = false; mockSpanner.putStatementResult( @@ -649,7 +611,7 @@ public void testInlinedBeginFirstReadReturnsUnavailable() { transaction -> { // The first attempt will return UNAVAILABLE and retry internally. try (ResultSet rs = - transaction.read("FOO", KeySet.all(), Arrays.asList("ID"))) { + transaction.read("FOO", KeySet.all(), Collections.singletonList("ID"))) { while (rs.next()) { return rs.getLong(0); } @@ -694,7 +656,7 @@ public void testInlinedBeginTxWithRead() { .run( transaction -> { try (ResultSet rs = - transaction.read("FOO", KeySet.all(), Arrays.asList("ID"))) { + transaction.read("FOO", KeySet.all(), Collections.singletonList("ID"))) { while (rs.next()) { return rs.getLong(0); } @@ -1169,19 +1131,16 @@ public void testInlinedBeginAsyncTxWithParallelQueries() try (AsyncResultSet rs = txn.executeQueryAsync(SELECT1)) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - res.set(resultSet.getLong(0)); - default: - throw new IllegalStateException(); - } + resultSet -> { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + res.set(resultSet.getLong(0)); + default: + throw new IllegalStateException(); } }); } @@ -1189,15 +1148,12 @@ public CallbackResponse cursorReady(AsyncResultSet resultSet) { } return ApiFutures.transformAsync( ApiFutures.allAsList(futures), - new ApiAsyncFunction, Long>() { - @Override - public ApiFuture apply(List input) throws Exception { - long sum = 0L; - for (Long l : input) { - sum += l; - } - return ApiFutures.immediateFuture(sum); + input -> { + long sum = 0L; + for (Long l : input) { + sum += l; } + return ApiFutures.immediateFuture(sum); }, MoreExecutors.directExecutor()); }, @@ -1251,7 +1207,7 @@ public void readWithoutNext() { .readWriteTransaction() .run( transaction -> { - transaction.read("FOO", KeySet.all(), Arrays.asList("ID")); + transaction.read("FOO", KeySet.all(), Collections.singletonList("ID")); return transaction.executeUpdate(UPDATE_STATEMENT); })) .isEqualTo(UPDATE_COUNT); @@ -1269,7 +1225,7 @@ public void readAsyncWithoutCallback() { .readWriteTransaction() .run( transaction -> { - transaction.readAsync("FOO", KeySet.all(), Arrays.asList("ID")); + transaction.readAsync("FOO", KeySet.all(), Collections.singletonList("ID")); return transaction.executeUpdate(UPDATE_STATEMENT); })) .isEqualTo(UPDATE_COUNT); @@ -1280,8 +1236,7 @@ public void readAsyncWithoutCallback() { } @Test - public void query_ThenUpdate_ThenConsumeResultSet() - throws InterruptedException, TimeoutException { + public void query_ThenUpdate_ThenConsumeResultSet() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("p", "i", "d")); assertThat( client @@ -1303,10 +1258,9 @@ public void query_ThenUpdate_ThenConsumeResultSet() assertThat(countTransactionsStarted()).isEqualTo(1); List requests = mockSpanner.getRequestsOfType(ExecuteSqlRequest.class); assertThat(requests.get(0)).isInstanceOf(ExecuteSqlRequest.class); - assertThat(((ExecuteSqlRequest) requests.get(0)).getSql()) - .isEqualTo(UPDATE_STATEMENT.getSql()); + assertThat(requests.get(0).getSql()).isEqualTo(UPDATE_STATEMENT.getSql()); assertThat(requests.get(1)).isInstanceOf(ExecuteSqlRequest.class); - assertThat(((ExecuteSqlRequest) requests.get(1)).getSql()).isEqualTo(SELECT1.getSql()); + assertThat(requests.get(1).getSql()).isEqualTo(SELECT1.getSql()); } @Test @@ -1331,14 +1285,14 @@ public void testInlinedBeginTxWithStreamRetry() { List requests = mockSpanner.getRequestsOfType(ExecuteSqlRequest.class); assertThat(requests.get(0)).isInstanceOf(ExecuteSqlRequest.class); - ExecuteSqlRequest request1 = (ExecuteSqlRequest) requests.get(0); + ExecuteSqlRequest request1 = requests.get(0); assertThat(request1.getSql()).isEqualTo(SELECT1_UNION_ALL_SELECT2.getSql()); assertThat(request1.getTransaction().getBegin().hasReadWrite()).isTrue(); assertThat(request1.getTransaction().getId()).isEqualTo(ByteString.EMPTY); assertThat(request1.getResumeToken()).isEqualTo(ByteString.EMPTY); assertThat(requests.get(1)).isInstanceOf(ExecuteSqlRequest.class); - ExecuteSqlRequest request2 = (ExecuteSqlRequest) requests.get(1); + ExecuteSqlRequest request2 = requests.get(1); assertThat(request2.getSql()).isEqualTo(SELECT1_UNION_ALL_SELECT2.getSql()); assertThat(request2.getTransaction().hasBegin()).isFalse(); assertThat(request2.getTransaction().getId()).isNotEqualTo(ByteString.EMPTY); @@ -1355,7 +1309,7 @@ public void testWaitForTransactionTimeout() { int attempt = 0; @Override - public Void run(TransactionContext transaction) throws Exception { + public Void run(TransactionContext transaction) { attempt++; TransactionContextImpl impl = (TransactionContextImpl) transaction; if (attempt == 1) { @@ -1426,7 +1380,7 @@ public void testReadWithInlineBeginDidNotReturnTransaction() { .readWriteTransaction() .run( transaction -> { - transaction.readRow("FOO", Key.of(1L), Arrays.asList("BAR")); + transaction.readRow("FOO", Key.of(1L), Collections.singletonList("BAR")); return null; }); fail("missing expected exception"); @@ -1474,7 +1428,7 @@ public void testBatchUpdateWithInlineBeginDidNotReturnTransaction() { .readWriteTransaction() .run( transaction -> { - transaction.batchUpdate(Arrays.asList(UPDATE_STATEMENT)); + transaction.batchUpdate(Collections.singletonList(UPDATE_STATEMENT)); return null; }); fail("missing expected exception"); @@ -1504,23 +1458,20 @@ public void testQueryAsyncWithInlineBeginDidNotReturnTransaction() { return SpannerApiFutures.get( rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - while (true) { - switch (resultSet.tryNext()) { - case OK: - break; - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - } + resultSet -> { + try { + while (true) { + switch (resultSet.tryNext()) { + case OK: + break; + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; } - } catch (SpannerException e) { - return CallbackResponse.DONE; } + } catch (SpannerException e) { + return CallbackResponse.DONE; } })); } @@ -1569,7 +1520,7 @@ public void testBatchUpdateAsyncWithInlineBeginDidNotReturnTransaction() { .run( transaction -> SpannerApiFutures.get( - transaction.batchUpdateAsync(Arrays.asList(UPDATE_STATEMENT)))); + transaction.batchUpdateAsync(Collections.singletonList(UPDATE_STATEMENT)))); fail("missing expected exception"); } catch (SpannerException e) { assertThat(e.getErrorCode()).isEqualTo(ErrorCode.FAILED_PRECONDITION); @@ -1601,7 +1552,7 @@ public void testInlinedBeginTx_withCancelledOnFirstStatement() { int attempt = 0; @Override - public Long run(TransactionContext transaction) throws Exception { + public Long run(TransactionContext transaction) { if (attempt > 0) { mockSpanner.putStatementResult(StatementResult.update(statement, 1L)); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceAdminClientTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceAdminClientTest.java index aaae750e70b..1f62b8d5924 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceAdminClientTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceAdminClientTest.java @@ -19,13 +19,12 @@ import static com.google.common.truth.Truth.assertThat; import com.google.api.gax.grpc.testing.LocalChannelProvider; -import com.google.api.gax.grpc.testing.MockGrpcService; import com.google.api.gax.grpc.testing.MockServiceHelper; import com.google.cloud.Identity; import com.google.cloud.NoCredentials; import com.google.cloud.Policy; import com.google.cloud.Role; -import java.util.Arrays; +import java.util.Collections; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; @@ -49,7 +48,7 @@ public class InstanceAdminClientTest { public static void startStaticServer() { mockInstanceAdmin = new MockInstanceAdminServiceImpl(); serviceHelper = - new MockServiceHelper("in-process-1", Arrays.asList(mockInstanceAdmin)); + new MockServiceHelper("in-process-1", Collections.singletonList(mockInstanceAdmin)); serviceHelper.start(); } @@ -91,7 +90,8 @@ public void getAndSetIAMPolicy() { @Test public void testIAMPermissions() { Iterable permissions = - client.testInstanceIAMPermissions(INSTANCE_ID, Arrays.asList("spanner.instances.list")); + client.testInstanceIAMPermissions( + INSTANCE_ID, Collections.singletonList("spanner.instances.list")); assertThat(permissions).containsExactly("spanner.instances.list"); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceAdminGaxTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceAdminGaxTest.java index 8077b4b06e8..6edb9fffde9 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceAdminGaxTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceAdminGaxTest.java @@ -18,13 +18,10 @@ import static org.junit.Assert.fail; -import com.google.api.core.ApiFunction; import com.google.api.gax.grpc.testing.LocalChannelProvider; import com.google.api.gax.longrunning.OperationFuture; import com.google.api.gax.paging.Page; import com.google.api.gax.retrying.RetrySettings; -import com.google.api.gax.rpc.UnaryCallSettings; -import com.google.api.gax.rpc.UnaryCallSettings.Builder; import com.google.cloud.NoCredentials; import com.google.cloud.spanner.admin.instance.v1.MockInstanceAdminImpl; import com.google.common.base.Throwables; @@ -48,8 +45,8 @@ import io.grpc.inprocess.InProcessServerBuilder; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledThreadPoolExecutor; @@ -253,12 +250,9 @@ public void setUp() throws Exception { builder .getInstanceAdminStubSettingsBuilder() .applyToAllUnaryMethods( - new ApiFunction, Void>() { - @Override - public Void apply(Builder input) { - input.setRetrySettings(retrySettingsToUse); - return null; - } + input -> { + input.setRetrySettings(retrySettingsToUse); + return null; }); if (!builder .getInstanceAdminStubSettingsBuilder() @@ -331,7 +325,7 @@ public void listInstanceConfigsTest() { for (int i = 0; i < 2; i++) { ListInstanceConfigsResponse.Builder builder = ListInstanceConfigsResponse.newBuilder() - .addAllInstanceConfigs(Arrays.asList(configs.get(i))); + .addAllInstanceConfigs(Collections.singletonList(configs.get(i))); if (i < (configs.size() - 1)) { builder.setNextPageToken(String.format(nextPageToken, i)); } @@ -397,7 +391,8 @@ public void listInstancesTest() { } for (int i = 0; i < 2; i++) { ListInstancesResponse.Builder builder = - ListInstancesResponse.newBuilder().addAllInstances(Arrays.asList(instances.get(i))); + ListInstancesResponse.newBuilder() + .addAllInstances(Collections.singletonList(instances.get(i))); if (i < (instances.size() - 1)) { builder.setNextPageToken(String.format(nextPageToken, i)); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceTest.java index 90f0b7630f5..86c39f59baa 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceTest.java @@ -24,7 +24,7 @@ import com.google.cloud.Policy; import com.google.cloud.Role; import com.google.common.testing.EqualsTester; -import java.util.Arrays; +import java.util.Collections; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -163,7 +163,7 @@ public void setIAMPolicy() { public void testIAMPermissions() { InstanceId id = new InstanceId("test-project", "test-instance"); Instance instance = new Instance.Builder(instanceClient, dbClient, id).build(); - Iterable permissions = Arrays.asList("read"); + Iterable permissions = Collections.singletonList("read"); instance.testIAMPermissions(permissions); verify(instanceClient).testInstanceIAMPermissions("test-instance", permissions); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IntegrationTestWithClosedSessionsEnv.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IntegrationTestWithClosedSessionsEnv.java index 84c7185e1f1..0fa5ff27d82 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IntegrationTestWithClosedSessionsEnv.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IntegrationTestWithClosedSessionsEnv.java @@ -34,8 +34,7 @@ private RemoteSpannerHelperWithClosedSessions( } @Override - RemoteSpannerHelper createTestHelper(SpannerOptions options, InstanceId instanceId) - throws Throwable { + RemoteSpannerHelper createTestHelper(SpannerOptions options, InstanceId instanceId) { SpannerWithClosedSessionsImpl spanner = new SpannerWithClosedSessionsImpl(options); return new RemoteSpannerHelperWithClosedSessions(options, instanceId, spanner); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IsRetryableInternalErrorTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IsRetryableInternalErrorTest.java index 0f76da6692f..e1c360da74f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IsRetryableInternalErrorTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IsRetryableInternalErrorTest.java @@ -29,7 +29,6 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -@SuppressWarnings("unchecked") @RunWith(JUnit4.class) public class IsRetryableInternalErrorTest { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IsSslHandshakeExceptionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IsSslHandshakeExceptionTest.java index b73c2d6ef1b..5dd52352c2e 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IsSslHandshakeExceptionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/IsSslHandshakeExceptionTest.java @@ -25,7 +25,6 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -@SuppressWarnings("unchecked") @RunWith(JUnit4.class) public class IsSslHandshakeExceptionTest { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MetricRegistryTestUtils.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MetricRegistryTestUtils.java index 546d0c55db4..1bedda47e5f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MetricRegistryTestUtils.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MetricRegistryTestUtils.java @@ -95,7 +95,7 @@ public void createTimeSeries( this.record .metrics .get(this.name) - .add(new PointWithFunction(t, toLongFunction, labelKeys, labelValues)); + .add(new PointWithFunction<>(t, toLongFunction, labelKeys, labelValues)); } @Override @@ -126,7 +126,7 @@ public void createTimeSeries( this.record .metrics .get(this.name) - .add(new PointWithFunction(t, toLongFunction, labelKeys, labelValues)); + .add(new PointWithFunction<>(t, toLongFunction, labelKeys, labelValues)); } @Override diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockDatabaseAdminServiceImpl.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockDatabaseAdminServiceImpl.java index 8977002afc4..20a39f318f9 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockDatabaseAdminServiceImpl.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockDatabaseAdminServiceImpl.java @@ -18,7 +18,6 @@ import com.google.api.gax.grpc.testing.MockGrpcService; import com.google.cloud.spanner.MockSpannerServiceImpl.SimulatedExecutionTime; -import com.google.common.base.Predicate; import com.google.common.base.Strings; import com.google.common.collect.Collections2; import com.google.iam.v1.GetIamPolicyRequest; @@ -914,15 +913,7 @@ public List getRequests() { } public int countRequestsOfType(final Class type) { - return Collections2.filter( - getRequests(), - new Predicate() { - @Override - public boolean apply(AbstractMessage input) { - return input.getClass().equals(type); - } - }) - .size(); + return Collections2.filter(getRequests(), input -> input.getClass().equals(type)).size(); } @Override diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockDatabaseAdminServiceImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockDatabaseAdminServiceImplTest.java index c73b79d6e61..9c9f0e7f91a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockDatabaseAdminServiceImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockDatabaseAdminServiceImplTest.java @@ -21,7 +21,6 @@ import com.google.api.gax.core.NoCredentialsProvider; import com.google.api.gax.grpc.testing.LocalChannelProvider; -import com.google.api.gax.grpc.testing.MockGrpcService; import com.google.api.gax.grpc.testing.MockServiceHelper; import com.google.api.gax.longrunning.OperationFuture; import com.google.api.gax.longrunning.OperationTimedPollAlgorithm; @@ -129,8 +128,7 @@ public static void startStaticServer() { mockOperations = new MockOperationsServiceImpl(); mockDatabaseAdmin = new MockDatabaseAdminServiceImpl(mockOperations); serviceHelper = - new MockServiceHelper( - "in-process-1", Arrays.asList(mockOperations, mockDatabaseAdmin)); + new MockServiceHelper("in-process-1", Arrays.asList(mockOperations, mockDatabaseAdmin)); serviceHelper.start(); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockSpannerServiceImpl.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockSpannerServiceImpl.java index 1a7e6b2364d..39fe74566a2 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockSpannerServiceImpl.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockSpannerServiceImpl.java @@ -432,17 +432,17 @@ public static SimulatedExecutionTime none() { public static SimulatedExecutionTime ofException(Exception exception) { return new SimulatedExecutionTime( - 0, 0, Arrays.asList(exception), false, Collections.emptySet()); + 0, 0, Collections.singletonList(exception), false, Collections.emptySet()); } public static SimulatedExecutionTime ofStickyException(Exception exception) { return new SimulatedExecutionTime( - 0, 0, Arrays.asList(exception), true, Collections.emptySet()); + 0, 0, Collections.singletonList(exception), true, Collections.emptySet()); } public static SimulatedExecutionTime ofStreamException(Exception exception, long streamIndex) { return new SimulatedExecutionTime( - 0, 0, Arrays.asList(exception), false, Collections.singleton(streamIndex)); + 0, 0, Collections.singletonList(exception), false, Collections.singleton(streamIndex)); } public static SimulatedExecutionTime stickyDatabaseNotFoundException(String name) { @@ -451,7 +451,7 @@ public static SimulatedExecutionTime stickyDatabaseNotFoundException(String name } public static SimulatedExecutionTime ofExceptions(Collection exceptions) { - return new SimulatedExecutionTime(0, 0, exceptions, false, Collections.emptySet()); + return new SimulatedExecutionTime(0, 0, exceptions, false, Collections.emptySet()); } public static SimulatedExecutionTime ofMinimumAndRandomTimeAndExceptions( @@ -459,16 +459,11 @@ public static SimulatedExecutionTime ofMinimumAndRandomTimeAndExceptions( int randomExecutionTime, Collection exceptions) { return new SimulatedExecutionTime( - minimumExecutionTime, - randomExecutionTime, - exceptions, - false, - Collections.emptySet()); + minimumExecutionTime, randomExecutionTime, exceptions, false, Collections.emptySet()); } private SimulatedExecutionTime(int minimum, int random) { - this( - minimum, random, Collections.emptyList(), false, Collections.emptySet()); + this(minimum, random, Collections.emptyList(), false, Collections.emptySet()); } private SimulatedExecutionTime( @@ -880,14 +875,7 @@ public void listSessions( session.toBuilder().setApproximateLastUseTime(getCurrentGoogleTimestamp()).build()); } } - Collections.sort( - res, - new Comparator() { - @Override - public int compare(Session o1, Session o2) { - return o1.getName().compareTo(o2.getName()); - } - }); + res.sort(Comparator.comparing(Session::getName)); responseObserver.onNext(ListSessionsResponse.newBuilder().addAllSessions(res).build()); responseObserver.onCompleted(); } catch (StatusRuntimeException e) { @@ -1420,13 +1408,7 @@ public void read(final ReadRequest request, StreamObserver responseOb // Get or start transaction ByteString transactionId = getTransactionId(session, request.getTransaction()); simulateAbort(session, transactionId); - Iterable cols = - new Iterable() { - @Override - public Iterator iterator() { - return request.getColumnsList().iterator(); - } - }; + Iterable cols = () -> request.getColumnsList().iterator(); Statement statement = StatementResult.createReadStatement( request.getTable(), @@ -1472,13 +1454,7 @@ public void streamingRead( } } simulateAbort(session, transactionId); - Iterable cols = - new Iterable() { - @Override - public Iterator iterator() { - return request.getColumnsList().iterator(); - } - }; + Iterable cols = () -> request.getColumnsList().iterator(); Statement statement = StatementResult.createReadStatement( request.getTable(), diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OperationFutureUtil.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OperationFutureUtil.java index 43471b5b700..b04d24413cb 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OperationFutureUtil.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OperationFutureUtil.java @@ -29,7 +29,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; // TODO(hzyi): add a public FakeOperationSnapshot in gax to support testing class OperationFutureUtil { @@ -79,7 +78,7 @@ public static FakeStatusCode of(Code code) { } } - public static final + public static OperationSnapshot completedSnapshot( final String name, final ResponseT response, final MetadataT metadata) { return new OperationSnapshot() { @@ -131,8 +130,7 @@ public void addListener(Runnable runnable, Executor executor) { } @Override - public V get(long time, TimeUnit unit) - throws ExecutionException, InterruptedException, TimeoutException { + public V get(long time, TimeUnit unit) throws ExecutionException, InterruptedException { return get(); } @@ -182,12 +180,12 @@ public ApiFuture peekAttemptResult() { } } - public static final RetryingFuture immediateRetryingFuture( + public static RetryingFuture immediateRetryingFuture( final ResponseT response) { - return new ImmediateRetryingFuture(response); + return new ImmediateRetryingFuture<>(response); } - public static final + public static OperationFuture immediateOperationFuture( final String name, final ResponseT response, final MetadataT metadata) { return immediateOperationFuture(completedSnapshot(name, response, metadata)); @@ -201,7 +199,7 @@ OperationFuture immediateOperationFuture( * respectively. */ @SuppressWarnings("unchecked") - public static final + public static OperationFuture immediateOperationFuture( final OperationSnapshot completedSnapshot) { @@ -247,7 +245,7 @@ public void addListener(Runnable runnable, Executor executor) { @Override public ResponseT get(long time, TimeUnit unit) - throws ExecutionException, InterruptedException, TimeoutException { + throws ExecutionException, InterruptedException { return get(); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/PartitionedDmlTransactionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/PartitionedDmlTransactionTest.java index a909fbd5706..b192ef77b50 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/PartitionedDmlTransactionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/PartitionedDmlTransactionTest.java @@ -288,7 +288,7 @@ public void testExecuteStreamingPartitionedUpdateMultipleAbortsUntilDeadlineExce long ticks = 0L; @Override - public Long answer(InvocationOnMock invocation) throws Throwable { + public Long answer(InvocationOnMock invocation) { return TimeUnit.NANOSECONDS.convert(++ticks, TimeUnit.MINUTES); } }); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/RandomResultSetGenerator.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/RandomResultSetGenerator.java index fc4f999796b..b5bbb9dd49a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/RandomResultSetGenerator.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/RandomResultSetGenerator.java @@ -71,7 +71,7 @@ public class RandomResultSetGenerator { .build(), }; - private static final ResultSetMetadata generateMetadata() { + private static ResultSetMetadata generateMetadata() { StructType.Builder rowTypeBuilder = StructType.newBuilder(); for (int col = 0; col < TYPES.length; col++) { rowTypeBuilder.addFields(Field.newBuilder().setName("COL" + col).setType(TYPES[col])).build(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadAsyncTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadAsyncTest.java index 1d9c37d11bb..77a2b2fc549 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadAsyncTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadAsyncTest.java @@ -20,17 +20,14 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.SettableApiFuture; import com.google.api.gax.grpc.testing.LocalChannelProvider; import com.google.cloud.NoCredentials; import com.google.cloud.spanner.AsyncResultSet.CallbackResponse; -import com.google.cloud.spanner.AsyncResultSet.ReadyCallback; import com.google.cloud.spanner.MockSpannerServiceImpl.SimulatedExecutionTime; import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult; -import com.google.common.base.Function; import com.google.common.collect.ContiguousSet; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; @@ -128,12 +125,9 @@ public void readAsyncPropagatesError() throws Exception { result = resultSet.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.CANCELLED, "Don't want the data"); - } + ignored -> { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.CANCELLED, "Don't want the data"); }); } try { @@ -157,19 +151,16 @@ public void emptyReadAsync() throws Exception { result = resultSet.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case OK: - fail("received unexpected data"); - case NOT_READY: - return CallbackResponse.CONTINUE; - case DONE: - assertThat(resultSet.getType()).isEqualTo(READ_TABLE_TYPE); - return CallbackResponse.DONE; - } + rs -> { + while (true) { + switch (rs.tryNext()) { + case OK: + fail("received unexpected data"); + case NOT_READY: + return CallbackResponse.CONTINUE; + case DONE: + assertThat(rs.getType()).isEqualTo(READ_TABLE_TYPE); + return CallbackResponse.DONE; } } }); @@ -260,26 +251,23 @@ public void closeTransactionBeforeEndOfAsyncQuery() throws Exception { closed = rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - finished.set(true); - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - dataReceived.countDown(); - results.put(resultSet.getString(0)); - } + resultSet -> { + try { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + finished.set(true); + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + dataReceived.countDown(); + results.put(resultSet.getString(0)); } - } catch (Throwable t) { - finished.setException(t); - return CallbackResponse.DONE; } + } catch (Throwable t) { + finished.setException(t); + return CallbackResponse.DONE; } }); } @@ -320,46 +308,20 @@ public void readOnlyTransaction() throws Exception { ApiFuture> values2; try (ReadOnlyTransaction tx = client.readOnlyTransaction()) { try (AsyncResultSet rs = tx.executeQueryAsync(statement1)) { - values1 = - rs.toListAsync( - new Function() { - @Override - public String apply(StructReader input) { - return input.getString("Value"); - } - }, - executor); + values1 = rs.toListAsync(input -> input.getString("Value"), executor); } try (AsyncResultSet rs = tx.executeQueryAsync(statement2)) { - values2 = - rs.toListAsync( - new Function() { - @Override - public String apply(StructReader input) { - return input.getString("Value"); - } - }, - executor); + values2 = rs.toListAsync(input -> input.getString("Value"), executor); } } ApiFuture> allValues = ApiFutures.transform( ApiFutures.allAsList(Arrays.asList(values1, values2)), - new ApiFunction>, Iterable>() { - @Override - public Iterable apply(List> input) { - return Iterables.mergeSorted( + input -> + Iterables.mergeSorted( input, - new Comparator() { - @Override - public int compare(String o1, String o2) { - // Return in numerical order (i.e. without the preceding 'v'). - return Integer.valueOf(o1.substring(1)) - .compareTo(Integer.valueOf(o2.substring(1))); - } - }); - } - }, + // Return in numerical order (i.e. without the preceding 'v'). + Comparator.comparing(o -> Integer.valueOf(o.substring(1)))), executor); assertThat(allValues.get()).containsExactly("v1", "v2", "v3", "v10", "v11", "v12"); } @@ -388,9 +350,30 @@ public void pauseResume() throws Exception { unevenFinished = unevenRs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + synchronized (lock) { + allValues.add(resultSet.getString("Value")); + } + unevenReturnedFirstRow.countDown(); + return CallbackResponse.PAUSE; + } + } + }); + evenFinished = + evenRs.setCallback( + executor, + resultSet -> { + try { + // Make sure the uneven result set has returned the first before we start the + // even results. + unevenReturnedFirstRow.await(); while (true) { switch (resultSet.tryNext()) { case DONE: @@ -401,39 +384,11 @@ public CallbackResponse cursorReady(AsyncResultSet resultSet) { synchronized (lock) { allValues.add(resultSet.getString("Value")); } - unevenReturnedFirstRow.countDown(); return CallbackResponse.PAUSE; } } - } - }); - evenFinished = - evenRs.setCallback( - executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - // Make sure the uneven result set has returned the first before we start the - // even - // results. - unevenReturnedFirstRow.await(); - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - synchronized (lock) { - allValues.add(resultSet.getString("Value")); - } - return CallbackResponse.PAUSE; - } - } - } catch (InterruptedException e) { - throw SpannerExceptionFactory.propagateInterrupt(e); - } + } catch (InterruptedException e) { + throw SpannerExceptionFactory.propagateInterrupt(e); } }); while (!(evenFinished.isDone() && unevenFinished.isDone())) { @@ -470,26 +425,23 @@ public void cancel() throws Exception { res = rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - values.add(resultSet.getString("Value")); - receivedFirstRow.countDown(); - cancelled.await(); - break; - } + resultSet -> { + try { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + values.add(resultSet.getString("Value")); + receivedFirstRow.countDown(); + cancelled.await(); + break; } - } catch (Throwable t) { - return CallbackResponse.DONE; } + } catch (Throwable t) { + return CallbackResponse.DONE; } }); receivedFirstRow.await(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadFormatTestRunner.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadFormatTestRunner.java index 05c79f1a33e..8d939712296 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadFormatTestRunner.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadFormatTestRunner.java @@ -101,7 +101,7 @@ protected List getChildren() { } } - private class TestCaseRunner { + private static class TestCaseRunner { private AbstractResultSet.GrpcResultSet resultSet; private SpannerRpc.ResultStreamConsumer consumer; private AbstractResultSet.GrpcStreamIterator stream; @@ -181,7 +181,7 @@ private void assertRow(Struct actualRow, JSONArray expectedRow) throws Exception } } - private List getRawList(Struct actualRow, int index, Type elementType) throws Exception { + private List getRawList(Struct actualRow, int index, Type elementType) { List rawList = null; switch (elementType.getCode()) { case BOOL: diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadWriteTransactionWithInlineBeginTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadWriteTransactionWithInlineBeginTest.java index 36c92b4495b..28f6566dab8 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadWriteTransactionWithInlineBeginTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadWriteTransactionWithInlineBeginTest.java @@ -120,7 +120,7 @@ public static void stopServer() throws InterruptedException { } @Before - public void setUp() throws IOException { + public void setUp() { mockSpanner.reset(); mockSpanner.removeAllExecutionTimes(); spanner = @@ -134,7 +134,7 @@ public void setUp() throws IOException { } @After - public void tearDown() throws Exception { + public void tearDown() { spanner.close(); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResultSetsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResultSetsTest.java index 84a3793bfd6..dcf2f895553 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResultSetsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResultSetsTest.java @@ -27,7 +27,6 @@ import com.google.cloud.Date; import com.google.cloud.Timestamp; import com.google.cloud.spanner.AsyncResultSet.CallbackResponse; -import com.google.cloud.spanner.AsyncResultSet.ReadyCallback; import com.google.common.primitives.Booleans; import com.google.common.primitives.Doubles; import com.google.common.primitives.Longs; @@ -376,7 +375,7 @@ public void closeResultSet() { ResultSet rs = ResultSets.forRows( Type.struct(Type.StructField.of("f1", Type.string())), - Arrays.asList(Struct.newBuilder().set("f1").to("x").build())); + Collections.singletonList(Struct.newBuilder().set("f1").to("x").build())); rs.close(); try { rs.getCurrentRowAsStruct(); @@ -391,7 +390,7 @@ public void exceptionIfNextIsNotCalled() { ResultSet rs = ResultSets.forRows( Type.struct(Type.StructField.of("f1", Type.string())), - Arrays.asList(Struct.newBuilder().set("f1").to("x").build())); + Collections.singletonList(Struct.newBuilder().set("f1").to("x").build())); try { rs.getCurrentRowAsStruct(); fail("Expected exception"); @@ -405,26 +404,23 @@ public void testToAsyncResultSet() { ResultSet delegate = ResultSets.forRows( Type.struct(Type.StructField.of("f1", Type.string())), - Arrays.asList(Struct.newBuilder().set("f1").to("x").build())); + Collections.singletonList(Struct.newBuilder().set("f1").to("x").build())); final AtomicInteger count = new AtomicInteger(); AsyncResultSet rs = ResultSets.toAsyncResultSet(delegate); ApiFuture fut = rs.setCallback( MoreExecutors.directExecutor(), - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - count.incrementAndGet(); - assertThat(resultSet.getString("f1")).isEqualTo("x"); - } + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + count.incrementAndGet(); + assertThat(resultSet.getString("f1")).isEqualTo("x"); } } }); @@ -437,7 +433,7 @@ public void testToAsyncResultSetWithExecProvider() { ResultSet delegate = ResultSets.forRows( Type.struct(Type.StructField.of("f1", Type.string())), - Arrays.asList(Struct.newBuilder().set("f1").to("x").build())); + Collections.singletonList(Struct.newBuilder().set("f1").to("x").build())); ExecutorProvider provider = new ExecutorProvider() { @@ -458,19 +454,16 @@ public ScheduledExecutorService getExecutor() { ApiFuture fut = rs.setCallback( MoreExecutors.directExecutor(), - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - count.incrementAndGet(); - assertThat(resultSet.getString("f1")).isEqualTo("x"); - } + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + count.incrementAndGet(); + assertThat(resultSet.getString("f1")).isEqualTo("x"); } } }); @@ -485,7 +478,7 @@ public void testToAsyncResultSetWithFuture() { ApiFutures.immediateFuture( ResultSets.forRows( Type.struct(Type.StructField.of("f1", Type.string())), - Arrays.asList(Struct.newBuilder().set("f1").to("x").build()))); + Collections.singletonList(Struct.newBuilder().set("f1").to("x").build()))); ExecutorProvider provider = new ExecutorProvider() { @@ -506,19 +499,16 @@ public ScheduledExecutorService getExecutor() { ApiFuture fut = rs.setCallback( MoreExecutors.directExecutor(), - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - count.incrementAndGet(); - assertThat(resultSet.getString("f1")).isEqualTo("x"); - } + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + count.incrementAndGet(); + assertThat(resultSet.getString("f1")).isEqualTo("x"); } } }); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/RetryOnInvalidatedSessionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/RetryOnInvalidatedSessionTest.java index 4ce21ac90e5..d8eec88d88c 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/RetryOnInvalidatedSessionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/RetryOnInvalidatedSessionTest.java @@ -24,7 +24,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.gax.core.NoCredentialsProvider; @@ -32,8 +31,6 @@ import com.google.cloud.NoCredentials; import com.google.cloud.Timestamp; import com.google.cloud.spanner.AsyncResultSet.CallbackResponse; -import com.google.cloud.spanner.AsyncResultSet.ReadyCallback; -import com.google.cloud.spanner.AsyncTransactionManager.AsyncTransactionFunction; import com.google.cloud.spanner.AsyncTransactionManager.AsyncTransactionStep; import com.google.cloud.spanner.AsyncTransactionManager.CommitTimestampFuture; import com.google.cloud.spanner.AsyncTransactionManager.TransactionContextFuture; @@ -56,6 +53,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -172,10 +170,14 @@ public static void startStaticServer() throws IOException { mockSpanner = new MockSpannerServiceImpl(); mockSpanner.setAbortProbability(0.0D); // We don't want any unpredictable aborted transactions. mockSpanner.putStatementResult( - StatementResult.read("FOO", KeySet.all(), Arrays.asList("BAR"), READ_RESULTSET)); + StatementResult.read( + "FOO", KeySet.all(), Collections.singletonList("BAR"), READ_RESULTSET)); mockSpanner.putStatementResult( StatementResult.read( - "FOO", KeySet.singleKey(Key.of()), Arrays.asList("BAR"), READ_ROW_RESULTSET)); + "FOO", + KeySet.singleKey(Key.of()), + Collections.singletonList("BAR"), + READ_ROW_RESULTSET)); mockSpanner.putStatementResult(StatementResult.query(SELECT1AND2, SELECT1_RESULTSET)); mockSpanner.putStatementResult(StatementResult.update(UPDATE_STATEMENT, UPDATE_COUNT)); @@ -290,7 +292,7 @@ public void singleUseRead() throws InterruptedException { invalidateSessionPool(); int count = 0; try (ReadContext context = client.singleUse()) { - try (ResultSet rs = context.read("FOO", KeySet.all(), Arrays.asList("BAR"))) { + try (ResultSet rs = context.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -308,7 +310,7 @@ public void singleUseReadUsingIndex() throws InterruptedException { int count = 0; try (ReadContext context = client.singleUse()) { try (ResultSet rs = - context.readUsingIndex("FOO", "IDX", KeySet.all(), Arrays.asList("BAR"))) { + context.readUsingIndex("FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -324,7 +326,7 @@ public void singleUseReadUsingIndex() throws InterruptedException { public void singleUseReadRow() throws InterruptedException { invalidateSessionPool(); try (ReadContext context = client.singleUse()) { - Struct row = context.readRow("FOO", Key.of(), Arrays.asList("BAR")); + Struct row = context.readRow("FOO", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0)).isEqualTo(1L); assertThat(failOnInvalidatedSession).isFalse(); } catch (SessionNotFoundException e) { @@ -336,7 +338,8 @@ public void singleUseReadRow() throws InterruptedException { public void singleUseReadRowUsingIndex() throws InterruptedException { invalidateSessionPool(); try (ReadContext context = client.singleUse()) { - Struct row = context.readRowUsingIndex("FOO", "IDX", Key.of(), Arrays.asList("BAR")); + Struct row = + context.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0)).isEqualTo(1L); assertThat(failOnInvalidatedSession).isFalse(); } catch (SessionNotFoundException e) { @@ -366,7 +369,7 @@ public void singleUseReadOnlyTransactionRead() throws InterruptedException { invalidateSessionPool(); int count = 0; try (ReadContext context = client.singleUseReadOnlyTransaction()) { - try (ResultSet rs = context.read("FOO", KeySet.all(), Arrays.asList("BAR"))) { + try (ResultSet rs = context.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -384,7 +387,7 @@ public void singlUseReadOnlyTransactionReadUsingIndex() throws InterruptedExcept int count = 0; try (ReadContext context = client.singleUseReadOnlyTransaction()) { try (ResultSet rs = - context.readUsingIndex("FOO", "IDX", KeySet.all(), Arrays.asList("BAR"))) { + context.readUsingIndex("FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -400,7 +403,7 @@ public void singlUseReadOnlyTransactionReadUsingIndex() throws InterruptedExcept public void singleUseReadOnlyTransactionReadRow() throws InterruptedException { invalidateSessionPool(); try (ReadContext context = client.singleUseReadOnlyTransaction()) { - Struct row = context.readRow("FOO", Key.of(), Arrays.asList("BAR")); + Struct row = context.readRow("FOO", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0)).isEqualTo(1L); assertThat(failOnInvalidatedSession).isFalse(); } catch (SessionNotFoundException e) { @@ -412,7 +415,8 @@ public void singleUseReadOnlyTransactionReadRow() throws InterruptedException { public void singleUseReadOnlyTransactionReadRowUsingIndex() throws InterruptedException { invalidateSessionPool(); try (ReadContext context = client.singleUseReadOnlyTransaction()) { - Struct row = context.readRowUsingIndex("FOO", "IDX", Key.of(), Arrays.asList("BAR")); + Struct row = + context.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0)).isEqualTo(1L); assertThat(failOnInvalidatedSession).isFalse(); } catch (SessionNotFoundException e) { @@ -442,7 +446,7 @@ public void readOnlyTransactionRead() throws InterruptedException { invalidateSessionPool(); int count = 0; try (ReadContext context = client.readOnlyTransaction()) { - try (ResultSet rs = context.read("FOO", KeySet.all(), Arrays.asList("BAR"))) { + try (ResultSet rs = context.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -460,7 +464,7 @@ public void readOnlyTransactionReadUsingIndex() throws InterruptedException { int count = 0; try (ReadContext context = client.readOnlyTransaction()) { try (ResultSet rs = - context.readUsingIndex("FOO", "IDX", KeySet.all(), Arrays.asList("BAR"))) { + context.readUsingIndex("FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -476,7 +480,7 @@ public void readOnlyTransactionReadUsingIndex() throws InterruptedException { public void readOnlyTransactionReadRow() throws InterruptedException { invalidateSessionPool(); try (ReadContext context = client.readOnlyTransaction()) { - Struct row = context.readRow("FOO", Key.of(), Arrays.asList("BAR")); + Struct row = context.readRow("FOO", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0)).isEqualTo(1L); assertThat(failOnInvalidatedSession).isFalse(); } catch (SessionNotFoundException e) { @@ -488,7 +492,8 @@ public void readOnlyTransactionReadRow() throws InterruptedException { public void readOnlyTransactionReadRowUsingIndex() throws InterruptedException { invalidateSessionPool(); try (ReadContext context = client.readOnlyTransaction()) { - Struct row = context.readRowUsingIndex("FOO", "IDX", Key.of(), Arrays.asList("BAR")); + Struct row = + context.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0)).isEqualTo(1L); assertThat(failOnInvalidatedSession).isFalse(); } catch (SessionNotFoundException e) { @@ -520,14 +525,14 @@ public void readOnlyTransactionSelectNonRecoverable() throws InterruptedExceptio public void readOnlyTransactionReadNonRecoverable() throws InterruptedException { int count = 0; try (ReadContext context = client.readOnlyTransaction()) { - try (ResultSet rs = context.read("FOO", KeySet.all(), Arrays.asList("BAR"))) { + try (ResultSet rs = context.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } } assertThat(count).isEqualTo(2); invalidateSessionPool(); - try (ResultSet rs = context.read("FOO", KeySet.all(), Arrays.asList("BAR"))) { + try (ResultSet rs = context.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -540,7 +545,7 @@ public void readOnlyTransactionReadUsingIndexNonRecoverable() throws Interrupted int count = 0; try (ReadContext context = client.readOnlyTransaction()) { try (ResultSet rs = - context.readUsingIndex("FOO", "IDX", KeySet.all(), Arrays.asList("BAR"))) { + context.readUsingIndex("FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -548,7 +553,7 @@ public void readOnlyTransactionReadUsingIndexNonRecoverable() throws Interrupted assertThat(count).isEqualTo(2); invalidateSessionPool(); try (ResultSet rs = - context.readUsingIndex("FOO", "IDX", KeySet.all(), Arrays.asList("BAR"))) { + context.readUsingIndex("FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -559,20 +564,21 @@ public void readOnlyTransactionReadUsingIndexNonRecoverable() throws Interrupted @Test(expected = SessionNotFoundException.class) public void readOnlyTransactionReadRowNonRecoverable() throws InterruptedException { try (ReadContext context = client.readOnlyTransaction()) { - Struct row = context.readRow("FOO", Key.of(), Arrays.asList("BAR")); + Struct row = context.readRow("FOO", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0)).isEqualTo(1L); invalidateSessionPool(); - row = context.readRow("FOO", Key.of(), Arrays.asList("BAR")); + context.readRow("FOO", Key.of(), Collections.singletonList("BAR")); } } @Test(expected = SessionNotFoundException.class) public void readOnlyTransactionReadRowUsingIndexNonRecoverable() throws InterruptedException { try (ReadContext context = client.readOnlyTransaction()) { - Struct row = context.readRowUsingIndex("FOO", "IDX", Key.of(), Arrays.asList("BAR")); + Struct row = + context.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0)).isEqualTo(1L); invalidateSessionPool(); - row = context.readRowUsingIndex("FOO", "IDX", Key.of(), Arrays.asList("BAR")); + context.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR")); } } @@ -645,7 +651,8 @@ public void readWriteTransactionRead() throws InterruptedException { runner.run( transaction -> { int count1 = 0; - try (ResultSet rs = transaction.read("FOO", KeySet.all(), Arrays.asList("BAR"))) { + try (ResultSet rs = + transaction.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count1++; } @@ -669,7 +676,8 @@ public void readWriteTransactionReadUsingIndex() throws InterruptedException { transaction -> { int count1 = 0; try (ResultSet rs = - transaction.readUsingIndex("FOO", "IDX", KeySet.all(), Arrays.asList("BAR"))) { + transaction.readUsingIndex( + "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count1++; } @@ -689,7 +697,9 @@ public void readWriteTransactionReadRow() throws InterruptedException { try { TransactionRunner runner = client.readWriteTransaction(); Struct row = - runner.run(transaction -> transaction.readRow("FOO", Key.of(), Arrays.asList("BAR"))); + runner.run( + transaction -> + transaction.readRow("FOO", Key.of(), Collections.singletonList("BAR"))); assertThat(row.getLong(0)).isEqualTo(1L); assertThat(failOnInvalidatedSession).isFalse(); } catch (SessionNotFoundException e) { @@ -705,7 +715,8 @@ public void readWriteTransactionReadRowUsingIndex() throws InterruptedException Struct row = runner.run( transaction -> - transaction.readRowUsingIndex("FOO", "IDX", Key.of(), Arrays.asList("BAR"))); + transaction.readRowUsingIndex( + "FOO", "IDX", Key.of(), Collections.singletonList("BAR"))); assertThat(row.getLong(0)).isEqualTo(1L); assertThat(failOnInvalidatedSession).isFalse(); } catch (SessionNotFoundException e) { @@ -732,7 +743,8 @@ public void readWriteTransactionBatchUpdate() throws InterruptedException { try { TransactionRunner runner = client.readWriteTransaction(); long[] count = - runner.run(transaction -> transaction.batchUpdate(Arrays.asList(UPDATE_STATEMENT))); + runner.run( + transaction -> transaction.batchUpdate(Collections.singletonList(UPDATE_STATEMENT))); assertThat(count.length).isEqualTo(1); assertThat(count[0]).isEqualTo(UPDATE_COUNT); assertThat(failOnInvalidatedSession).isFalse(); @@ -808,7 +820,8 @@ public void readWriteTransactionReadInvalidatedDuringTransaction() { public Integer run(TransactionContext transaction) throws Exception { attempt++; int count = 0; - try (ResultSet rs = transaction.read("FOO", KeySet.all(), Arrays.asList("BAR"))) { + try (ResultSet rs = + transaction.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -817,7 +830,8 @@ public Integer run(TransactionContext transaction) throws Exception { if (attempt == 1) { invalidateSessionPool(); } - try (ResultSet rs = transaction.read("FOO", KeySet.all(), Arrays.asList("BAR"))) { + try (ResultSet rs = + transaction.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -847,7 +861,7 @@ public Integer run(TransactionContext transaction) throws Exception { int count = 0; try (ResultSet rs = transaction.readUsingIndex( - "FOO", "IDX", KeySet.all(), Arrays.asList("BAR"))) { + "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -858,7 +872,7 @@ public Integer run(TransactionContext transaction) throws Exception { } try (ResultSet rs = transaction.readUsingIndex( - "FOO", "IDX", KeySet.all(), Arrays.asList("BAR"))) { + "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -885,12 +899,13 @@ public void readWriteTransactionReadRowInvalidatedDuringTransaction() { @Override public Integer run(TransactionContext transaction) throws Exception { attempt++; - Struct row = transaction.readRow("FOO", Key.of(), Arrays.asList("BAR")); + Struct row = + transaction.readRow("FOO", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0)).isEqualTo(1L); if (attempt == 1) { invalidateSessionPool(); } - row = transaction.readRow("FOO", Key.of(), Arrays.asList("BAR")); + transaction.readRow("FOO", Key.of(), Collections.singletonList("BAR")); return attempt; } }); @@ -914,12 +929,14 @@ public void readWriteTransactionReadRowUsingIndexInvalidatedDuringTransaction() public Integer run(TransactionContext transaction) throws Exception { attempt++; Struct row = - transaction.readRowUsingIndex("FOO", "IDX", Key.of(), Arrays.asList("BAR")); + transaction.readRowUsingIndex( + "FOO", "IDX", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0)).isEqualTo(1L); if (attempt == 1) { invalidateSessionPool(); } - row = transaction.readRowUsingIndex("FOO", "IDX", Key.of(), Arrays.asList("BAR")); + transaction.readRowUsingIndex( + "FOO", "IDX", Key.of(), Collections.singletonList("BAR")); return attempt; } }); @@ -1014,7 +1031,8 @@ public void transactionManagerRead() throws InterruptedException { TransactionContext transaction = manager.begin(); while (true) { try { - try (ResultSet rs = transaction.read("FOO", KeySet.all(), Arrays.asList("BAR"))) { + try (ResultSet rs = + transaction.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -1043,7 +1061,8 @@ public void transactionManagerReadUsingIndex() throws InterruptedException { while (true) { try { try (ResultSet rs = - transaction.readUsingIndex("FOO", "IDX", KeySet.all(), Arrays.asList("BAR"))) { + transaction.readUsingIndex( + "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -1071,7 +1090,7 @@ public void transactionManagerReadRow() throws InterruptedException { TransactionContext transaction = manager.begin(); while (true) { try { - row = transaction.readRow("FOO", Key.of(), Arrays.asList("BAR")); + row = transaction.readRow("FOO", Key.of(), Collections.singletonList("BAR")); manager.commit(); break; } catch (AbortedException e) { @@ -1095,7 +1114,9 @@ public void transactionManagerReadRowUsingIndex() throws InterruptedException { TransactionContext transaction = manager.begin(); while (true) { try { - row = transaction.readRowUsingIndex("FOO", "IDX", Key.of(), Arrays.asList("BAR")); + row = + transaction.readRowUsingIndex( + "FOO", "IDX", Key.of(), Collections.singletonList("BAR")); manager.commit(); break; } catch (AbortedException e) { @@ -1179,7 +1200,7 @@ public void transactionManagerBatchUpdate() throws InterruptedException { TransactionContext transaction = manager.begin(); while (true) { try { - count = transaction.batchUpdate(Arrays.asList(UPDATE_STATEMENT)); + count = transaction.batchUpdate(Collections.singletonList(UPDATE_STATEMENT)); manager.commit(); break; } catch (AbortedException e) { @@ -1266,7 +1287,8 @@ public void transactionManagerReadInvalidatedDuringTransaction() throws Interrup attempts++; int count = 0; try { - try (ResultSet rs = transaction.read("FOO", KeySet.all(), Arrays.asList("BAR"))) { + try (ResultSet rs = + transaction.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -1275,7 +1297,8 @@ public void transactionManagerReadInvalidatedDuringTransaction() throws Interrup if (attempts == 1) { invalidateSessionPool(); } - try (ResultSet rs = transaction.read("FOO", KeySet.all(), Arrays.asList("BAR"))) { + try (ResultSet rs = + transaction.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -1306,7 +1329,8 @@ public void transactionManagerReadUsingIndexInvalidatedDuringTransaction() int count = 0; try { try (ResultSet rs = - transaction.readUsingIndex("FOO", "IDX", KeySet.all(), Arrays.asList("BAR"))) { + transaction.readUsingIndex( + "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -1316,7 +1340,8 @@ public void transactionManagerReadUsingIndexInvalidatedDuringTransaction() invalidateSessionPool(); } try (ResultSet rs = - transaction.readUsingIndex("FOO", "IDX", KeySet.all(), Arrays.asList("BAR"))) { + transaction.readUsingIndex( + "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { while (rs.next()) { count++; } @@ -1344,12 +1369,12 @@ public void transactionManagerReadRowInvalidatedDuringTransaction() throws Inter while (true) { attempts++; try { - Struct row = transaction.readRow("FOO", Key.of(), Arrays.asList("BAR")); + Struct row = transaction.readRow("FOO", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0)).isEqualTo(1L); if (attempts == 1) { invalidateSessionPool(); } - row = transaction.readRow("FOO", Key.of(), Arrays.asList("BAR")); + transaction.readRow("FOO", Key.of(), Collections.singletonList("BAR")); manager.commit(); break; } catch (AbortedException e) { @@ -1374,12 +1399,14 @@ public void transactionManagerReadRowUsingIndexInvalidatedDuringTransaction() while (true) { attempts++; try { - Struct row = transaction.readRowUsingIndex("FOO", "IDX", Key.of(), Arrays.asList("BAR")); + Struct row = + transaction.readRowUsingIndex( + "FOO", "IDX", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0)).isEqualTo(1L); if (attempts == 1) { invalidateSessionPool(); } - row = transaction.readRowUsingIndex("FOO", "IDX", Key.of(), Arrays.asList("BAR")); + transaction.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR")); manager.commit(); break; } catch (AbortedException e) { @@ -1409,7 +1436,8 @@ public void partitionedDml() throws InterruptedException { public void write() throws InterruptedException { invalidateSessionPool(); try { - Timestamp timestamp = client.write(Arrays.asList(Mutation.delete("FOO", KeySet.all()))); + Timestamp timestamp = + client.write(Collections.singletonList(Mutation.delete("FOO", KeySet.all()))); assertThat(timestamp).isNotNull(); assertThat(failOnInvalidatedSession).isFalse(); } catch (SessionNotFoundException e) { @@ -1422,7 +1450,7 @@ public void writeAtLeastOnce() throws InterruptedException { invalidateSessionPool(); try { Timestamp timestamp = - client.writeAtLeastOnce(Arrays.asList(Mutation.delete("FOO", KeySet.all()))); + client.writeAtLeastOnce(Collections.singletonList(Mutation.delete("FOO", KeySet.all()))); assertThat(timestamp).isNotNull(); assertThat(failOnInvalidatedSession).isFalse(); } catch (SessionNotFoundException e) { @@ -1432,35 +1460,21 @@ public void writeAtLeastOnce() throws InterruptedException { @Test public void asyncRunnerSelect() throws InterruptedException { - asyncRunner_withReadFunction( - new Function() { - @Override - public AsyncResultSet apply(TransactionContext input) { - return input.executeQueryAsync(SELECT1AND2); - } - }); + asyncRunner_withReadFunction(input -> input.executeQueryAsync(SELECT1AND2)); } @Test public void asyncRunnerRead() throws InterruptedException { asyncRunner_withReadFunction( - new Function() { - @Override - public AsyncResultSet apply(TransactionContext input) { - return input.readAsync("FOO", KeySet.all(), Arrays.asList("BAR")); - } - }); + input -> input.readAsync("FOO", KeySet.all(), Collections.singletonList("BAR"))); } @Test public void asyncRunnerReadUsingIndex() throws InterruptedException { asyncRunner_withReadFunction( - new Function() { - @Override - public AsyncResultSet apply(TransactionContext input) { - return input.readUsingIndexAsync("FOO", "IDX", KeySet.all(), Arrays.asList("BAR")); - } - }); + input -> + input.readUsingIndexAsync( + "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))); } private void asyncRunner_withReadFunction( @@ -1477,31 +1491,21 @@ private void asyncRunner_withReadFunction( ApiFuture fut = rs.setCallback( queryExecutor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case OK: - counter.incrementAndGet(); - break; - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - } + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case OK: + counter.incrementAndGet(); + break; + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; } } }); return ApiFutures.transform( - fut, - new ApiFunction() { - @Override - public Long apply(Void input) { - return counter.get(); - } - }, - MoreExecutors.directExecutor()); + fut, input -> counter.get(), MoreExecutors.directExecutor()); }, executor); assertThat(get(count)).isEqualTo(2); @@ -1519,7 +1523,8 @@ public void asyncRunnerReadRow() throws InterruptedException { try { AsyncRunner runner = client.runAsync(); ApiFuture row = - runner.runAsync(txn -> txn.readRowAsync("FOO", Key.of(), Arrays.asList("BAR")), executor); + runner.runAsync( + txn -> txn.readRowAsync("FOO", Key.of(), Collections.singletonList("BAR")), executor); assertThat(get(row).getLong(0)).isEqualTo(1L); assertThat(failOnInvalidatedSession).isFalse(); } catch (SessionNotFoundException e) { @@ -1534,7 +1539,9 @@ public void asyncRunnerReadRowUsingIndex() throws InterruptedException { AsyncRunner runner = client.runAsync(); ApiFuture row = runner.runAsync( - txn -> txn.readRowUsingIndexAsync("FOO", "IDX", Key.of(), Arrays.asList("BAR")), + txn -> + txn.readRowUsingIndexAsync( + "FOO", "IDX", Key.of(), Collections.singletonList("BAR")), executor); assertThat(get(row).getLong(0)).isEqualTo(1L); assertThat(failOnInvalidatedSession).isFalse(); @@ -1596,35 +1603,21 @@ public void asyncRunnerBuffer() throws InterruptedException { @Test public void asyncTransactionManagerAsyncSelect() throws InterruptedException { - asyncTransactionManager_readAsync( - new Function() { - @Override - public AsyncResultSet apply(TransactionContext input) { - return input.executeQueryAsync(SELECT1AND2); - } - }); + asyncTransactionManager_readAsync(input -> input.executeQueryAsync(SELECT1AND2)); } @Test public void asyncTransactionManagerAsyncRead() throws InterruptedException { asyncTransactionManager_readAsync( - new Function() { - @Override - public AsyncResultSet apply(TransactionContext input) { - return input.readAsync("FOO", KeySet.all(), Arrays.asList("BAR")); - } - }); + input -> input.readAsync("FOO", KeySet.all(), Collections.singletonList("BAR"))); } @Test public void asyncTransactionManagerAsyncReadUsingIndex() throws InterruptedException { asyncTransactionManager_readAsync( - new Function() { - @Override - public AsyncResultSet apply(TransactionContext input) { - return input.readUsingIndexAsync("FOO", "idx", KeySet.all(), Arrays.asList("BAR")); - } - }); + input -> + input.readUsingIndexAsync( + "FOO", "idx", KeySet.all(), Collections.singletonList("BAR"))); } private void asyncTransactionManager_readAsync( @@ -1638,40 +1631,26 @@ private void asyncTransactionManager_readAsync( final AtomicLong counter = new AtomicLong(); AsyncTransactionStep count = context.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - AsyncResultSet rs = fn.apply(txn); - ApiFuture fut = - rs.setCallback( - queryExecutor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case OK: - counter.incrementAndGet(); - break; - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - } - } + (transaction, ignored) -> { + AsyncResultSet rs = fn.apply(transaction); + ApiFuture fut = + rs.setCallback( + queryExecutor, + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case OK: + counter.incrementAndGet(); + break; + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; } - }); - return ApiFutures.transform( - fut, - new ApiFunction() { - @Override - public Long apply(Void input) { - return counter.get(); - } - }, - MoreExecutors.directExecutor()); - } + } + }); + return ApiFutures.transform( + fut, input -> counter.get(), MoreExecutors.directExecutor()); }, executor); CommitTimestampFuture ts = count.commitAsync(); @@ -1692,35 +1671,20 @@ public Long apply(Void input) { @Test public void asyncTransactionManagerSelect() throws InterruptedException { - asyncTransactionManager_readSync( - new Function() { - @Override - public ResultSet apply(TransactionContext input) { - return input.executeQuery(SELECT1AND2); - } - }); + asyncTransactionManager_readSync(input -> input.executeQuery(SELECT1AND2)); } @Test public void asyncTransactionManagerRead() throws InterruptedException { asyncTransactionManager_readSync( - new Function() { - @Override - public ResultSet apply(TransactionContext input) { - return input.read("FOO", KeySet.all(), Arrays.asList("BAR")); - } - }); + input -> input.read("FOO", KeySet.all(), Collections.singletonList("BAR"))); } @Test public void asyncTransactionManagerReadUsingIndex() throws InterruptedException { asyncTransactionManager_readSync( - new Function() { - @Override - public ResultSet apply(TransactionContext input) { - return input.readUsingIndex("FOO", "idx", KeySet.all(), Arrays.asList("BAR")); - } - }); + input -> + input.readUsingIndex("FOO", "idx", KeySet.all(), Collections.singletonList("BAR"))); } private void asyncTransactionManager_readSync(final Function fn) @@ -1733,18 +1697,14 @@ private void asyncTransactionManager_readSync(final Function count = context.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - long counter = 0L; - try (ResultSet rs = fn.apply(txn)) { - while (rs.next()) { - counter++; - } + (transaction, ignored) -> { + long counter = 0L; + try (ResultSet rs = fn.apply(transaction)) { + while (rs.next()) { + counter++; } - return ApiFutures.immediateFuture(counter); } + return ApiFutures.immediateFuture(counter); }, executor); CommitTimestampFuture ts = count.commitAsync(); @@ -1766,47 +1726,32 @@ public ApiFuture apply(TransactionContext txn, Void input) @Test public void asyncTransactionManagerReadRow() throws InterruptedException { asyncTransactionManager_readRowFunction( - new Function>() { - @Override - public ApiFuture apply(TransactionContext input) { - return ApiFutures.immediateFuture( - input.readRow("FOO", Key.of("foo"), Arrays.asList("BAR"))); - } - }); + input -> + ApiFutures.immediateFuture( + input.readRow("FOO", Key.of("foo"), Collections.singletonList("BAR")))); } @Test public void asyncTransactionManagerReadRowUsingIndex() throws InterruptedException { asyncTransactionManager_readRowFunction( - new Function>() { - @Override - public ApiFuture apply(TransactionContext input) { - return ApiFutures.immediateFuture( - input.readRowUsingIndex("FOO", "idx", Key.of("foo"), Arrays.asList("BAR"))); - } - }); + input -> + ApiFutures.immediateFuture( + input.readRowUsingIndex( + "FOO", "idx", Key.of("foo"), Collections.singletonList("BAR")))); } @Test public void asyncTransactionManagerReadRowAsync() throws InterruptedException { asyncTransactionManager_readRowFunction( - new Function>() { - @Override - public ApiFuture apply(TransactionContext input) { - return input.readRowAsync("FOO", Key.of("foo"), Arrays.asList("BAR")); - } - }); + input -> input.readRowAsync("FOO", Key.of("foo"), Collections.singletonList("BAR"))); } @Test public void asyncTransactionManagerReadRowUsingIndexAsync() throws InterruptedException { asyncTransactionManager_readRowFunction( - new Function>() { - @Override - public ApiFuture apply(TransactionContext input) { - return input.readRowUsingIndexAsync("FOO", "idx", Key.of("foo"), Arrays.asList("BAR")); - } - }); + input -> + input.readRowUsingIndexAsync( + "FOO", "idx", Key.of("foo"), Collections.singletonList("BAR"))); } private void asyncTransactionManager_readRowFunction( @@ -1818,15 +1763,7 @@ private void asyncTransactionManager_readRowFunction( while (true) { try { AsyncTransactionStep row = - context.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - return fn.apply(txn); - } - }, - executor); + context.then((transaction, ignored) -> fn.apply(transaction), executor); CommitTimestampFuture ts = row.commitAsync(); assertThat(get(ts)).isNotNull(); assertThat(get(row)).isEqualTo(Struct.newBuilder().set("BAR").to(1L).build()); @@ -1846,49 +1783,28 @@ public ApiFuture apply(TransactionContext txn, Void input) @Test public void asyncTransactionManagerUpdateAsync() throws InterruptedException { asyncTransactionManager_updateFunction( - new Function>() { - @Override - public ApiFuture apply(TransactionContext input) { - return input.executeUpdateAsync(UPDATE_STATEMENT); - } - }, - UPDATE_COUNT); + input -> input.executeUpdateAsync(UPDATE_STATEMENT), UPDATE_COUNT); } @Test public void asyncTransactionManagerUpdate() throws InterruptedException { asyncTransactionManager_updateFunction( - new Function>() { - @Override - public ApiFuture apply(TransactionContext input) { - return ApiFutures.immediateFuture(input.executeUpdate(UPDATE_STATEMENT)); - } - }, - UPDATE_COUNT); + input -> ApiFutures.immediateFuture(input.executeUpdate(UPDATE_STATEMENT)), UPDATE_COUNT); } @Test public void asyncTransactionManagerBatchUpdateAsync() throws InterruptedException { asyncTransactionManager_updateFunction( - new Function>() { - @Override - public ApiFuture apply(TransactionContext input) { - return input.batchUpdateAsync(Arrays.asList(UPDATE_STATEMENT, UPDATE_STATEMENT)); - } - }, + input -> input.batchUpdateAsync(Arrays.asList(UPDATE_STATEMENT, UPDATE_STATEMENT)), new long[] {UPDATE_COUNT, UPDATE_COUNT}); } @Test public void asyncTransactionManagerBatchUpdate() throws InterruptedException { asyncTransactionManager_updateFunction( - new Function>() { - @Override - public ApiFuture apply(TransactionContext input) { - return ApiFutures.immediateFuture( - input.batchUpdate(Arrays.asList(UPDATE_STATEMENT, UPDATE_STATEMENT))); - } - }, + input -> + ApiFutures.immediateFuture( + input.batchUpdate(Arrays.asList(UPDATE_STATEMENT, UPDATE_STATEMENT))), new long[] {UPDATE_COUNT, UPDATE_COUNT}); } @@ -1900,14 +1816,7 @@ private void asyncTransactionManager_updateFunction( while (true) { try { AsyncTransactionStep res = - transaction.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) throws Exception { - return fn.apply(txn); - } - }, - executor); + transaction.then((txn, input) -> fn.apply(txn), executor); CommitTimestampFuture ts = res.commitAsync(); assertThat(get(res)).isEqualTo(expected); assertThat(get(ts)).isNotNull(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionClientTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionClientTest.java index 3de323fa4c5..6ec64d7fdd5 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionClientTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionClientTest.java @@ -26,6 +26,7 @@ import com.google.cloud.grpc.GrpcTransportOptions.ExecutorFactory; import com.google.cloud.spanner.SessionClient.SessionConsumer; import com.google.cloud.spanner.spi.v1.SpannerRpc; +import com.google.cloud.spanner.spi.v1.SpannerRpc.Option; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -51,8 +52,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; @RunWith(Parameterized.class) public class SessionClientTest { @@ -149,23 +148,20 @@ public void batchCreateAndCloseSessions() { when(rpc.batchCreateSessions( Mockito.eq(dbName), Mockito.anyInt(), Mockito.eq(labels), Mockito.anyMap())) .then( - new Answer>() { - @Override - public List answer(InvocationOnMock invocation) { - Map options = invocation.getArgumentAt(3, Map.class); - Long channelHint = (Long) options.get(SpannerRpc.Option.CHANNEL_HINT); - usedChannels.add(channelHint); - int sessionCount = invocation.getArgumentAt(1, Integer.class); - List res = new ArrayList<>(); - for (int i = 1; i <= sessionCount; i++) { - res.add( - com.google.spanner.v1.Session.newBuilder() - .setName(String.format(sessionName, i)) - .putAllLabels(labels) - .build()); - } - return res; + invocation -> { + Map options = invocation.getArgumentAt(3, Map.class); + Long channelHint = (Long) options.get(Option.CHANNEL_HINT); + usedChannels.add(channelHint); + int sessionCount = invocation.getArgumentAt(1, Integer.class); + List res = new ArrayList<>(); + for (int i = 1; i <= sessionCount; i++) { + res.add( + com.google.spanner.v1.Session.newBuilder() + .setName(String.format(sessionName, i)) + .putAllLabels(labels) + .build()); } + return res; }); final AtomicInteger returnedSessionCount = new AtomicInteger(); @@ -206,29 +202,26 @@ public void onSessionCreateFailure(Throwable t, int createFailureForSessionCount public void batchCreateSessionsDistributesMultipleRequestsOverChannels() { DatabaseId db = DatabaseId.of(dbName); final String sessionName = dbName + "/sessions/s%d"; - final Map labels = Collections.emptyMap(); + final Map labels = Collections.emptyMap(); when(spannerOptions.getSessionLabels()).thenReturn(labels); final Set usedChannelHints = Collections.synchronizedSet(new HashSet<>()); when(rpc.batchCreateSessions( Mockito.eq(dbName), Mockito.anyInt(), Mockito.eq(labels), Mockito.anyMap())) .then( - new Answer>() { - @Override - public List answer(InvocationOnMock invocation) { - Map options = invocation.getArgumentAt(3, Map.class); - Long channelHint = (Long) options.get(SpannerRpc.Option.CHANNEL_HINT); - usedChannelHints.add(channelHint); - int sessionCount = invocation.getArgumentAt(1, Integer.class); - List res = new ArrayList<>(); - for (int i = 1; i <= sessionCount; i++) { - res.add( - com.google.spanner.v1.Session.newBuilder() - .setName(String.format(sessionName, i)) - .putAllLabels(labels) - .build()); - } - return res; + invocation -> { + Map options = invocation.getArgumentAt(3, Map.class); + Long channelHint = (Long) options.get(Option.CHANNEL_HINT); + usedChannelHints.add(channelHint); + int sessionCount = invocation.getArgumentAt(1, Integer.class); + List res = new ArrayList<>(); + for (int i = 1; i <= sessionCount; i++) { + res.add( + com.google.spanner.v1.Session.newBuilder() + .setName(String.format(sessionName, i)) + .putAllLabels(labels) + .build()); } + return res; }); final AtomicInteger returnedSessionCount = new AtomicInteger(); @@ -296,25 +289,22 @@ public void batchCreateSessionsWithExceptions() { when(rpc.batchCreateSessions( Mockito.eq(dbName), Mockito.anyInt(), Mockito.anyMap(), Mockito.anyMap())) .then( - new Answer>() { - @Override - public List answer(InvocationOnMock invocation) { - Map options = invocation.getArgumentAt(3, Map.class); - Long channelHint = (Long) options.get(SpannerRpc.Option.CHANNEL_HINT); - if (errorOnChannels.contains(channelHint)) { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.RESOURCE_EXHAUSTED, "could not create any more sessions"); - } else { - int sessionCount = invocation.getArgumentAt(1, Integer.class); - List res = new ArrayList<>(); - for (int i = 1; i <= sessionCount; i++) { - res.add( - com.google.spanner.v1.Session.newBuilder() - .setName(String.format(sessionName, i)) - .build()); - } - return res; + invocation -> { + Map options = invocation.getArgumentAt(3, Map.class); + Long channelHint = (Long) options.get(Option.CHANNEL_HINT); + if (errorOnChannels.contains(channelHint)) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.RESOURCE_EXHAUSTED, "could not create any more sessions"); + } else { + int sessionCount = invocation.getArgumentAt(1, Integer.class); + List res = new ArrayList<>(); + for (int i = 1; i <= sessionCount; i++) { + res.add( + com.google.spanner.v1.Session.newBuilder() + .setName(String.format(sessionName, i)) + .build()); } + return res; } }); @@ -363,19 +353,16 @@ public void batchCreateSessionsServerReturnsLessSessionsPerBatch() { when(rpc.batchCreateSessions( Mockito.eq(dbName), Mockito.anyInt(), Mockito.anyMap(), Mockito.anyMap())) .then( - new Answer>() { - @Override - public List answer(InvocationOnMock invocation) { - int sessionCount = invocation.getArgumentAt(1, Integer.class); - List res = new ArrayList<>(); - for (int i = 1; i <= Math.min(MAX_SESSIONS_PER_BATCH, sessionCount); i++) { - res.add( - com.google.spanner.v1.Session.newBuilder() - .setName(String.format(sessionName, i)) - .build()); - } - return res; + invocation -> { + int sessionCount = invocation.getArgumentAt(1, Integer.class); + List res = new ArrayList<>(); + for (int i = 1; i <= Math.min(MAX_SESSIONS_PER_BATCH, sessionCount); i++) { + res.add( + com.google.spanner.v1.Session.newBuilder() + .setName(String.format(sessionName, i)) + .build()); } + return res; }); final AtomicInteger returnedSessionCount = new AtomicInteger(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionImplTest.java index 3a3f8b7ce83..c97c2c2721f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionImplTest.java @@ -38,14 +38,12 @@ import com.google.spanner.v1.CommitResponse; import com.google.spanner.v1.Mutation.Write; import com.google.spanner.v1.PartialResultSet; -import com.google.spanner.v1.ReadRequest; import com.google.spanner.v1.ResultSetMetadata; import com.google.spanner.v1.RollbackRequest; import com.google.spanner.v1.Session; import com.google.spanner.v1.Transaction; import io.opencensus.trace.Span; import java.text.ParseException; -import java.util.Arrays; import java.util.Calendar; import java.util.Collections; import java.util.GregorianCalendar; @@ -62,8 +60,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; /** Unit tests for {@link com.google.cloud.spanner.SessionImpl}. */ @RunWith(JUnit4.class) @@ -82,7 +78,7 @@ public void setUp() { when(spannerOptions.getPrefetchChunks()).thenReturn(1); when(spannerOptions.getRetrySettings()).thenReturn(RetrySettings.newBuilder().build()); when(spannerOptions.getClock()).thenReturn(NanoClock.getDefaultClock()); - when(spannerOptions.getSessionLabels()).thenReturn(Collections.emptyMap()); + when(spannerOptions.getSessionLabels()).thenReturn(Collections.emptyMap()); GrpcTransportOptions transportOptions = mock(GrpcTransportOptions.class); when(transportOptions.getExecutorFactory()).thenReturn(mock(ExecutorFactory.class)); when(spannerOptions.getTransportOptions()).thenReturn(transportOptions); @@ -198,7 +194,7 @@ public void writeAtLeastOnce() throws ParseException { Timestamp timestamp = session.writeAtLeastOnce( - Arrays.asList(Mutation.newInsertBuilder("T").set("C").to("x").build())); + Collections.singletonList(Mutation.newInsertBuilder("T").set("C").to("x").build())); assertThat(timestamp.getSeconds()) .isEqualTo(utcTimeSeconds(2015, Calendar.OCTOBER, 1, 10, 54, 20)); assertThat(timestamp.getNanos()).isEqualTo(TimeUnit.MILLISECONDS.toNanos(21)); @@ -228,7 +224,8 @@ public void writeAtLeastOnceWithOptions() throws ParseException { CommitResponse.newBuilder().setCommitTimestamp(Timestamps.parse(timestampString)).build(); Mockito.when(rpc.commit(commit.capture(), Mockito.eq(options))).thenReturn(response); session.writeAtLeastOnceWithOptions( - Arrays.asList(Mutation.newInsertBuilder("T").set("C").to("x").build()), Options.tag(tag)); + Collections.singletonList(Mutation.newInsertBuilder("T").set("C").to("x").build()), + Options.tag(tag)); CommitRequest request = commit.getValue(); assertThat(request.getRequestOptions().getTransactionTag()).isEqualTo(tag); @@ -256,7 +253,7 @@ public void newSingleUseContextClosesOldSingleUseContext() { ReadContext ctx = session.singleUse(TimestampBound.strong()); session.singleUse(TimestampBound.strong()); try { - ctx.read("Dummy", KeySet.all(), Arrays.asList("C")); + ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); fail("Expected exception"); } catch (IllegalStateException ex) { assertThat(ex.getMessage()).contains("invalidated"); @@ -268,7 +265,7 @@ public void newSingleUseContextClosesOldSingleUseReadOnlyTransactionContext() { ReadContext ctx = session.singleUseReadOnlyTransaction(TimestampBound.strong()); session.singleUse(TimestampBound.strong()); try { - ctx.read("Dummy", KeySet.all(), Arrays.asList("C")); + ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); fail("Expected exception"); } catch (IllegalStateException ex) { assertThat(ex.getMessage()).contains("invalidated"); @@ -280,7 +277,7 @@ public void newSingleUseContextClosesOldMultiUseReadOnlyTransactionContext() { ReadContext ctx = session.singleUseReadOnlyTransaction(TimestampBound.strong()); session.singleUse(TimestampBound.strong()); try { - ctx.read("Dummy", KeySet.all(), Arrays.asList("C")); + ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); fail("Expected exception"); } catch (IllegalStateException ex) { assertThat(ex.getMessage()).contains("invalidated"); @@ -292,7 +289,7 @@ public void newSingleUseReadOnlyTransactionContextClosesOldSingleUseContext() { ReadContext ctx = session.singleUse(TimestampBound.strong()); session.singleUseReadOnlyTransaction(TimestampBound.strong()); try { - ctx.read("Dummy", KeySet.all(), Arrays.asList("C")); + ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); fail("Expected exception"); } catch (IllegalStateException ex) { assertThat(ex.getMessage()).contains("invalidated"); @@ -304,7 +301,7 @@ public void newMultiUseReadOnlyTransactionContextClosesOldSingleUseContext() { ReadContext ctx = session.singleUse(TimestampBound.strong()); session.readOnlyTransaction(TimestampBound.strong()); try { - ctx.read("Dummy", KeySet.all(), Arrays.asList("C")); + ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); fail("Expected exception"); } catch (IllegalStateException ex) { assertThat(ex.getMessage()).contains("invalidated"); @@ -315,14 +312,14 @@ public void newMultiUseReadOnlyTransactionContextClosesOldSingleUseContext() { public void writeClosesOldSingleUseContext() throws ParseException { ReadContext ctx = session.singleUse(TimestampBound.strong()); - Mockito.when(rpc.commit(Mockito.any(), Mockito.eq(options))) + Mockito.when(rpc.commit(Mockito.any(), Mockito.eq(options))) .thenReturn( CommitResponse.newBuilder() .setCommitTimestamp(Timestamps.parse("2015-10-01T10:54:20.021Z")) .build()); - session.writeAtLeastOnce(Arrays.asList()); + session.writeAtLeastOnce(Collections.emptyList()); try { - ctx.read("Dummy", KeySet.all(), Arrays.asList("C")); + ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); fail("Expected exception"); } catch (IllegalStateException ex) { assertThat(ex.getMessage()).contains("invalidated"); @@ -336,7 +333,7 @@ public void transactionClosesOldSingleUseContext() { // Note that we don't even run the transaction - just preparing the runner is sufficient. session.readWriteTransaction(); try { - ctx.read("Dummy", KeySet.all(), Arrays.asList("C")); + ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); fail("Expected exception"); } catch (IllegalStateException ex) { assertThat(ex.getMessage()).contains("invalidated"); @@ -364,11 +361,11 @@ public void singleUseContextClosesTransaction() { public void prepareClosesOldSingleUseContext() { ReadContext ctx = session.singleUse(TimestampBound.strong()); - Mockito.when(rpc.beginTransaction(Mockito.any(), Mockito.eq(options))) + Mockito.when(rpc.beginTransaction(Mockito.any(), Mockito.eq(options))) .thenReturn(Transaction.newBuilder().setId(ByteString.copyFromUtf8("t1")).build()); session.prepareReadWriteTransaction(); try { - ctx.read("Dummy", KeySet.all(), Arrays.asList("C")); + ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); fail("Expected exception"); } catch (IllegalStateException ex) { assertThat(ex.getMessage()).contains("invalidated"); @@ -388,7 +385,7 @@ public void singleUseReadOnlyTransactionDoesntReturnTransactionMetadata() { mockRead(resultSet); ReadOnlyTransaction txn = session.singleUseReadOnlyTransaction(TimestampBound.strong()); - assertThat(txn.readRow("Dummy", Key.of(), Arrays.asList("C"))).isNull(); + assertThat(txn.readRow("Dummy", Key.of(), Collections.singletonList("C"))).isNull(); // For now, getReadTimestamp() will raise an ISE because it hasn't seen a timestamp. It would // be better for the read to fail with an INTERNAL error, but we can't do that until txn @@ -415,7 +412,7 @@ public void singleUseReadOnlyTransactionReturnsEmptyTransactionMetadata() { ReadOnlyTransaction txn = session.singleUseReadOnlyTransaction(TimestampBound.strong()); try { - txn.readRow("Dummy", Key.of(), Arrays.asList("C")); + txn.readRow("Dummy", Key.of(), Collections.singletonList("C")); fail("Expected exception"); } catch (SpannerException ex) { assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); @@ -433,15 +430,12 @@ public void request(int numMessages) {} private void mockRead(final PartialResultSet myResultSet) { final ArgumentCaptor consumer = ArgumentCaptor.forClass(SpannerRpc.ResultStreamConsumer.class); - Mockito.when(rpc.read(Mockito.any(), consumer.capture(), Mockito.eq(options))) + Mockito.when(rpc.read(Mockito.any(), consumer.capture(), Mockito.eq(options))) .then( - new Answer() { - @Override - public SpannerRpc.StreamingCall answer(InvocationOnMock invocation) { - consumer.getValue().onPartialResultSet(myResultSet); - consumer.getValue().onCompleted(); - return new NoOpStreamingCall(); - } + invocation -> { + consumer.getValue().onPartialResultSet(myResultSet); + consumer.getValue().onCompleted(); + return new NoOpStreamingCall(); }); } @@ -452,13 +446,12 @@ public void multiUseReadOnlyTransactionReturnsEmptyTransactionMetadata() { PartialResultSet.newBuilder() .setMetadata(newMetadata(Type.struct(Type.StructField.of("C", Type.string())))) .build(); - Mockito.when(rpc.beginTransaction(Mockito.any(), Mockito.eq(options))) - .thenReturn(txnMetadata); + Mockito.when(rpc.beginTransaction(Mockito.any(), Mockito.eq(options))).thenReturn(txnMetadata); mockRead(resultSet); ReadOnlyTransaction txn = session.readOnlyTransaction(TimestampBound.strong()); try { - txn.readRow("Dummy", Key.of(), Arrays.asList("C")); + txn.readRow("Dummy", Key.of(), Collections.singletonList("C")); fail("Expected exception"); } catch (SpannerException e) { assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); @@ -472,13 +465,12 @@ public void multiUseReadOnlyTransactionReturnsMissingTimestamp() { PartialResultSet.newBuilder() .setMetadata(newMetadata(Type.struct(Type.StructField.of("C", Type.string())))) .build(); - Mockito.when(rpc.beginTransaction(Mockito.any(), Mockito.eq(options))) - .thenReturn(txnMetadata); + Mockito.when(rpc.beginTransaction(Mockito.any(), Mockito.eq(options))).thenReturn(txnMetadata); mockRead(resultSet); ReadOnlyTransaction txn = session.readOnlyTransaction(TimestampBound.strong()); try { - txn.readRow("Dummy", Key.of(), Arrays.asList("C")); + txn.readRow("Dummy", Key.of(), Collections.singletonList("C")); fail("Expected exception"); } catch (SpannerException e) { assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); @@ -493,13 +485,12 @@ public void multiUseReadOnlyTransactionReturnsMissingTransactionId() throws Pars PartialResultSet.newBuilder() .setMetadata(newMetadata(Type.struct(Type.StructField.of("C", Type.string())))) .build(); - Mockito.when(rpc.beginTransaction(Mockito.any(), Mockito.eq(options))) - .thenReturn(txnMetadata); + Mockito.when(rpc.beginTransaction(Mockito.any(), Mockito.eq(options))).thenReturn(txnMetadata); mockRead(resultSet); ReadOnlyTransaction txn = session.readOnlyTransaction(TimestampBound.strong()); try { - txn.readRow("Dummy", Key.of(), Arrays.asList("C")); + txn.readRow("Dummy", Key.of(), Collections.singletonList("C")); fail("Expected exception"); } catch (SpannerException e) { assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolBenchmark.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolBenchmark.java index 46c89ced307..4415ba7d707 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolBenchmark.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolBenchmark.java @@ -245,7 +245,7 @@ public void burstReadAndWrite(final BenchmarkState server) throws Exception { /** Measures the time needed to acquire MaxSessions session sequentially. */ @Benchmark - public void steadyIncrease(BenchmarkState server) throws Exception { + public void steadyIncrease(BenchmarkState server) { final DatabaseClient client = server.spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); SessionPool pool = ((DatabaseClientImpl) client).pool; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolMaintainerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolMaintainerTest.java index 929fe2c3476..e7c8f3ded54 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolMaintainerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolMaintainerTest.java @@ -27,7 +27,6 @@ import com.google.cloud.spanner.SessionPool.PooledSession; import com.google.cloud.spanner.SessionPool.PooledSessionFuture; import com.google.cloud.spanner.SessionPool.SessionConsumerImpl; -import com.google.common.base.Function; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -41,8 +40,6 @@ import org.junit.runners.JUnit4; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; @RunWith(JUnit4.class) public class SessionPoolMaintainerTest extends BaseSessionPoolTest { @@ -77,20 +74,17 @@ public void setUp() { private void setupMockSessionCreation() { doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - int sessionCount = invocation.getArgumentAt(0, Integer.class); - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - for (int i = 0; i < sessionCount; i++) { - consumer.onSessionReady(setupMockSession(mockSession())); - } - }); - return null; - } + invocation -> { + executor.submit( + () -> { + int sessionCount = invocation.getArgumentAt(0, Integer.class); + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + for (int i = 0; i < sessionCount; i++) { + consumer.onSessionReady(setupMockSession(mockSession())); + } + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions( @@ -103,16 +97,13 @@ private SessionImpl setupMockSession(final SessionImpl session) { when(session.singleUse(any(TimestampBound.class))).thenReturn(mockContext); when(mockContext.executeQuery(any(Statement.class))) .thenAnswer( - new Answer() { - @Override - public ResultSet answer(InvocationOnMock invocation) { - Integer currentValue = pingedSessions.get(session.getName()); - if (currentValue == null) { - currentValue = 0; - } - pingedSessions.put(session.getName(), ++currentValue); - return mockResult; + invocation -> { + Integer currentValue = pingedSessions.get(session.getName()); + if (currentValue == null) { + currentValue = 0; } + pingedSessions.put(session.getName(), ++currentValue); + return mockResult; }); when(mockResult.next()).thenReturn(true); return session; @@ -123,12 +114,9 @@ private SessionPool createPool() throws Exception { SessionPool.createPool( options, new TestExecutorFactory(), client.getSessionClient(db), clock); pool.idleSessionRemovedListener = - new Function() { - @Override - public Void apply(PooledSession input) { - idledSessions.add(input); - return null; - } + input -> { + idledSessions.add(input); + return null; }; // Wait until pool has initialized. while (pool.totalSessions() < options.getMinSessions()) { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolStressTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolStressTest.java index ad62240e815..cab395d2c25 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolStressTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolStressTest.java @@ -22,13 +22,10 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.cloud.spanner.SessionClient.SessionConsumer; -import com.google.cloud.spanner.SessionPool.PooledSession; import com.google.cloud.spanner.SessionPool.PooledSessionFuture; import com.google.cloud.spanner.SessionPool.SessionConsumerImpl; -import com.google.common.base.Function; import com.google.common.util.concurrent.Uninterruptibles; import com.google.protobuf.ByteString; import com.google.protobuf.Empty; @@ -51,8 +48,6 @@ import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; /** * Stress test for {@code SessionPool} which does multiple operations on the pool, making some of @@ -98,29 +93,26 @@ private void setupSpanner(DatabaseId db) { when(mockSpanner.getSessionClient(db)).thenReturn(sessionClient); when(mockSpanner.getOptions()).thenReturn(spannerOptions); doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - createExecutor.submit( - () -> { - int sessionCount = invocation.getArgumentAt(0, Integer.class); - for (int s = 0; s < sessionCount; s++) { - SessionImpl session; - synchronized (lock) { - session = mockSession(); - setupSession(session); - sessions.put(session.getName(), false); - if (sessions.size() > maxAliveSessions) { - maxAliveSessions = sessions.size(); - } + invocation -> { + createExecutor.submit( + () -> { + int sessionCount = invocation.getArgumentAt(0, Integer.class); + for (int s = 0; s < sessionCount; s++) { + SessionImpl session; + synchronized (lock) { + session = mockSession(); + setupSession(session); + sessions.put(session.getName(), false); + if (sessions.size() > maxAliveSessions) { + maxAliveSessions = sessions.size(); } - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(session); } - }); - return null; - } + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(session); + } + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions( @@ -133,56 +125,45 @@ private void setupSession(final SessionImpl session) { when(session.singleUse(any(TimestampBound.class))).thenReturn(mockContext); when(mockContext.executeQuery(any(Statement.class))) .thenAnswer( - new Answer() { - - @Override - public ResultSet answer(InvocationOnMock invocation) { - resetTransaction(session); - return mockResult; - } + invocation -> { + resetTransaction(session); + return mockResult; }); when(mockResult.next()).thenReturn(true); doAnswer( - new Answer>() { - - @Override - public ApiFuture answer(InvocationOnMock invocation) { - synchronized (lock) { - if (expiredSessions.contains(session.getName())) { - return ApiFutures.immediateFailedFuture( - SpannerExceptionFactoryTest.newSessionNotFoundException(session.getName())); - } - if (sessions.remove(session.getName()) == null) { - setFailed(closedSessions.get(session.getName())); - } - closedSessions.put(session.getName(), new Exception("Session closed at:")); - if (sessions.size() < minSessionsWhenSessionClosed) { - minSessionsWhenSessionClosed = sessions.size(); - } + invocation -> { + synchronized (lock) { + if (expiredSessions.contains(session.getName())) { + return ApiFutures.immediateFailedFuture( + SpannerExceptionFactoryTest.newSessionNotFoundException(session.getName())); + } + if (sessions.remove(session.getName()) == null) { + setFailed(closedSessions.get(session.getName())); + } + closedSessions.put(session.getName(), new Exception("Session closed at:")); + if (sessions.size() < minSessionsWhenSessionClosed) { + minSessionsWhenSessionClosed = sessions.size(); } - return ApiFutures.immediateFuture(Empty.getDefaultInstance()); } + return ApiFutures.immediateFuture(Empty.getDefaultInstance()); }) .when(session) .asyncClose(); doAnswer( - new Answer() { - @Override - public Void answer(InvocationOnMock invocation) { - if (random.nextInt(100) < 10) { - expireSession(session); - throw SpannerExceptionFactoryTest.newSessionNotFoundException(session.getName()); - } - String name = session.getName(); - synchronized (lock) { - if (sessions.put(name, true)) { - setFailed(); - } - session.readyTransactionId = ByteString.copyFromUtf8("foo"); + invocation -> { + if (random.nextInt(100) < 10) { + expireSession(session); + throw SpannerExceptionFactoryTest.newSessionNotFoundException(session.getName()); + } + String name = session.getName(); + synchronized (lock) { + if (sessions.put(name, true)) { + setFailed(); } - return null; + session.readyTransactionId = ByteString.copyFromUtf8("foo"); } + return null; }) .when(session) .prepareReadWriteTransaction(); @@ -239,14 +220,11 @@ public void stressTest() throws Exception { SessionPool.createPool( builder.build(), new TestExecutorFactory(), mockSpanner.getSessionClient(db), clock); pool.idleSessionRemovedListener = - new Function() { - @Override - public Void apply(PooledSession pooled) { - String name = pooled.getName(); - synchronized (lock) { - sessions.remove(name); - return null; - } + pooled -> { + String name = pooled.getName(); + synchronized (lock) { + sessions.remove(name); + return null; } }; for (int i = 0; i < concurrentThreads; i++) { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java index 2c086b5483c..127d51f24d8 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java @@ -72,6 +72,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -89,8 +90,6 @@ import org.junit.runners.Parameterized.Parameters; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; /** Tests for SessionPool that mock out the underlying stub. */ @RunWith(Parameterized.class) @@ -149,20 +148,17 @@ public void setUp() { private void setupMockSessionCreation() { doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - int sessionCount = invocation.getArgumentAt(0, Integer.class); - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - for (int i = 0; i < sessionCount; i++) { - consumer.onSessionReady(mockSession()); - } - }); - return null; - } + invocation -> { + executor.submit( + () -> { + int sessionCount = invocation.getArgumentAt(0, Integer.class); + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + for (int i = 0; i < sessionCount; i++) { + consumer.onSessionReady(mockSession()); + } + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions( @@ -230,17 +226,14 @@ public void poolClosureClosesLeakedSessions() throws Exception { final LinkedList sessions = new LinkedList<>(Arrays.asList(mockSession1, mockSession2)); doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(sessions.pop()); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(sessions.pop()); + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); @@ -281,33 +274,27 @@ public void poolClosureFailsPendingReadWaiters() throws Exception { final SessionImpl session1 = mockSession(); final SessionImpl session2 = mockSession(); doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(session1); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(session1); + }); + return null; }) .doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - insideCreation.countDown(); - releaseCreation.await(); - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(session2); - return null; - }); - return null; - } + invocation -> { + executor.submit( + () -> { + insideCreation.countDown(); + releaseCreation.await(); + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(session2); + return null; + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); @@ -333,33 +320,27 @@ public void poolClosureFailsPendingWriteWaiters() throws Exception { final SessionImpl session1 = mockSession(); final SessionImpl session2 = mockSession(); doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(session1); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(session1); + }); + return null; }) .doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - insideCreation.countDown(); - releaseCreation.await(); - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(session2); - return null; - }); - return null; - } + invocation -> { + executor.submit( + () -> { + insideCreation.countDown(); + releaseCreation.await(); + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(session2); + return null; + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); @@ -383,21 +364,18 @@ public void poolClosesEvenIfCreationFails() throws Exception { final CountDownLatch insideCreation = new CountDownLatch(1); final CountDownLatch releaseCreation = new CountDownLatch(1); doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - insideCreation.countDown(); - releaseCreation.await(); - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionCreateFailure( - SpannerExceptionFactory.newSpannerException(new RuntimeException()), 1); - return null; - }); - return null; - } + invocation -> { + executor.submit( + () -> { + insideCreation.countDown(); + releaseCreation.await(); + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionCreateFailure( + SpannerExceptionFactory.newSpannerException(new RuntimeException()), 1); + return null; + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); @@ -416,17 +394,14 @@ public Void answer(final InvocationOnMock invocation) { public void poolClosureFailsNewRequests() { final SessionImpl session = mockSession(); doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(session); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(session); + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); @@ -463,19 +438,16 @@ public void atMostMaxSessionsCreated() { @Test public void creationExceptionPropagatesToReadSession() { doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionCreateFailure( - SpannerExceptionFactory.newSpannerException(ErrorCode.INTERNAL, ""), 1); - return null; - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionCreateFailure( + SpannerExceptionFactory.newSpannerException(ErrorCode.INTERNAL, ""), 1); + return null; + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); @@ -497,17 +469,14 @@ public void failOnPoolExhaustion() { .setFailIfPoolExhausted() .build(); doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(mockSession()); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(mockSession()); + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); @@ -540,17 +509,14 @@ public void idleSessionCleanup() throws Exception { final LinkedList sessions = new LinkedList<>(Arrays.asList(session1, session2, session3)); doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(sessions.pop()); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(sessions.pop()); + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); @@ -602,20 +568,17 @@ public void keepAlive() throws Exception { // This is cheating as we are returning the same session each but it makes the verification // easier. doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - int sessionCount = invocation.getArgumentAt(0, Integer.class); - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - for (int i = 0; i < sessionCount; i++) { - consumer.onSessionReady(session); - } - }); - return null; - } + invocation -> { + executor.submit( + () -> { + int sessionCount = invocation.getArgumentAt(0, Integer.class); + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + for (int i = 0; i < sessionCount; i++) { + consumer.onSessionReady(session); + } + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions(anyInt(), Mockito.anyBoolean(), any(SessionConsumer.class)); @@ -710,30 +673,24 @@ public void testSessionNotFoundSingleUse() { when(openSession.singleUse()).thenReturn(openContext); doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(closedSession); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(closedSession); + }); + return null; }) .doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(openSession); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(openSession); + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); @@ -760,30 +717,24 @@ public void testSessionNotFoundReadOnlyTransaction() { when(openSession.readOnlyTransaction()).thenReturn(openTransaction); doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(closedSession); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(closedSession); + }); + return null; }) .doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(openSession); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(openSession); + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); @@ -877,30 +828,24 @@ public void testSessionNotFoundReadWriteTransaction() { when(spanner.getSessionClient(db)).thenReturn(sessionClient); doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(closedSession); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(closedSession); + }); + return null; }) .doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(openSession); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(openSession); + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions( @@ -981,7 +926,7 @@ public Integer run(TransactionContext transaction) { public void testSessionNotFoundWrite() { SpannerException sessionNotFound = SpannerExceptionFactoryTest.newSessionNotFoundException(sessionName); - List mutations = Arrays.asList(Mutation.newInsertBuilder("FOO").build()); + List mutations = Collections.singletonList(Mutation.newInsertBuilder("FOO").build()); final SessionImpl closedSession = mockSession(); when(closedSession.writeWithOptions(mutations)).thenThrow(sessionNotFound); @@ -991,30 +936,24 @@ public void testSessionNotFoundWrite() { when(response.getCommitTimestamp()).thenReturn(Timestamp.now()); when(openSession.writeWithOptions(mutations)).thenReturn(response); doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(closedSession); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(closedSession); + }); + return null; }) .doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(openSession); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(openSession); + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); @@ -1030,7 +969,7 @@ public Void answer(final InvocationOnMock invocation) { public void testSessionNotFoundWriteAtLeastOnce() { SpannerException sessionNotFound = SpannerExceptionFactoryTest.newSessionNotFoundException(sessionName); - List mutations = Arrays.asList(Mutation.newInsertBuilder("FOO").build()); + List mutations = Collections.singletonList(Mutation.newInsertBuilder("FOO").build()); final SessionImpl closedSession = mockSession(); when(closedSession.writeAtLeastOnceWithOptions(mutations)).thenThrow(sessionNotFound); @@ -1040,30 +979,24 @@ public void testSessionNotFoundWriteAtLeastOnce() { when(response.getCommitTimestamp()).thenReturn(Timestamp.now()); when(openSession.writeAtLeastOnceWithOptions(mutations)).thenReturn(response); doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(closedSession); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(closedSession); + }); + return null; }) .doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(openSession); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(openSession); + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); @@ -1085,30 +1018,24 @@ public void testSessionNotFoundPartitionedUpdate() { final SessionImpl openSession = mockSession(); when(openSession.executePartitionedUpdate(statement)).thenReturn(1L); doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(closedSession); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(closedSession); + }); + return null; }) .doAnswer( - new Answer() { - @Override - public Void answer(final InvocationOnMock invocation) { - executor.submit( - () -> { - SessionConsumerImpl consumer = - invocation.getArgumentAt(2, SessionConsumerImpl.class); - consumer.onSessionReady(openSession); - }); - return null; - } + invocation -> { + executor.submit( + () -> { + SessionConsumerImpl consumer = + invocation.getArgumentAt(2, SessionConsumerImpl.class); + consumer.onSessionReady(openSession); + }); + return null; }) .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpanTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpanTest.java index 11276c68dcf..7d8a2c1639b 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpanTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpanTest.java @@ -19,10 +19,8 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; -import com.google.api.core.ApiFunction; import com.google.api.gax.grpc.testing.LocalChannelProvider; import com.google.api.gax.retrying.RetrySettings; -import com.google.api.gax.rpc.UnaryCallSettings.Builder; import com.google.cloud.NoCredentials; import com.google.cloud.spanner.MockSpannerServiceImpl.SimulatedExecutionTime; import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult; @@ -172,12 +170,9 @@ public void setUp() throws Exception { builder .getSpannerStubSettingsBuilder() .applyToAllUnaryMethods( - new ApiFunction, Void>() { - @Override - public Void apply(Builder input) { - input.setRetrySettings(retrySettings); - return null; - } + input -> { + input.setRetrySettings(retrySettings); + return null; }); builder .getSpannerStubSettingsBuilder() diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerApiFuturesTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerApiFuturesTest.java index ca2411a23a4..33454da27a1 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerApiFuturesTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerApiFuturesTest.java @@ -83,7 +83,7 @@ public void testGetOtherException() { @Test public void testGetInterruptedException() { ApiFuture fut = - new ForwardingApiFuture(ApiFutures.immediateFuture(null)) { + new ForwardingApiFuture(ApiFutures.immediateFuture(null)) { public Void get() throws InterruptedException { throw new InterruptedException("test interrupted exception"); } @@ -101,8 +101,8 @@ public Void get() throws InterruptedException { @Test public void testGetCancellationException() { ApiFuture fut = - new ForwardingApiFuture(ApiFutures.immediateFuture(null)) { - public Void get() throws InterruptedException { + new ForwardingApiFuture(ApiFutures.immediateFuture(null)) { + public Void get() { throw new CancellationException("test cancellation exception"); } }; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerExceptionFactoryTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerExceptionFactoryTest.java index 49cbfb905d2..2c4801bd0d7 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerExceptionFactoryTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerExceptionFactoryTest.java @@ -149,7 +149,7 @@ public void abortWithRetryInfo() { SpannerException e = SpannerExceptionFactory.newSpannerException(new StatusRuntimeException(status, trailers)); assertThat(e).isInstanceOf(AbortedException.class); - assertThat(((AbortedException) e).getRetryDelayInMillis()).isEqualTo(1001L); + assertThat(e.getRetryDelayInMillis()).isEqualTo(1001L); } @Test @@ -158,7 +158,7 @@ public void abortWithoutRetryInfo() { SpannerException e = SpannerExceptionFactory.newSpannerException(new StatusRuntimeException(status)); assertThat(e).isInstanceOf(AbortedException.class); - assertThat(((AbortedException) e).getRetryDelayInMillis()).isEqualTo(-1L); + assertThat(e.getRetryDelayInMillis()).isEqualTo(-1L); } @Test @@ -170,7 +170,7 @@ public void abortWithoutDuration() { SpannerException e = SpannerExceptionFactory.newSpannerException(new StatusRuntimeException(status, trailers)); assertThat(e).isInstanceOf(AbortedException.class); - assertThat(((AbortedException) e).getRetryDelayInMillis()).isEqualTo(-1L); + assertThat(e.getRetryDelayInMillis()).isEqualTo(-1L); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerGaxRetryTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerGaxRetryTest.java index 6773f8a5b57..a227719e0b5 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerGaxRetryTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerGaxRetryTest.java @@ -22,11 +22,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -import com.google.api.core.ApiFunction; import com.google.api.gax.grpc.testing.LocalChannelProvider; import com.google.api.gax.retrying.RetrySettings; -import com.google.api.gax.rpc.UnaryCallSettings; -import com.google.api.gax.rpc.UnaryCallSettings.Builder; import com.google.cloud.NoCredentials; import com.google.cloud.spanner.MockSpannerServiceImpl.SimulatedExecutionTime; import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult; @@ -161,12 +158,9 @@ public void setUp() throws Exception { builder .getSpannerStubSettingsBuilder() .applyToAllUnaryMethods( - new ApiFunction, Void>() { - @Override - public Void apply(Builder input) { - input.setRetrySettings(retrySettings); - return null; - } + input -> { + input.setRetrySettings(retrySettings); + return null; }); builder .getSpannerStubSettingsBuilder() diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerImplTest.java index aafd88390c0..2040f795366 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerImplTest.java @@ -64,7 +64,7 @@ public void setUp() { when(spannerOptions.getPrefetchChunks()).thenReturn(1); when(spannerOptions.getRetrySettings()).thenReturn(RetrySettings.newBuilder().build()); when(spannerOptions.getClock()).thenReturn(NanoClock.getDefaultClock()); - when(spannerOptions.getSessionLabels()).thenReturn(Collections.emptyMap()); + when(spannerOptions.getSessionLabels()).thenReturn(Collections.emptyMap()); impl = new SpannerImpl(rpc, spannerOptions); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java index fbfd468d349..15bc446f0b4 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java @@ -50,6 +50,7 @@ import com.google.spanner.v1.RollbackRequest; import com.google.spanner.v1.SpannerGrpc; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -140,7 +141,7 @@ public void testSpannerDefaultRetrySettings() { List> callsWithRetry1 = Arrays.asList(stubSettings.listSessionsSettings(), stubSettings.commitSettings()); List> callsWithRetry2 = - Arrays.asList(stubSettings.batchCreateSessionsSettings()); + Collections.singletonList(stubSettings.batchCreateSessionsSettings()); List> callsWithRetry3 = Arrays.asList( stubSettings.createSessionSettings(), @@ -276,7 +277,7 @@ public void testDatabaseAdminDefaultRetrySettings() { stubSettings.getDatabaseSettings(), stubSettings.getDatabaseDdlSettings()); List> callsWithRetryPolicy2 = - Arrays.asList(stubSettings.getIamPolicySettings()); + Collections.singletonList(stubSettings.getIamPolicySettings()); List> callsWithNoRetry2 = Arrays.asList( stubSettings.setIamPolicySettings(), stubSettings.testIamPermissionsSettings()); @@ -375,7 +376,7 @@ public void testInstanceAdminDefaultRetrySettings() { stubSettings.getInstanceSettings(), stubSettings.listInstancesSettings()); List> callsWithRetryPolicy2 = - Arrays.asList(stubSettings.getIamPolicySettings()); + Collections.singletonList(stubSettings.getIamPolicySettings()); List> callsWithNoRetryPolicy1 = Arrays.asList(stubSettings.createInstanceSettings(), stubSettings.updateInstanceSettings()); List> callsWithNoRetryPolicy2 = @@ -558,13 +559,7 @@ public void testSetEmulatorHostWithProtocol() { @Test public void testDefaultQueryOptions() { - SpannerOptions.useEnvironment( - new SpannerOptions.SpannerEnvironment() { - @Override - public String getOptimizerVersion() { - return ""; - } - }); + SpannerOptions.useEnvironment(() -> ""); SpannerOptions options = SpannerOptions.newBuilder() .setDefaultQueryOptions( @@ -579,13 +574,7 @@ public String getOptimizerVersion() { .isEqualTo(QueryOptions.getDefaultInstance()); // Now simulate that the user has set an environment variable for the query optimizer version. - SpannerOptions.useEnvironment( - new SpannerOptions.SpannerEnvironment() { - @Override - public String getOptimizerVersion() { - return "2"; - } - }); + SpannerOptions.useEnvironment(() -> "2"); // Create options with '1' as the default query optimizer version. This should be overridden by // the environment variable. options = diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsThreadTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsThreadTest.java index 8626f5cb5c8..91919b15234 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsThreadTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsThreadTest.java @@ -18,7 +18,6 @@ import static com.google.common.truth.Truth.assertThat; -import com.google.api.core.ApiFunction; import com.google.cloud.NoCredentials; import com.google.cloud.spanner.connection.AbstractMockServerTest; import com.google.common.base.Stopwatch; @@ -48,19 +47,11 @@ public class SpannerOptionsThreadTest extends AbstractMockServerTest { private final DatabaseId dbId = DatabaseId.of("p", "i", "d"); - @SuppressWarnings("rawtypes") private SpannerOptions createOptions() { return SpannerOptions.newBuilder() .setProjectId("p") // Set a custom channel configurator to allow http instead of https. - .setChannelConfigurator( - new ApiFunction() { - @Override - public ManagedChannelBuilder apply(ManagedChannelBuilder input) { - input.usePlaintext(); - return input; - } - }) + .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) .setHost("http://localhost:" + getPort()) .setCredentials(NoCredentials.getInstance()) .build(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerRetryHelperTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerRetryHelperTest.java index f0b79554618..4b5640c548a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerRetryHelperTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerRetryHelperTest.java @@ -218,6 +218,7 @@ public void testExceptionWithRetryInfo() { try { Thread.sleep(Long.MAX_VALUE); } catch (InterruptedException e) { + // Ignored exception } } }); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/StandardBenchmarkMockServer.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/StandardBenchmarkMockServer.java index bb733d3f52b..4fce617a15e 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/StandardBenchmarkMockServer.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/StandardBenchmarkMockServer.java @@ -21,7 +21,6 @@ import com.google.cloud.spanner.MockSpannerServiceImpl.SimulatedExecutionTime; import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult; import com.google.cloud.spanner.connection.RandomResultSetGenerator; -import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import com.google.protobuf.AbstractMessage; import com.google.protobuf.ListValue; @@ -131,14 +130,7 @@ MockSpannerServiceImpl getMockSpanner() { } int countRequests(final Class type) { - return Collections2.filter( - mockSpanner.getRequests(), - new Predicate() { - @Override - public boolean apply(AbstractMessage input) { - return input.getClass().equals(type); - } - }) + return Collections2.filter(mockSpanner.getRequests(), input -> input.getClass().equals(type)) .size(); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionContextImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionContextImplTest.java index 1ca9e0e6673..369385478d8 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionContextImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionContextImplTest.java @@ -31,7 +31,7 @@ import com.google.spanner.v1.CommitRequest; import com.google.spanner.v1.ExecuteBatchDmlRequest; import com.google.spanner.v1.ExecuteBatchDmlResponse; -import java.util.Arrays; +import java.util.Collections; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -99,7 +99,7 @@ private void batchDml(int status) { .setTransactionId(ByteString.copyFromUtf8("test")) .setOptions(Options.fromTransactionOptions()) .build()) { - impl.batchUpdate(Arrays.asList(statement)); + impl.batchUpdate(Collections.singletonList(statement)); } } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerAbortedTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerAbortedTest.java index 8917d2d2e54..a437b41ddb4 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerAbortedTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerAbortedTest.java @@ -37,6 +37,7 @@ import io.grpc.inprocess.InProcessServerBuilder; import java.io.IOException; import java.util.Arrays; +import java.util.Collections; import java.util.concurrent.ScheduledThreadPoolExecutor; import org.junit.After; import org.junit.AfterClass; @@ -130,10 +131,14 @@ public static void startStaticServer() throws IOException { mockSpanner = new MockSpannerServiceImpl(); mockSpanner.setAbortProbability(0.0D); // We don't want any unpredictable aborted transactions. mockSpanner.putStatementResult( - StatementResult.read("FOO", KeySet.all(), Arrays.asList("BAR"), READ_RESULTSET)); + StatementResult.read( + "FOO", KeySet.all(), Collections.singletonList("BAR"), READ_RESULTSET)); mockSpanner.putStatementResult( StatementResult.read( - "FOO", KeySet.singleKey(Key.of()), Arrays.asList("BAR"), READ_ROW_RESULTSET)); + "FOO", + KeySet.singleKey(Key.of()), + Collections.singletonList("BAR"), + READ_ROW_RESULTSET)); mockSpanner.putStatementResult(StatementResult.query(SELECT1AND2, SELECT1AND2_RESULTSET)); mockSpanner.putStatementResult(StatementResult.update(UPDATE_STATEMENT, UPDATE_COUNT)); mockSpanner.putStatementResult( @@ -335,7 +340,7 @@ public void testTransactionManagerAbortOnRead() throws InterruptedException { if (attempts == 1) { mockSpanner.abortNextTransaction(); } - try (ResultSet rs = txn.read("FOO", KeySet.all(), Arrays.asList("BAR"))) { + try (ResultSet rs = txn.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { int rows = 0; while (rs.next()) { rows++; @@ -368,7 +373,7 @@ public void testTransactionManagerAbortOnReadUsingIndex() throws InterruptedExce mockSpanner.abortNextTransaction(); } try (ResultSet rs = - txn.readUsingIndex("FOO", "INDEX", KeySet.all(), Arrays.asList("BAR"))) { + txn.readUsingIndex("FOO", "INDEX", KeySet.all(), Collections.singletonList("BAR"))) { int rows = 0; while (rs.next()) { rows++; @@ -400,7 +405,7 @@ public void testTransactionManagerAbortOnReadRow() throws InterruptedException { if (attempts == 1) { mockSpanner.abortNextTransaction(); } - Struct row = txn.readRow("FOO", Key.of(), Arrays.asList("BAR")); + Struct row = txn.readRow("FOO", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0), is(equalTo(1L))); manager.commit(); break; @@ -427,7 +432,8 @@ public void testTransactionManagerAbortOnReadRowUsingIndex() throws InterruptedE if (attempts == 1) { mockSpanner.abortNextTransaction(); } - Struct row = txn.readRowUsingIndex("FOO", "INDEX", Key.of(), Arrays.asList("BAR")); + Struct row = + txn.readRowUsingIndex("FOO", "INDEX", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0), is(equalTo(1L))); manager.commit(); break; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerImplTest.java index 4ffed254cb6..6e2fa03960d 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerImplTest.java @@ -26,7 +26,6 @@ import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; -import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.cloud.Timestamp; import com.google.cloud.grpc.GrpcTransportOptions; @@ -39,13 +38,13 @@ import com.google.spanner.v1.CommitRequest; import com.google.spanner.v1.ExecuteSqlRequest; import com.google.spanner.v1.ExecuteSqlRequest.QueryOptions; +import com.google.spanner.v1.ResultSet; import com.google.spanner.v1.ResultSetMetadata; import com.google.spanner.v1.ResultSetStats; +import com.google.spanner.v1.Session; import com.google.spanner.v1.Transaction; import io.opencensus.trace.Span; -import java.util.Arrays; import java.util.Collections; -import java.util.List; import java.util.UUID; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -56,8 +55,6 @@ import org.junit.runners.JUnit4; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; @RunWith(JUnit4.class) public class TransactionManagerImplTest { @@ -234,50 +231,37 @@ public void usesPreparedTransaction() { SessionPoolOptions sessionPoolOptions = SessionPoolOptions.newBuilder().setMinSessions(0).setIncStep(1).build(); when(options.getSessionPoolOptions()).thenReturn(sessionPoolOptions); - when(options.getSessionLabels()).thenReturn(Collections.emptyMap()); + when(options.getSessionLabels()).thenReturn(Collections.emptyMap()); SpannerRpc rpc = mock(SpannerRpc.class); when(rpc.asyncDeleteSession(Mockito.anyString(), Mockito.anyMap())) .thenReturn(ApiFutures.immediateFuture(Empty.getDefaultInstance())); when(rpc.batchCreateSessions( Mockito.anyString(), Mockito.eq(1), Mockito.anyMap(), Mockito.anyMap())) .thenAnswer( - new Answer>() { - @Override - public List answer(InvocationOnMock invocation) { - return Arrays.asList( - com.google.spanner.v1.Session.newBuilder() - .setName((String) invocation.getArguments()[0] + "/sessions/1") + invocation -> + Collections.singletonList( + Session.newBuilder() + .setName(invocation.getArguments()[0] + "/sessions/1") .setCreateTime( com.google.protobuf.Timestamp.newBuilder() .setSeconds(System.currentTimeMillis() * 1000)) - .build()); - } - }); + .build())); when(rpc.beginTransactionAsync(Mockito.any(BeginTransactionRequest.class), Mockito.anyMap())) .thenAnswer( - new Answer>() { - @Override - public ApiFuture answer(InvocationOnMock invocation) { - return ApiFutures.immediateFuture( + invocation -> + ApiFutures.immediateFuture( Transaction.newBuilder() .setId(ByteString.copyFromUtf8(UUID.randomUUID().toString())) - .build()); - } - }); + .build())); when(rpc.commitAsync(Mockito.any(CommitRequest.class), Mockito.anyMap())) .thenAnswer( - new Answer>() { - @Override - public ApiFuture answer( - InvocationOnMock invocation) throws Throwable { - return ApiFutures.immediateFuture( + invocation -> + ApiFutures.immediateFuture( com.google.spanner.v1.CommitResponse.newBuilder() .setCommitTimestamp( com.google.protobuf.Timestamp.newBuilder() .setSeconds(System.currentTimeMillis() * 1000)) - .build()); - } - }); + .build())); DatabaseId db = DatabaseId.of("test", "test", "test"); try (SpannerImpl spanner = new SpannerImpl(rpc, options)) { DatabaseClient client = spanner.getDatabaseClient(db); @@ -301,7 +285,7 @@ public void inlineBegin() { SessionPoolOptions sessionPoolOptions = SessionPoolOptions.newBuilder().setMinSessions(0).setIncStep(1).build(); when(options.getSessionPoolOptions()).thenReturn(sessionPoolOptions); - when(options.getSessionLabels()).thenReturn(Collections.emptyMap()); + when(options.getSessionLabels()).thenReturn(Collections.emptyMap()); when(options.getDefaultQueryOptions(Mockito.any(DatabaseId.class))) .thenReturn(QueryOptions.getDefaultInstance()); SpannerRpc rpc = mock(SpannerRpc.class); @@ -310,68 +294,50 @@ public void inlineBegin() { when(rpc.batchCreateSessions( Mockito.anyString(), Mockito.eq(1), Mockito.anyMap(), Mockito.anyMap())) .thenAnswer( - new Answer>() { - @Override - public List answer(InvocationOnMock invocation) - throws Throwable { - return Arrays.asList( - com.google.spanner.v1.Session.newBuilder() - .setName((String) invocation.getArguments()[0] + "/sessions/1") + invocation -> + Collections.singletonList( + Session.newBuilder() + .setName(invocation.getArguments()[0] + "/sessions/1") .setCreateTime( com.google.protobuf.Timestamp.newBuilder() .setSeconds(System.currentTimeMillis() * 1000)) - .build()); - } - }); + .build())); when(rpc.beginTransactionAsync(Mockito.any(BeginTransactionRequest.class), Mockito.anyMap())) .thenAnswer( - new Answer>() { - @Override - public ApiFuture answer(InvocationOnMock invocation) throws Throwable { - return ApiFutures.immediateFuture( + invocation -> + ApiFutures.immediateFuture( Transaction.newBuilder() .setId(ByteString.copyFromUtf8(UUID.randomUUID().toString())) - .build()); - } - }); + .build())); final AtomicInteger transactionsStarted = new AtomicInteger(); when(rpc.executeQuery(Mockito.any(ExecuteSqlRequest.class), Mockito.anyMap())) .thenAnswer( - new Answer() { - @Override - public com.google.spanner.v1.ResultSet answer(InvocationOnMock invocation) - throws Throwable { - com.google.spanner.v1.ResultSet.Builder builder = - com.google.spanner.v1.ResultSet.newBuilder() - .setStats(ResultSetStats.newBuilder().setRowCountExact(1L).build()); - ExecuteSqlRequest request = invocation.getArgumentAt(0, ExecuteSqlRequest.class); - if (request.getTransaction() != null && request.getTransaction().hasBegin()) { - transactionsStarted.incrementAndGet(); - builder.setMetadata( - ResultSetMetadata.newBuilder() - .setTransaction( - Transaction.newBuilder() - .setId(ByteString.copyFromUtf8("test-tx")) - .build()) - .build()); - } - return builder.build(); + invocation -> { + ResultSet.Builder builder = + ResultSet.newBuilder() + .setStats(ResultSetStats.newBuilder().setRowCountExact(1L).build()); + ExecuteSqlRequest request = invocation.getArgumentAt(0, ExecuteSqlRequest.class); + if (request.getTransaction() != null && request.getTransaction().hasBegin()) { + transactionsStarted.incrementAndGet(); + builder.setMetadata( + ResultSetMetadata.newBuilder() + .setTransaction( + Transaction.newBuilder() + .setId(ByteString.copyFromUtf8("test-tx")) + .build()) + .build()); } + return builder.build(); }); when(rpc.commitAsync(Mockito.any(CommitRequest.class), Mockito.anyMap())) .thenAnswer( - new Answer>() { - @Override - public ApiFuture answer( - InvocationOnMock invocation) throws Throwable { - return ApiFutures.immediateFuture( + invocation -> + ApiFutures.immediateFuture( com.google.spanner.v1.CommitResponse.newBuilder() .setCommitTimestamp( com.google.protobuf.Timestamp.newBuilder() .setSeconds(System.currentTimeMillis() * 1000)) - .build()); - } - }); + .build())); DatabaseId db = DatabaseId.of("test", "test", "test"); try (SpannerImpl spanner = new SpannerImpl(rpc, options)) { DatabaseClient client = spanner.getDatabaseClient(db); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionRunnerImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionRunnerImplTest.java index de3794c26d3..4398c8c864f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionRunnerImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionRunnerImplTest.java @@ -25,7 +25,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.cloud.grpc.GrpcTransportOptions; import com.google.cloud.grpc.GrpcTransportOptions.ExecutorFactory; @@ -50,6 +49,7 @@ import com.google.spanner.v1.ResultSetMetadata; import com.google.spanner.v1.ResultSetStats; import com.google.spanner.v1.RollbackRequest; +import com.google.spanner.v1.Session; import com.google.spanner.v1.Transaction; import io.grpc.Metadata; import io.grpc.Status; @@ -58,7 +58,6 @@ import io.opencensus.trace.Span; import java.util.Arrays; import java.util.Collections; -import java.util.List; import java.util.UUID; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -70,8 +69,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; /** Unit test for {@link com.google.cloud.spanner.SpannerImpl.TransactionRunnerImpl} */ @RunWith(JUnit4.class) @@ -103,24 +100,21 @@ public void setUp() { when(session.newTransaction(Options.fromTransactionOptions())).thenReturn(txn); when(rpc.executeQuery(Mockito.any(ExecuteSqlRequest.class), Mockito.anyMap())) .thenAnswer( - new Answer() { - @Override - public ResultSet answer(InvocationOnMock invocation) throws Throwable { - ResultSet.Builder builder = - ResultSet.newBuilder() - .setStats(ResultSetStats.newBuilder().setRowCountExact(1L).build()); - ExecuteSqlRequest request = invocation.getArgumentAt(0, ExecuteSqlRequest.class); - if (request.getTransaction().hasBegin() - && request.getTransaction().getBegin().hasReadWrite()) { - builder.setMetadata( - ResultSetMetadata.newBuilder() - .setTransaction( - Transaction.newBuilder().setId(ByteString.copyFromUtf8("test"))) - .build()); - usedInlinedBegin = true; - } - return builder.build(); + invocation -> { + ResultSet.Builder builder = + ResultSet.newBuilder() + .setStats(ResultSetStats.newBuilder().setRowCountExact(1L).build()); + ExecuteSqlRequest request = invocation.getArgumentAt(0, ExecuteSqlRequest.class); + if (request.getTransaction().hasBegin() + && request.getTransaction().getBegin().hasReadWrite()) { + builder.setMetadata( + ResultSetMetadata.newBuilder() + .setTransaction( + Transaction.newBuilder().setId(ByteString.copyFromUtf8("test"))) + .build()); + usedInlinedBegin = true; } + return builder.build(); }); transactionRunner = new TransactionRunnerImpl(session); when(rpc.commitAsync(Mockito.any(CommitRequest.class), Mockito.anyMap())) @@ -145,48 +139,35 @@ public void usesPreparedTransaction() { SessionPoolOptions sessionPoolOptions = SessionPoolOptions.newBuilder().setMinSessions(0).setIncStep(1).build(); when(options.getSessionPoolOptions()).thenReturn(sessionPoolOptions); - when(options.getSessionLabels()).thenReturn(Collections.emptyMap()); + when(options.getSessionLabels()).thenReturn(Collections.emptyMap()); SpannerRpc rpc = mock(SpannerRpc.class); when(rpc.asyncDeleteSession(Mockito.anyString(), Mockito.anyMap())) .thenReturn(ApiFutures.immediateFuture(Empty.getDefaultInstance())); when(rpc.batchCreateSessions( Mockito.anyString(), Mockito.eq(1), Mockito.anyMap(), Mockito.anyMap())) .thenAnswer( - new Answer>() { - @Override - public List answer(InvocationOnMock invocation) { - return Arrays.asList( - com.google.spanner.v1.Session.newBuilder() - .setName((String) invocation.getArguments()[0] + "/sessions/1") + invocation -> + Collections.singletonList( + Session.newBuilder() + .setName(invocation.getArguments()[0] + "/sessions/1") .setCreateTime( Timestamp.newBuilder().setSeconds(System.currentTimeMillis() * 1000)) - .build()); - } - }); + .build())); when(rpc.beginTransactionAsync(Mockito.any(BeginTransactionRequest.class), Mockito.anyMap())) .thenAnswer( - new Answer>() { - @Override - public ApiFuture answer(InvocationOnMock invocation) { - return ApiFutures.immediateFuture( + invocation -> + ApiFutures.immediateFuture( Transaction.newBuilder() .setId(ByteString.copyFromUtf8(UUID.randomUUID().toString())) - .build()); - } - }); + .build())); when(rpc.commitAsync(Mockito.any(CommitRequest.class), Mockito.anyMap())) .thenAnswer( - new Answer>() { - @Override - public ApiFuture answer(InvocationOnMock invocation) - throws Throwable { - return ApiFutures.immediateFuture( + invocation -> + ApiFutures.immediateFuture( CommitResponse.newBuilder() .setCommitTimestamp( Timestamp.newBuilder().setSeconds(System.currentTimeMillis() * 1000)) - .build()); - } - }); + .build())); DatabaseId db = DatabaseId.of("test", "test", "test"); try (SpannerImpl spanner = new SpannerImpl(rpc, options)) { DatabaseClient client = spanner.getDatabaseClient(db); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueBinderTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueBinderTest.java index 4681d80970b..d171a46acb9 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueBinderTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueBinderTest.java @@ -27,6 +27,7 @@ import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.util.Arrays; +import java.util.Collections; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -67,8 +68,9 @@ public void reflection() throws InvocationTargetException, IllegalAccessExceptio // Array of structs. assertThat(binderMethod.getParameterTypes()).hasLength(2); - Value expected = (Value) method.invoke(Value.class, structType, Arrays.asList(struct)); - assertThat(binderMethod.invoke(binder, structType, Arrays.asList(struct))) + Value expected = + (Value) method.invoke(Value.class, structType, Collections.singletonList(struct)); + assertThat(binderMethod.invoke(binder, structType, Collections.singletonList(struct))) .isEqualTo(lastReturnValue); assertThat(lastValue).isEqualTo(expected); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java index 8692e92e825..15a22e61cda 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java @@ -36,7 +36,7 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; -import java.util.Iterator; +import java.util.Collections; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; @@ -54,13 +54,7 @@ private static ByteArray newByteArray(String data) { /** Returns an {@code Iterable} over {@code values} that is not a {@code Collection}. */ @SafeVarargs private static Iterable plainIterable(T... values) { - final List list = Lists.newArrayList(values); - return new Iterable() { - @Override - public Iterator iterator() { - return list.iterator(); - } - }; + return Lists.newArrayList(values); } @Test @@ -569,7 +563,7 @@ public void boolArrayFromPlainIterable() { @Test public void boolArrayTryGetInt64Array() { - Value value = Value.boolArray(Arrays.asList(true)); + Value value = Value.boolArray(Collections.singletonList(true)); try { value.getInt64Array(); fail("Expected exception"); @@ -630,7 +624,7 @@ public void int64ArrayWrapperNull() { @Test public void int64ArrayTryGetBool() { - Value value = Value.int64Array(Arrays.asList(1234L)); + Value value = Value.int64Array(Collections.singletonList(1234L)); try { value.getBool(); fail("Expected exception"); @@ -702,7 +696,7 @@ public void float64ArrayWrapperNull() { @Test public void float64ArrayTryGetInt64Array() { - Value value = Value.float64Array(Arrays.asList(.1)); + Value value = Value.float64Array(Collections.singletonList(.1)); try { value.getInt64Array(); fail("Expected exception"); @@ -724,7 +718,7 @@ public void numericArray() { @Test public void numericArrayNull() { - Value v = Value.numericArray((Iterable) null); + Value v = Value.numericArray(null); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); @@ -738,7 +732,7 @@ public void numericArrayNull() { @Test public void numericArrayTryGetInt64Array() { - Value value = Value.numericArray(Arrays.asList(BigDecimal.valueOf(1, 1))); + Value value = Value.numericArray(Collections.singletonList(BigDecimal.valueOf(1, 1))); try { value.getInt64Array(); @@ -771,7 +765,7 @@ public void stringArrayNull() { @Test public void stringArrayTryGetBytesArray() { - Value value = Value.stringArray(Arrays.asList("a")); + Value value = Value.stringArray(Collections.singletonList("a")); try { value.getBytesArray(); fail("Expected exception"); @@ -805,7 +799,7 @@ public void bytesArrayNull() { @Test public void bytesArrayTryGetStringArray() { - Value value = Value.bytesArray(Arrays.asList(newByteArray("a"))); + Value value = Value.bytesArray(Collections.singletonList(newByteArray("a"))); try { value.getStringArray(); fail("Expected exception"); @@ -879,7 +873,8 @@ public void struct() { Value v2 = Value.struct(struct.getType(), struct); assertThat(v2).isEqualTo(v1); try { - Value.struct(Type.struct(Arrays.asList(StructField.of("f3", Type.string()))), struct); + Value.struct( + Type.struct(Collections.singletonList(StructField.of("f3", Type.string()))), struct); fail("Expected exception"); } catch (IllegalArgumentException e) { assertThat(e.getMessage().contains("Mismatch between struct value and type.")); @@ -1449,7 +1444,7 @@ public void testEqualsHashCode() { tester.addEqualityGroup(Value.struct(structValue1), Value.struct(structValue2)); Type structType1 = structValue1.getType(); - Type structType2 = Type.struct(Arrays.asList(StructField.of("f1", Type.string()))); + Type structType2 = Type.struct(Collections.singletonList(StructField.of("f1", Type.string()))); tester.addEqualityGroup(Value.struct(structType1, null), Value.struct(structType1, null)); tester.addEqualityGroup(Value.struct(structType2, null), Value.struct(structType2, null)); @@ -1458,7 +1453,7 @@ public void testEqualsHashCode() { Value.boolArray(new boolean[] {false, true}), Value.boolArray(new boolean[] {true, false, true, false}, 1, 2), Value.boolArray(plainIterable(false, true))); - tester.addEqualityGroup(Value.boolArray(Arrays.asList(false))); + tester.addEqualityGroup(Value.boolArray(Collections.singletonList(false))); tester.addEqualityGroup(Value.boolArray((Iterable) null)); tester.addEqualityGroup( @@ -1466,7 +1461,7 @@ public void testEqualsHashCode() { Value.int64Array(new long[] {1L, 2L}), Value.int64Array(new long[] {0L, 1L, 2L, 3L}, 1, 2), Value.int64Array(plainIterable(1L, 2L))); - tester.addEqualityGroup(Value.int64Array(Arrays.asList(3L))); + tester.addEqualityGroup(Value.int64Array(Collections.singletonList(3L))); tester.addEqualityGroup(Value.int64Array((Iterable) null)); tester.addEqualityGroup( @@ -1474,23 +1469,24 @@ public void testEqualsHashCode() { Value.float64Array(new double[] {.1, .2}), Value.float64Array(new double[] {.0, .1, .2, .3}, 1, 2), Value.float64Array(plainIterable(.1, .2))); - tester.addEqualityGroup(Value.float64Array(Arrays.asList(.3))); + tester.addEqualityGroup(Value.float64Array(Collections.singletonList(.3))); tester.addEqualityGroup(Value.float64Array((Iterable) null)); tester.addEqualityGroup( Value.numericArray(Arrays.asList(BigDecimal.valueOf(1, 1), BigDecimal.valueOf(2, 1)))); - tester.addEqualityGroup(Value.numericArray(Arrays.asList(BigDecimal.valueOf(3, 1)))); - tester.addEqualityGroup(Value.numericArray((Iterable) null)); + tester.addEqualityGroup( + Value.numericArray(Collections.singletonList(BigDecimal.valueOf(3, 1)))); + tester.addEqualityGroup(Value.numericArray(null)); tester.addEqualityGroup( Value.stringArray(Arrays.asList("a", "b")), Value.stringArray(Arrays.asList("a", "b"))); - tester.addEqualityGroup(Value.stringArray(Arrays.asList("c"))); + tester.addEqualityGroup(Value.stringArray(Collections.singletonList("c"))); tester.addEqualityGroup(Value.stringArray(null)); tester.addEqualityGroup( Value.bytesArray(Arrays.asList(newByteArray("a"), newByteArray("b"))), Value.bytesArray(Arrays.asList(newByteArray("a"), newByteArray("b")))); - tester.addEqualityGroup(Value.bytesArray(Arrays.asList(newByteArray("c")))); + tester.addEqualityGroup(Value.bytesArray(Collections.singletonList(newByteArray("c")))); tester.addEqualityGroup(Value.bytesArray(null)); tester.addEqualityGroup( @@ -1507,8 +1503,8 @@ public void testEqualsHashCode() { Value.structArray(structType1, Arrays.asList(structValue1, null)), Value.structArray(structType1, Arrays.asList(structValue2, null))); tester.addEqualityGroup( - Value.structArray(structType1, Arrays.asList((Struct) null)), - Value.structArray(structType1, Arrays.asList((Struct) null))); + Value.structArray(structType1, Collections.singletonList(null)), + Value.structArray(structType1, Collections.singletonList(null))); tester.addEqualityGroup( Value.structArray(structType1, null), Value.structArray(structType1, null)); tester.addEqualityGroup( @@ -1569,7 +1565,7 @@ public void serialization() { Value.numericArray( BrokenSerializationList.of( BigDecimal.valueOf(1, 1), BigDecimal.valueOf(2, 1), BigDecimal.valueOf(3, 1)))); - reserializeAndAssert(Value.numericArray((Iterable) null)); + reserializeAndAssert(Value.numericArray(null)); reserializeAndAssert(Value.timestamp(null)); reserializeAndAssert(Value.timestamp(Value.COMMIT_TIMESTAMP)); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbortedTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbortedTest.java index 88401ef1bc0..1703d987adc 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbortedTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbortedTest.java @@ -38,7 +38,7 @@ import com.google.spanner.v1.ExecuteSqlRequest; import io.grpc.Status; import io.grpc.StatusRuntimeException; -import java.util.Arrays; +import java.util.Collections; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -150,7 +150,7 @@ public void testAbortedDuringRetryOfFailedBatchUpdate() { createConnection(createAbortFirstRetryListener(invalidStatement, notFound))) { connection.execute(INSERT_STATEMENT); try { - connection.executeBatchUpdate(Arrays.asList(invalidStatement)); + connection.executeBatchUpdate(Collections.singletonList(invalidStatement)); fail("missing expected exception"); } catch (SpannerException e) { assertThat(e.getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); @@ -230,7 +230,7 @@ public void testAbortedDuringRetryOfFailedBatchUpdateAsFirstStatement() { try (ITConnection connection = createConnection(createAbortFirstRetryListener(invalidStatement, notFound))) { try { - connection.executeBatchUpdate(Arrays.asList(invalidStatement)); + connection.executeBatchUpdate(Collections.singletonList(invalidStatement)); fail("missing expected exception"); } catch (SpannerException e) { assertThat(e.getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); @@ -246,8 +246,7 @@ public void testAbortedDuringRetryOfFailedBatchUpdateAsFirstStatement() { ITConnection createConnection(TransactionRetryListener listener) { ITConnection connection = - super.createConnection( - ImmutableList.of(), ImmutableList.of(listener)); + super.createConnection(ImmutableList.of(), ImmutableList.of(listener)); connection.setAutocommit(false); return connection; } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractConnectionImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractConnectionImplTest.java index 9d17398207d..7cfc4dd9142 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractConnectionImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractConnectionImplTest.java @@ -39,6 +39,7 @@ import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; import org.junit.AfterClass; @@ -262,24 +263,18 @@ public void testStartBatchDml() { expectSpannerException( "Select should not be allowed after startBatchDml()", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - log("@EXPECT EXCEPTION FAILED_PRECONDITION"); - log(SELECT + ";"); - t.execute(Statement.of(SELECT)); - } + t -> { + log("@EXPECT EXCEPTION FAILED_PRECONDITION"); + log(SELECT + ";"); + t.execute(Statement.of(SELECT)); }, connection); expectSpannerException( "DDL should not be allowed after startBatchDml()", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - log("@EXPECT EXCEPTION FAILED_PRECONDITION"); - log(DDL + ";"); - t.execute(Statement.of(DDL)); - } + t -> { + log("@EXPECT EXCEPTION FAILED_PRECONDITION"); + log(DDL + ";"); + t.execute(Statement.of(DDL)); }, connection); log(UPDATE + ";"); @@ -312,24 +307,18 @@ public void testStartBatchDdl() { expectSpannerException( "Select should not be allowed after startBatchDdl()", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - log("@EXPECT EXCEPTION FAILED_PRECONDITION"); - log(SELECT + ";"); - t.execute(Statement.of(SELECT)); - } + t -> { + log("@EXPECT EXCEPTION FAILED_PRECONDITION"); + log(SELECT + ";"); + t.execute(Statement.of(SELECT)); }, connection); expectSpannerException( "Update should not be allowed after startBatchDdl()", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - log("@EXPECT EXCEPTION FAILED_PRECONDITION"); - log(UPDATE + ";"); - t.execute(Statement.of(UPDATE)); - } + t -> { + log("@EXPECT EXCEPTION FAILED_PRECONDITION"); + log(UPDATE + ";"); + t.execute(Statement.of(UPDATE)); }, connection); log(DDL + ";"); @@ -399,13 +388,10 @@ public void testBeginTransaction() { } else { expectSpannerException( "Select should not be allowed after beginTransaction", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - log("@EXPECT EXCEPTION FAILED_PRECONDITION"); - log(SELECT + ";"); - t.execute(Statement.of(SELECT)); - } + t -> { + log("@EXPECT EXCEPTION FAILED_PRECONDITION"); + log(SELECT + ";"); + t.execute(Statement.of(SELECT)); }, connection); } @@ -415,13 +401,10 @@ public void accept(Connection t) { } else { expectSpannerException( "Update should not be allowed after beginTransaction", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - log("@EXPECT EXCEPTION FAILED_PRECONDITION"); - log(UPDATE + ";"); - t.execute(Statement.of(UPDATE)); - } + t -> { + log("@EXPECT EXCEPTION FAILED_PRECONDITION"); + log(UPDATE + ";"); + t.execute(Statement.of(UPDATE)); }, connection); } @@ -431,13 +414,10 @@ public void accept(Connection t) { } else { expectSpannerException( "DDL should not be allowed after beginTransaction", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - log("@EXPECT EXCEPTION FAILED_PRECONDITION"); - log(DDL + ";"); - t.execute(Statement.of(DDL)); - } + t -> { + log("@EXPECT EXCEPTION FAILED_PRECONDITION"); + log(DDL + ";"); + t.execute(Statement.of(DDL)); }, connection); } @@ -469,13 +449,10 @@ private void testSetTransactionMode(final TransactionMode mode) { } else { expectSpannerException( mode + " should not be allowed", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - log("@EXPECT EXCEPTION FAILED_PRECONDITION"); - log("SET TRANSACTION " + mode.getStatementString() + ";"); - t.setTransactionMode(mode); - } + t -> { + log("@EXPECT EXCEPTION FAILED_PRECONDITION"); + log("SET TRANSACTION " + mode.getStatementString() + ";"); + t.setTransactionMode(mode); }, connection); } @@ -577,16 +554,13 @@ private void testSetReadOnlyStaleness(final TimestampBound staleness) { } else { expectSpannerException( staleness.getMode() + " should not be allowed", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - log("@EXPECT EXCEPTION FAILED_PRECONDITION"); - log( - "SET READ_ONLY_STALENESS='" - + ReadOnlyStalenessUtil.timestampBoundToString(staleness) - + "';"); - t.setReadOnlyStaleness(staleness); - } + t -> { + log("@EXPECT EXCEPTION FAILED_PRECONDITION"); + log( + "SET READ_ONLY_STALENESS='" + + ReadOnlyStalenessUtil.timestampBoundToString(staleness) + + "';"); + t.setReadOnlyStaleness(staleness); }, connection); } @@ -772,13 +746,10 @@ private void testExecute(final StatementType type) { } else { expectSpannerException( type + " should not be allowed", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - log("@EXPECT EXCEPTION FAILED_PRECONDITION"); - log(getTestStatement(type).getSql() + ";"); - t.execute(getTestStatement(type)); - } + t -> { + log("@EXPECT EXCEPTION FAILED_PRECONDITION"); + log(getTestStatement(type).getSql() + ";"); + t.execute(getTestStatement(type)); }, connection); } @@ -820,25 +791,17 @@ private void testExecuteQuery(final StatementType type) { // it is a query, but queries are not allowed for this connection state expectSpannerException( type + " should not be allowed", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - log("@EXPECT EXCEPTION FAILED_PRECONDITION"); - log(getTestStatement(type).getSql() + ";"); - t.executeQuery(getTestStatement(type)); - } + t -> { + log("@EXPECT EXCEPTION FAILED_PRECONDITION"); + log(getTestStatement(type).getSql() + ";"); + t.executeQuery(getTestStatement(type)); }, connection, ErrorCode.FAILED_PRECONDITION); } else { expectSpannerException( type + " should be an invalid argument", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - t.executeQuery(getTestStatement(type)); - } - }, + t -> t.executeQuery(getTestStatement(type)), connection, ErrorCode.INVALID_ARGUMENT); } @@ -867,23 +830,13 @@ private void testAnalyzeQuery(final StatementType type) { // it is a query, but queries are not allowed for this connection state expectSpannerException( type + " should not be allowed", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - t.analyzeQuery(getTestStatement(type), currentMode); - } - }, + t -> t.analyzeQuery(getTestStatement(type), currentMode), connection, ErrorCode.FAILED_PRECONDITION); } else { expectSpannerException( type + " should be an invalid argument", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - t.analyzeQuery(getTestStatement(type), currentMode); - } - }, + t -> t.analyzeQuery(getTestStatement(type), currentMode), connection, ErrorCode.INVALID_ARGUMENT); } @@ -909,25 +862,17 @@ private void testExecuteUpdate(final StatementType type) { // it is an update statement, but updates are not allowed for this connection state expectSpannerException( type + "should not be allowed", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - log("@EXPECT EXCEPTION FAILED_PRECONDITION"); - log(getTestStatement(type).getSql() + ";"); - t.executeUpdate(getTestStatement(type)); - } + t -> { + log("@EXPECT EXCEPTION FAILED_PRECONDITION"); + log(getTestStatement(type).getSql() + ";"); + t.executeUpdate(getTestStatement(type)); }, connection, ErrorCode.FAILED_PRECONDITION); } else { expectSpannerException( type + " should be an invalid argument", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - t.executeUpdate(getTestStatement(type)); - } - }, + t -> t.executeUpdate(getTestStatement(type)), connection, ErrorCode.INVALID_ARGUMENT); } @@ -952,7 +897,7 @@ public void testWriteIterable() { if (!isWriteAllowed() || !connection.isAutocommit()) { exception.expect(matchCode(ErrorCode.FAILED_PRECONDITION)); } - connection.write(Arrays.asList(createTestMutation())); + connection.write(Collections.singletonList(createTestMutation())); } } @@ -972,7 +917,7 @@ public void testBufferedWriteIterable() { if (!isWriteAllowed() || connection.isAutocommit()) { exception.expect(matchCode(ErrorCode.FAILED_PRECONDITION)); } - connection.bufferedWrite(Arrays.asList(createTestMutation())); + connection.bufferedWrite(Collections.singletonList(createTestMutation())); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractMockServerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractMockServerTest.java index 112621f8533..154384e2e5b 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractMockServerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractMockServerTest.java @@ -49,7 +49,6 @@ import java.net.InetSocketAddress; import java.sql.DriverManager; import java.sql.SQLException; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; @@ -156,7 +155,7 @@ public void getOperation( } @AfterClass - public static void stopServer() throws Exception { + public static void stopServer() { server.shutdown(); } @@ -204,25 +203,22 @@ protected java.sql.Connection createJdbcConnection() throws SQLException { } ITConnection createConnection() { - return createConnection( - Collections.emptyList(), - Collections.emptyList()); + return createConnection(Collections.emptyList(), Collections.emptyList()); } ITConnection createConnection( AbortInterceptor interceptor, TransactionRetryListener transactionRetryListener) { return createConnection( - Arrays.asList(interceptor), - Arrays.asList(transactionRetryListener)); + Collections.singletonList(interceptor), + Collections.singletonList(transactionRetryListener)); } ITConnection createConnection( List interceptors, List transactionRetryListeners) { - StringBuilder url = new StringBuilder(getBaseUrl()); ConnectionOptions.Builder builder = ConnectionOptions.newBuilder() - .setUri(url.toString()) + .setUri(getBaseUrl()) .setStatementExecutionInterceptors(interceptors); ConnectionOptions options = builder.build(); ITConnection connection = createITConnection(options); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AsyncStatementResultImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AsyncStatementResultImplTest.java index 53c3e1a1fcb..0a47e3ea2df 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AsyncStatementResultImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AsyncStatementResultImplTest.java @@ -36,7 +36,7 @@ public class AsyncStatementResultImplTest { @Test public void testNoResultGetResultSetAsync() { AsyncStatementResult subject = - AsyncStatementResultImpl.noResult(ApiFutures.immediateFuture(null)); + AsyncStatementResultImpl.noResult(ApiFutures.immediateFuture(null)); assertThat(subject.getResultType()).isEqualTo(ResultType.NO_RESULT); try { subject.getResultSetAsync(); @@ -49,7 +49,7 @@ public void testNoResultGetResultSetAsync() { @Test public void testNoResultGetUpdateCountAsync() { AsyncStatementResult subject = - AsyncStatementResultImpl.noResult(ApiFutures.immediateFuture(null)); + AsyncStatementResultImpl.noResult(ApiFutures.immediateFuture(null)); assertThat(subject.getResultType()).isEqualTo(ResultType.NO_RESULT); try { subject.getUpdateCountAsync(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AutocommitDmlModeTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AutocommitDmlModeTest.java index 301619ab761..e5e4b41b756 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AutocommitDmlModeTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AutocommitDmlModeTest.java @@ -35,8 +35,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; @RunWith(JUnit4.class) public class AutocommitDmlModeTest { @@ -60,13 +58,10 @@ private ConnectionImpl createConnection(ConnectionOptions options) { when(dbClient.readWriteTransaction()).thenReturn(txRunner); when(txRunner.run(any(TransactionCallable.class))) .thenAnswer( - new Answer() { - @Override - public Long answer(InvocationOnMock invocation) throws Throwable { - TransactionCallable callable = - (TransactionCallable) invocation.getArguments()[0]; - return callable.run(txContext); - } + invocation -> { + TransactionCallable callable = + (TransactionCallable) invocation.getArguments()[0]; + return callable.run(txContext); }); TransactionManager txManager = mock(TransactionManager.class); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionAsyncApiAbortedTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionAsyncApiAbortedTest.java index 812ed83fc00..8aac69acdf8 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionAsyncApiAbortedTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionAsyncApiAbortedTest.java @@ -33,7 +33,6 @@ import com.google.cloud.spanner.SpannerExceptionFactory; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.connection.ITAbstractSpannerTest.ITConnection; -import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; @@ -115,8 +114,7 @@ public void reset() { ITConnection createConnection(TransactionRetryListener listener) { ITConnection connection = - super.createConnection( - ImmutableList.of(), ImmutableList.of(listener)); + super.createConnection(ImmutableList.of(), ImmutableList.of(listener)); connection.setAutocommit(false); return connection; } @@ -291,7 +289,7 @@ public CallbackResponse cursorReady(AsyncResultSet resultSet) { // Wait until the query has actually executed. queryLatch.await(10L, TimeUnit.SECONDS); ApiFuture updateCount = connection.executeUpdateAsync(INSERT_STATEMENT); - updateCount.addListener(() -> updateLatch.countDown(), MoreExecutors.directExecutor()); + updateCount.addListener(updateLatch::countDown, MoreExecutors.directExecutor()); // We should not commit before the AsyncResultSet has finished. assertThat(get(finished)).isNull(); @@ -306,13 +304,7 @@ public CallbackResponse cursorReady(AsyncResultSet resultSet) { List requests = Lists.newArrayList( Collections2.filter( - mockSpanner.getRequests(), - new Predicate() { - @Override - public boolean apply(AbstractMessage input) { - return input instanceof ExecuteSqlRequest; - } - })); + mockSpanner.getRequests(), input -> input instanceof ExecuteSqlRequest)); // The entire transaction should be retried. assertThat(requests).hasSize(4); assertThat(((ExecuteSqlRequest) requests.get(0)).getSeqno()).isEqualTo(1L); @@ -348,27 +340,24 @@ public void testUpdateAndQueryAbortedMidway_UpdateCountChanged() throws Interrup finished = rs.setCallback( singleThreadedExecutor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - // Indicate that the query has been executed. - queryLatch.countDown(); - try { - // Wait until the update is on its way. - updateLatch.await(10L, TimeUnit.SECONDS); - while (true) { - switch (resultSet.tryNext()) { - case OK: - break; - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - } + resultSet -> { + // Indicate that the query has been executed. + queryLatch.countDown(); + try { + // Wait until the update is on its way. + updateLatch.await(10L, TimeUnit.SECONDS); + while (true) { + switch (resultSet.tryNext()) { + case OK: + break; + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; } - } catch (InterruptedException e) { - throw SpannerExceptionFactory.propagateInterrupt(e); } + } catch (InterruptedException e) { + throw SpannerExceptionFactory.propagateInterrupt(e); } }); } @@ -395,13 +384,7 @@ public CallbackResponse cursorReady(AsyncResultSet resultSet) { List requests = Lists.newArrayList( Collections2.filter( - mockSpanner.getRequests(), - new Predicate() { - @Override - public boolean apply(AbstractMessage input) { - return input instanceof ExecuteSqlRequest; - } - })); + mockSpanner.getRequests(), input -> input instanceof ExecuteSqlRequest)); // The entire transaction should be retried, but will not succeed as the result of the update // statement was different during the retry. assertThat(requests).hasSize(4); @@ -421,7 +404,7 @@ public boolean apply(AbstractMessage input) { } @Test - public void testQueriesAbortedMidway_ResultsChanged() throws InterruptedException { + public void testQueriesAbortedMidway_ResultsChanged() { mockSpanner.setExecuteStreamingSqlExecutionTime( SimulatedExecutionTime.ofStreamException( mockSpanner.createAbortedException(ByteString.copyFromUtf8("test")), @@ -440,24 +423,21 @@ public void testQueriesAbortedMidway_ResultsChanged() throws InterruptedExceptio res1 = rs.setCallback( multiThreadedExecutor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - latch.await(10L, TimeUnit.SECONDS); - while (true) { - switch (resultSet.tryNext()) { - case OK: - break; - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - } + resultSet -> { + try { + latch.await(10L, TimeUnit.SECONDS); + while (true) { + switch (resultSet.tryNext()) { + case OK: + break; + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; } - } catch (Throwable t) { - throw SpannerExceptionFactory.asSpannerException(t); } + } catch (Throwable t) { + throw SpannerExceptionFactory.asSpannerException(t); } }); } @@ -591,13 +571,10 @@ public void testBlindUpdateAborted_ThenAsyncQuery_WithConcurrentModification() { ApiFuture fut = rs.setCallback( singleThreadedExecutor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - // The following line should throw AbortedDueToConcurrentModificationException. - resultSet.tryNext(); - return CallbackResponse.DONE; - } + resultSet -> { + // The following line should throw AbortedDueToConcurrentModificationException. + resultSet.tryNext(); + return CallbackResponse.DONE; }); try { assertThat(get(fut)).isNull(); @@ -613,12 +590,9 @@ public CallbackResponse cursorReady(AsyncResultSet resultSet) { ApiFuture fut = rs.setCallback( singleThreadedExecutor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - resultSet.tryNext(); - return CallbackResponse.DONE; - } + resultSet -> { + resultSet.tryNext(); + return CallbackResponse.DONE; }); assertThat(get(fut)).isNull(); } @@ -668,19 +642,16 @@ private QueryResult executeQueryAsync( res = rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case OK: - rowCount.incrementAndGet(); - break; - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - } + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case OK: + rowCount.incrementAndGet(); + break; + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; } } }); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionAsyncApiTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionAsyncApiTest.java index 39d33ae1cae..ca16259f68b 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionAsyncApiTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionAsyncApiTest.java @@ -34,7 +34,6 @@ import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.connection.StatementResult.ResultType; import com.google.common.base.Function; -import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; @@ -57,28 +56,16 @@ public class ConnectionAsyncApiTest extends AbstractMockServerTest { private static final ExecutorService executor = Executors.newSingleThreadExecutor(); private static final Function AUTOCOMMIT = - new Function() { - @Override - public Void apply(Connection input) { - input.setAutocommit(true); - return null; - } + input -> { + input.setAutocommit(true); + return null; }; private static final Function READ_ONLY = - new Function() { - @Override - public Void apply(Connection input) { - input.setReadOnly(true); - return null; - } - }; - private static final Function READ_WRITE = - new Function() { - @Override - public Void apply(Connection input) { - return null; - } + input -> { + input.setReadOnly(true); + return null; }; + private static final Function READ_WRITE = input -> null; @AfterClass public static void stopExecutor() { @@ -282,13 +269,9 @@ public CallbackResponse cursorReady(AsyncResultSet resultSet) { Lists.newArrayList( Collections2.filter( mockSpanner.getRequests(), - new Predicate() { - @Override - public boolean apply(AbstractMessage input) { - return input instanceof ExecuteSqlRequest - || input instanceof ExecuteBatchDmlRequest; - } - })); + input -> + input instanceof ExecuteSqlRequest + || input instanceof ExecuteBatchDmlRequest)); assertThat(requests).hasSize(4); assertThat(requests.get(0)).isInstanceOf(ExecuteSqlRequest.class); assertThat(((ExecuteSqlRequest) requests.get(0)).getSeqno()).isEqualTo(1L); @@ -361,18 +344,15 @@ public void testExecuteClientSideQueryAsync() { connection.executeQueryAsync(Statement.of("SHOW VARIABLE AUTOCOMMIT"))) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - autocommit.set(resultSet.getBoolean("AUTOCOMMIT")); - } + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + autocommit.set(resultSet.getBoolean("AUTOCOMMIT")); } } }); @@ -453,25 +433,22 @@ private void testExecuteQueryAsync( res = rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - while (true) { - switch (resultSet.tryNext()) { - case OK: - rowCount.incrementAndGet(); - break; - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - } + resultSet -> { + try { + while (true) { + switch (resultSet.tryNext()) { + case OK: + rowCount.incrementAndGet(); + break; + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; } - } catch (SpannerException e) { - receivedTimeout.set(e.getErrorCode() == ErrorCode.DEADLINE_EXCEEDED); - throw e; } + } catch (SpannerException e) { + receivedTimeout.set(e.getErrorCode() == ErrorCode.DEADLINE_EXCEEDED); + throw e; } }); } @@ -777,19 +754,16 @@ private void testExecuteQueryAsyncIsNonBlocking( res = rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case OK: - rowCount.incrementAndGet(); - break; - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - } + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case OK: + rowCount.incrementAndGet(); + break; + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; } } }); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTest.java index 41782eecb40..a24231030b4 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTest.java @@ -48,7 +48,6 @@ import com.google.cloud.spanner.ForwardingResultSet; import com.google.cloud.spanner.Options; import com.google.cloud.spanner.Options.QueryOption; -import com.google.cloud.spanner.Options.TransactionOption; import com.google.cloud.spanner.ReadContext.QueryAnalyzeMode; import com.google.cloud.spanner.ReadOnlyTransaction; import com.google.cloud.spanner.ResultSet; @@ -62,7 +61,6 @@ import com.google.cloud.spanner.TransactionManager; import com.google.cloud.spanner.TransactionRunner; import com.google.cloud.spanner.Type; -import com.google.cloud.spanner.connection.AbstractConnectionImplTest.ConnectionConsumer; import com.google.cloud.spanner.connection.ConnectionImpl.UnitOfWorkType; import com.google.cloud.spanner.connection.ConnectionStatementExecutorImpl.StatementTimeoutGetter; import com.google.cloud.spanner.connection.ReadOnlyStalenessUtil.GetExactStaleness; @@ -236,15 +234,12 @@ public static ConnectionImpl createConnection(final ConnectionOptions options) { final SimpleResultSet select1ResultSetWithStats = new SimpleResultSet(mockResultSetWithStats); when(singleUseReadOnlyTx.executeQuery(Statement.of(SELECT))) .thenAnswer( - new Answer() { - @Override - public ResultSet answer(InvocationOnMock invocation) { - if (select1ResultSet.nextCalled) { - // create a new mock - return new SimpleResultSet(createSelect1MockResultSet()); - } - return select1ResultSet; + invocation -> { + if (select1ResultSet.nextCalled) { + // create a new mock + return new SimpleResultSet(createSelect1MockResultSet()); } + return select1ResultSet; }); when(singleUseReadOnlyTx.analyzeQuery(Statement.of(SELECT), QueryAnalyzeMode.PLAN)) .thenReturn(select1ResultSetWithStats); @@ -252,84 +247,66 @@ public ResultSet answer(InvocationOnMock invocation) { .thenReturn(select1ResultSetWithStats); when(singleUseReadOnlyTx.getReadTimestamp()) .then( - new Answer() { - @Override - public Timestamp answer(InvocationOnMock invocation) { - if (select1ResultSet.isNextCalled() || select1ResultSetWithStats.isNextCalled()) { - return Timestamp.now(); - } - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.FAILED_PRECONDITION, "No query has returned with any data yet"); + invocation -> { + if (select1ResultSet.isNextCalled() || select1ResultSetWithStats.isNextCalled()) { + return Timestamp.now(); } + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.FAILED_PRECONDITION, "No query has returned with any data yet"); }); when(dbClient.singleUseReadOnlyTransaction(Matchers.any(TimestampBound.class))) .thenReturn(singleUseReadOnlyTx); - when(dbClient.transactionManager((TransactionOption[]) Mockito.anyVararg())) + when(dbClient.transactionManager(Mockito.anyVararg())) .thenAnswer( - new Answer() { - @Override - public TransactionManager answer(InvocationOnMock invocation) { - TransactionContext txContext = mock(TransactionContext.class); - when(txContext.executeQuery(Statement.of(SELECT))) - .thenAnswer( - new Answer() { - @Override - public ResultSet answer(InvocationOnMock invocation) { - if (select1ResultSet.nextCalled) { - // create a new mock - return new SimpleResultSet(createSelect1MockResultSet()); - } - return select1ResultSet; - } - }); - when(txContext.analyzeQuery(Statement.of(SELECT), QueryAnalyzeMode.PLAN)) - .thenReturn(select1ResultSetWithStats); - when(txContext.analyzeQuery(Statement.of(SELECT), QueryAnalyzeMode.PROFILE)) - .thenReturn(select1ResultSetWithStats); - when(txContext.executeUpdate(Statement.of(UPDATE))).thenReturn(1L); - return new SimpleTransactionManager(txContext, options.isReturnCommitStats()); - } + invocation -> { + TransactionContext txContext = mock(TransactionContext.class); + when(txContext.executeQuery(Statement.of(SELECT))) + .thenAnswer( + ignored -> { + if (select1ResultSet.nextCalled) { + // create a new mock + return new SimpleResultSet(createSelect1MockResultSet()); + } + return select1ResultSet; + }); + when(txContext.analyzeQuery(Statement.of(SELECT), QueryAnalyzeMode.PLAN)) + .thenReturn(select1ResultSetWithStats); + when(txContext.analyzeQuery(Statement.of(SELECT), QueryAnalyzeMode.PROFILE)) + .thenReturn(select1ResultSetWithStats); + when(txContext.executeUpdate(Statement.of(UPDATE))).thenReturn(1L); + return new SimpleTransactionManager(txContext, options.isReturnCommitStats()); }); when(dbClient.readOnlyTransaction(Matchers.any(TimestampBound.class))) .thenAnswer( - new Answer() { - @Override - public ReadOnlyTransaction answer(InvocationOnMock invocation) { - ReadOnlyTransaction tx = mock(ReadOnlyTransaction.class); - when(tx.executeQuery(Statement.of(SELECT))) - .thenAnswer( - new Answer() { - @Override - public ResultSet answer(InvocationOnMock invocation) { - if (select1ResultSet.nextCalled) { - // create a new mock - return new SimpleResultSet(createSelect1MockResultSet()); - } - return select1ResultSet; - } - }); - when(tx.analyzeQuery(Statement.of(SELECT), QueryAnalyzeMode.PLAN)) - .thenReturn(select1ResultSetWithStats); - when(tx.analyzeQuery(Statement.of(SELECT), QueryAnalyzeMode.PROFILE)) - .thenReturn(select1ResultSetWithStats); - when(tx.getReadTimestamp()) - .then( - new Answer() { - @Override - public Timestamp answer(InvocationOnMock invocation) { - if (select1ResultSet.isNextCalled() - || select1ResultSetWithStats.isNextCalled()) { - return Timestamp.now(); - } - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.FAILED_PRECONDITION, - "No query has returned with any data yet"); - } - }); - return tx; - } + invocation -> { + ReadOnlyTransaction tx = mock(ReadOnlyTransaction.class); + when(tx.executeQuery(Statement.of(SELECT))) + .thenAnswer( + ignored -> { + if (select1ResultSet.nextCalled) { + // create a new mock + return new SimpleResultSet(createSelect1MockResultSet()); + } + return select1ResultSet; + }); + when(tx.analyzeQuery(Statement.of(SELECT), QueryAnalyzeMode.PLAN)) + .thenReturn(select1ResultSetWithStats); + when(tx.analyzeQuery(Statement.of(SELECT), QueryAnalyzeMode.PROFILE)) + .thenReturn(select1ResultSetWithStats); + when(tx.getReadTimestamp()) + .then( + ignored -> { + if (select1ResultSet.isNextCalled() + || select1ResultSetWithStats.isNextCalled()) { + return Timestamp.now(); + } + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.FAILED_PRECONDITION, + "No query has returned with any data yet"); + }); + return tx; }); when(dbClient.readWriteTransaction()) @@ -421,7 +398,7 @@ public void testExecuteGetAutocommit() { assertThat(res.getResultSet().getBoolean("AUTOCOMMIT"), is(true)); // set autocommit to false and assert that autocommit is false - res = subject.execute(Statement.of("set autocommit = false")); + subject.execute(Statement.of("set autocommit = false")); assertThat(subject.isAutocommit(), is(false)); res = subject.execute(Statement.of("show variable autocommit")); assertThat(res.getResultType(), is(equalTo(ResultType.RESULT_SET))); @@ -479,7 +456,7 @@ public void testExecuteGetReadOnly() { assertThat(res.getResultSet().getBoolean("READONLY"), is(false)); // set read only to true and assert that read only is true - res = subject.execute(Statement.of("set readonly = true")); + subject.execute(Statement.of("set readonly = true")); assertThat(subject.isReadOnly(), is(true)); res = subject.execute(Statement.of("show variable readonly")); assertThat(res.getResultType(), is(equalTo(ResultType.RESULT_SET))); @@ -1227,12 +1204,7 @@ public void testChangeReadOnlyModeInAutocommit() { subject.setReadOnly(true); expectSpannerException( "Updates should not be allowed in read-only mode", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - t.execute(Statement.of(UPDATE)); - } - }, + connection -> connection.execute(Statement.of(UPDATE)), subject); assertThat(subject.executeQuery(Statement.of(SELECT)), is(notNullValue())); @@ -1245,12 +1217,7 @@ public void accept(Connection t) { subject.setReadOnly(true); expectSpannerException( "DDL should not be allowed in read-only mode", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - t.execute(Statement.of(DDL)); - } - }, + connection -> connection.execute(Statement.of(DDL)), subject); assertThat(subject.executeQuery(Statement.of(SELECT)), is(notNullValue())); } @@ -1274,12 +1241,7 @@ public void testChangeReadOnlyModeInTransactionalMode() { subject.setReadOnly(true); expectSpannerException( "Updates should not be allowed in read-only mode", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - t.execute(Statement.of(UPDATE)); - } - }, + connection -> connection.execute(Statement.of(UPDATE)), subject); assertThat(subject.executeQuery(Statement.of(SELECT)), is(notNullValue())); subject.commit(); @@ -1294,12 +1256,7 @@ public void accept(Connection t) { subject.setReadOnly(true); expectSpannerException( "DDL should not be allowed in read-only mode", - new ConnectionConsumer() { - @Override - public void accept(Connection t) { - t.execute(Statement.of(DDL)); - } - }, + connection -> connection.execute(Statement.of(DDL)), subject); assertThat(subject.executeQuery(Statement.of(SELECT)), is(notNullValue())); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java index 3ab5bbddb46..8584970b103 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java @@ -28,6 +28,7 @@ import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerOptions; import java.util.Arrays; +import java.util.Collections; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -250,6 +251,7 @@ private void setInvalidUri(ConnectionOptions.Builder builder, String uri) { builder.setUri(uri); fail(uri + " should be considered an invalid uri"); } catch (IllegalArgumentException e) { + // Expected exception } } @@ -325,7 +327,7 @@ public void testParseProperties() { final String baseUri = "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database"; assertThat(ConnectionOptions.parseProperties(baseUri + "?autocommit=true")) - .isEqualTo(Arrays.asList("autocommit")); + .isEqualTo(Collections.singletonList("autocommit")); assertThat(ConnectionOptions.parseProperties(baseUri + "?autocommit=true;readonly=false")) .isEqualTo(Arrays.asList("autocommit", "readonly")); assertThat(ConnectionOptions.parseProperties(baseUri + "?autocommit=true;READONLY=false")) @@ -443,12 +445,11 @@ public void testLenient() { assertThat(options.getWarnings()).doesNotContain("lenient"); try { - options = - ConnectionOptions.newBuilder() - .setUri( - "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database?bar=foo") - .setCredentialsUrl(FILE_TEST_PATH) - .build(); + ConnectionOptions.newBuilder() + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database?bar=foo") + .setCredentialsUrl(FILE_TEST_PATH) + .build(); fail("missing expected exception"); } catch (IllegalArgumentException e) { assertThat(e.getMessage()).contains("bar"); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionTest.java index 4a26721fe8f..38d182cc540 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionTest.java @@ -27,9 +27,7 @@ import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerOptions; import com.google.cloud.spanner.Statement; -import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; -import com.google.protobuf.AbstractMessage; import com.google.spanner.v1.BatchCreateSessionsRequest; import com.google.spanner.v1.ExecuteSqlRequest; import com.google.spanner.v1.ExecuteSqlRequest.QueryOptions; @@ -61,13 +59,7 @@ public void testDefaultOptimizerVersion() { @Test public void testUseOptimizerVersionFromEnvironment() { try { - SpannerOptions.useEnvironment( - new SpannerOptions.SpannerEnvironment() { - @Override - public String getOptimizerVersion() { - return "20"; - } - }); + SpannerOptions.useEnvironment(() -> "20"); try (Connection connection = createConnection()) { // Do a query and verify that the version from the environment is used. try (ResultSet rs = connection.executeQuery(SELECT_COUNT_STATEMENT)) { @@ -204,13 +196,9 @@ protected String getBaseUrl() { public void testMinSessions() throws InterruptedException, TimeoutException { try (Connection connection = createConnection()) { mockSpanner.waitForRequestsToContain( - new Predicate() { - @Override - public boolean apply(AbstractMessage input) { - return input instanceof BatchCreateSessionsRequest - && ((BatchCreateSessionsRequest) input).getSessionCount() == 1; - } - }, + input -> + input instanceof BatchCreateSessionsRequest + && ((BatchCreateSessionsRequest) input).getSessionCount() == 1, 5000L); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlBatchTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlBatchTest.java index 7a5e9adb16f..00ad2a42305 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlBatchTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlBatchTest.java @@ -61,8 +61,6 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.mockito.ArgumentMatcher; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; @RunWith(JUnit4.class) public class DdlBatchTest { @@ -89,12 +87,9 @@ private DdlClient createDefaultMockDdlClient( if (waitForMillis > 0L) { when(operation.get()) .thenAnswer( - new Answer() { - @Override - public Void answer(InvocationOnMock invocation) throws Throwable { - Thread.sleep(waitForMillis); - return null; - } + invocation -> { + Thread.sleep(waitForMillis); + return null; }); } else if (exceptionOnGetResult) { when(operation.get()) @@ -229,7 +224,7 @@ public void testGetReadTimestamp() { public void testWriteIterable() { DdlBatch batch = createSubject(); try { - batch.writeAsync(Arrays.asList(Mutation.newInsertBuilder("foo").build())); + batch.writeAsync(Collections.singletonList(Mutation.newInsertBuilder("foo").build())); fail("expected FAILED_PRECONDITION"); } catch (SpannerException e) { assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlClientTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlClientTest.java index 782f7032984..f7070b150b0 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlClientTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlClientTest.java @@ -27,6 +27,7 @@ import com.google.cloud.spanner.DatabaseAdminClient; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; import org.junit.Test; @@ -59,7 +60,7 @@ public void testExecuteDdl() throws InterruptedException, ExecutionException { DdlClient subject = createSubject(client); String ddl = "CREATE TABLE FOO"; subject.executeDdl(ddl); - verify(client).updateDatabaseDdl(instanceId, databaseId, Arrays.asList(ddl), null); + verify(client).updateDatabaseDdl(instanceId, databaseId, Collections.singletonList(ddl), null); subject = createSubject(client); List ddlList = Arrays.asList("CREATE TABLE FOO", "DROP TABLE FOO"); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DirectExecuteResultSetTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DirectExecuteResultSetTest.java index 74bfb2e9a69..9695794805e 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DirectExecuteResultSetTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DirectExecuteResultSetTest.java @@ -32,6 +32,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; @@ -44,7 +45,7 @@ private DirectExecuteResultSet createSubject() { ResultSet delegate = ResultSets.forRows( Type.struct(StructField.of("test", Type.int64())), - Arrays.asList(Struct.newBuilder().set("test").to(1L).build())); + Collections.singletonList(Struct.newBuilder().set("test").to(1L).build())); return DirectExecuteResultSet.ofResultSet(delegate); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DmlBatchTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DmlBatchTest.java index 4bb4ba99ca9..821c9d95f61 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DmlBatchTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DmlBatchTest.java @@ -35,6 +35,7 @@ import com.google.cloud.spanner.connection.StatementParser.StatementType; import com.google.cloud.spanner.connection.UnitOfWork.UnitOfWorkState; import java.util.Arrays; +import java.util.Collections; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -136,7 +137,7 @@ public void testGetCommitResponseOrNull() { public void testWriteIterable() { DmlBatch batch = createSubject(); try { - batch.writeAsync(Arrays.asList(Mutation.newInsertBuilder("foo").build())); + batch.writeAsync(Collections.singletonList(Mutation.newInsertBuilder("foo").build())); fail("Expected exception"); } catch (SpannerException e) { assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); @@ -161,7 +162,7 @@ public void testGetStateAndIsActive() { UnitOfWork tx = mock(UnitOfWork.class); when(tx.executeBatchUpdateAsync(anyListOf(ParsedStatement.class))) - .thenReturn(ApiFutures.immediateFailedFuture(mock(SpannerException.class))); + .thenReturn(ApiFutures.immediateFailedFuture(mock(SpannerException.class))); batch = createSubject(tx); assertThat(batch.getState(), is(UnitOfWorkState.STARTED)); assertThat(batch.isActive(), is(true)); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/EmulatorUtilTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/EmulatorUtilTest.java index 94aea2adeec..e9f9a70ab7f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/EmulatorUtilTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/EmulatorUtilTest.java @@ -77,7 +77,7 @@ public void testCreateInstanceAndDatabase_bothSucceed() when(databaseClient.createDatabase( Matchers.eq("test-instance"), Matchers.eq("test-database"), - Matchers.eq(ImmutableList.of()))) + Matchers.eq(ImmutableList.of()))) .thenReturn(databaseOperationFuture); when(databaseOperationFuture.get()).thenReturn(mock(Database.class)); @@ -92,8 +92,7 @@ public void testCreateInstanceAndDatabase_bothSucceed() .setInstanceConfigId(InstanceConfigId.of("test-project", "emulator-config")) .setNodeCount(1) .build()); - verify(databaseClient) - .createDatabase("test-instance", "test-database", ImmutableList.of()); + verify(databaseClient).createDatabase("test-instance", "test-database", ImmutableList.of()); } @Test @@ -127,7 +126,7 @@ public void testCreateInstanceAndDatabase_bothFailWithAlreadyExists() when(databaseClient.createDatabase( Matchers.eq("test-instance"), Matchers.eq("test-database"), - Matchers.eq(ImmutableList.of()))) + Matchers.eq(ImmutableList.of()))) .thenReturn(databaseOperationFuture); when(databaseOperationFuture.get()) .thenThrow( @@ -146,8 +145,7 @@ public void testCreateInstanceAndDatabase_bothFailWithAlreadyExists() .setInstanceConfigId(InstanceConfigId.of("test-project", "emulator-config")) .setNodeCount(1) .build()); - verify(databaseClient) - .createDatabase("test-instance", "test-database", ImmutableList.of()); + verify(databaseClient).createDatabase("test-instance", "test-database", ImmutableList.of()); } @Test @@ -235,7 +233,7 @@ public void testCreateInstanceAndDatabase_propagatesOtherErrorsOnDatabaseCreatio when(databaseClient.createDatabase( Matchers.eq("test-instance"), Matchers.eq("test-database"), - Matchers.eq(ImmutableList.of()))) + Matchers.eq(ImmutableList.of()))) .thenReturn(databaseOperationFuture); when(databaseOperationFuture.get()) .thenThrow( @@ -279,7 +277,7 @@ public void testCreateInstanceAndDatabase_propagatesInterruptsOnDatabaseCreation when(databaseClient.createDatabase( Matchers.eq("test-instance"), Matchers.eq("test-database"), - Matchers.eq(ImmutableList.of()))) + Matchers.eq(ImmutableList.of()))) .thenReturn(databaseOperationFuture); when(databaseOperationFuture.get()).thenThrow(new InterruptedException()); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ITAbstractSpannerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ITAbstractSpannerTest.java index fc7ba382bf7..0a16b102097 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ITAbstractSpannerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ITAbstractSpannerTest.java @@ -41,7 +41,6 @@ import java.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Paths; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; @@ -236,22 +235,18 @@ public static void teardown() { * @return the newly opened connection. */ public ITConnection createConnection() { - return createConnection( - Collections.emptyList(), - Collections.emptyList()); + return createConnection(Collections.emptyList(), Collections.emptyList()); } public ITConnection createConnection(AbortInterceptor interceptor) { - return createConnection( - Arrays.asList(interceptor), - Collections.emptyList()); + return createConnection(Collections.singletonList(interceptor), Collections.emptyList()); } public ITConnection createConnection( AbortInterceptor interceptor, TransactionRetryListener transactionRetryListener) { return createConnection( - Arrays.asList(interceptor), - Arrays.asList(transactionRetryListener)); + Collections.singletonList(interceptor), + Collections.singletonList(transactionRetryListener)); } /** diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/RandomResultSetGenerator.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/RandomResultSetGenerator.java index 1560aea76d2..2cda94baadc 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/RandomResultSetGenerator.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/RandomResultSetGenerator.java @@ -81,7 +81,7 @@ public class RandomResultSetGenerator { .build(), }; - private static final ResultSetMetadata generateMetadata() { + private static ResultSetMetadata generateMetadata() { StructType.Builder rowTypeBuilder = StructType.newBuilder(); for (int col = 0; col < TYPES.length; col++) { rowTypeBuilder.addFields(Field.newBuilder().setName("COL" + col).setType(TYPES[col])).build(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadWriteTransactionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadWriteTransactionTest.java index e1b124a2368..1d74a209c5f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadWriteTransactionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadWriteTransactionTest.java @@ -62,8 +62,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; @RunWith(JUnit4.class) public class ReadWriteTransactionTest { @@ -156,24 +154,20 @@ private ReadWriteTransaction createSubject( DatabaseClient client = mock(DatabaseClient.class); when(client.transactionManager()) .thenAnswer( - new Answer() { - @Override - public TransactionManager answer(InvocationOnMock invocation) { - TransactionContext txContext = mock(TransactionContext.class); - when(txContext.executeQuery(any(Statement.class))) - .thenReturn(mock(ResultSet.class)); - ResultSet rsWithStats = mock(ResultSet.class); - when(rsWithStats.getStats()).thenReturn(ResultSetStats.getDefaultInstance()); - when(txContext.analyzeQuery(any(Statement.class), any(QueryAnalyzeMode.class))) - .thenReturn(rsWithStats); - when(txContext.executeUpdate(any(Statement.class))).thenReturn(1L); - return new SimpleTransactionManager(txContext, commitBehavior); - } + invocation -> { + TransactionContext txContext = mock(TransactionContext.class); + when(txContext.executeQuery(any(Statement.class))).thenReturn(mock(ResultSet.class)); + ResultSet rsWithStats = mock(ResultSet.class); + when(rsWithStats.getStats()).thenReturn(ResultSetStats.getDefaultInstance()); + when(txContext.analyzeQuery(any(Statement.class), any(QueryAnalyzeMode.class))) + .thenReturn(rsWithStats); + when(txContext.executeUpdate(any(Statement.class))).thenReturn(1L); + return new SimpleTransactionManager(txContext, commitBehavior); }); return ReadWriteTransaction.newBuilder() .setDatabaseClient(client) .setRetryAbortsInternally(withRetry) - .setTransactionRetryListeners(Collections.emptyList()) + .setTransactionRetryListeners(Collections.emptyList()) .withStatementExecutor(new StatementExecutor()) .build(); } @@ -465,7 +459,7 @@ public void testRetry() { ReadWriteTransaction subject = ReadWriteTransaction.newBuilder() .setRetryAbortsInternally(true) - .setTransactionRetryListeners(Collections.emptyList()) + .setTransactionRetryListeners(Collections.emptyList()) .setDatabaseClient(client) .withStatementExecutor(new StatementExecutor()) .build(); @@ -492,7 +486,7 @@ public void testChecksumResultSet() { ReadWriteTransaction transaction = ReadWriteTransaction.newBuilder() .setRetryAbortsInternally(true) - .setTransactionRetryListeners(Collections.emptyList()) + .setTransactionRetryListeners(Collections.emptyList()) .setDatabaseClient(client) .withStatementExecutor(new StatementExecutor()) .build(); @@ -631,7 +625,7 @@ public void testChecksumResultSetWithArray() { ReadWriteTransaction transaction = ReadWriteTransaction.newBuilder() .setRetryAbortsInternally(true) - .setTransactionRetryListeners(Collections.emptyList()) + .setTransactionRetryListeners(Collections.emptyList()) .setDatabaseClient(client) .withStatementExecutor(new StatementExecutor()) .build(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReplaceableForwardingResultSetTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReplaceableForwardingResultSetTest.java index 51c8999addb..de10e1c4a52 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReplaceableForwardingResultSetTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReplaceableForwardingResultSetTest.java @@ -34,6 +34,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; @@ -46,7 +47,7 @@ private ReplaceableForwardingResultSet createSubject() { ResultSet delegate = ResultSets.forRows( Type.struct(StructField.of("test", Type.int64())), - Arrays.asList(Struct.newBuilder().set("test").to(1L).build())); + Collections.singletonList(Struct.newBuilder().set("test").to(1L).build())); return new ReplaceableForwardingResultSet(delegate); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SingleUseTransactionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SingleUseTransactionTest.java index c994d075bd3..040b01b1c8f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SingleUseTransactionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SingleUseTransactionTest.java @@ -371,12 +371,9 @@ private SingleUseTransaction createSubject( when(txContext.executeUpdate(Statement.of(VALID_UPDATE))).thenReturn(VALID_UPDATE_COUNT); when(txContext.executeUpdate(Statement.of(SLOW_UPDATE))) .thenAnswer( - new Answer() { - @Override - public Long answer(InvocationOnMock invocation) throws Throwable { - Thread.sleep(1000L); - return VALID_UPDATE_COUNT; - } + invocation -> { + Thread.sleep(1000L); + return VALID_UPDATE_COUNT; }); when(txContext.executeUpdate(Statement.of(INVALID_UPDATE))) .thenThrow( @@ -695,6 +692,7 @@ public void testMultiUse() { get(subject.executeQueryAsync(createParsedQuery(VALID_QUERY), AnalyzeMode.NONE)); fail("missing expected exception"); } catch (IllegalStateException e) { + // Expected exception } } @@ -708,6 +706,7 @@ public void testMultiUse() { get(subject.executeDdlAsync(ddl)); fail("missing expected exception"); } catch (IllegalStateException e) { + // Expected exception } ParsedStatement update = createParsedUpdate(VALID_UPDATE); @@ -719,6 +718,7 @@ public void testMultiUse() { get(subject.executeUpdateAsync(update)); fail("missing expected exception"); } catch (IllegalStateException e) { + // Expected exception } subject = createSubject(); @@ -728,6 +728,7 @@ public void testMultiUse() { get(subject.writeAsync(Collections.singleton(Mutation.newInsertBuilder("FOO").build()))); fail("missing expected exception"); } catch (IllegalStateException e) { + // Expected exception } subject = createSubject(); @@ -738,6 +739,7 @@ public void testMultiUse() { get(subject.writeAsync(Arrays.asList(mutation, mutation))); fail("missing expected exception"); } catch (IllegalStateException e) { + // Expected exception } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SpannerPoolTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SpannerPoolTest.java index 126bab1f239..ab5a345909f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SpannerPoolTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SpannerPoolTest.java @@ -360,7 +360,7 @@ public void testCloseUnusedSpanners() { private static final long MILLISECOND = TimeUnit.NANOSECONDS.convert(1L, TimeUnit.MILLISECONDS); @Test - public void testAutomaticCloser() throws InterruptedException { + public void testAutomaticCloser() { FakeTicker ticker = new FakeTicker(); SpannerPool pool = createSubjectAndMocks(TEST_AUTOMATIC_CLOSE_TIMEOUT_MILLIS, ticker); Spanner spanner1; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SqlScriptVerifier.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SqlScriptVerifier.java index 89e6a6a9009..2c3eae6623d 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SqlScriptVerifier.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SqlScriptVerifier.java @@ -124,12 +124,12 @@ private Object getArrayValue(ResultSet rs, String col, Type type) { } @Override - protected int getColumnCount() throws Exception { + protected int getColumnCount() { return resultSet.getColumnCount(); } @Override - protected Object getFirstValue() throws Exception { + protected Object getFirstValue() { return getValue(resultSet.getType().getStructFields().get(0).getName()); } } @@ -151,7 +151,7 @@ protected GenericStatementResult execute(String sql) { } @Override - public void close() throws Exception { + public void close() { if (this.connection != null) { this.connection.close(); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementTimeoutTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementTimeoutTest.java index c8e0781b4c2..87fde11f9bb 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementTimeoutTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementTimeoutTest.java @@ -30,10 +30,8 @@ import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; -import com.google.cloud.spanner.SpannerOptions.Builder; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.connection.AbstractConnectionImplTest.ConnectionConsumer; -import com.google.cloud.spanner.connection.ConnectionOptions.SpannerOptionsConfigurator; import com.google.cloud.spanner.connection.ITAbstractSpannerTest.ITConnection; import com.google.common.util.concurrent.Uninterruptibles; import com.google.longrunning.Operation; @@ -83,15 +81,12 @@ public class StatementTimeoutTest extends AbstractMockServerTest { private static final int TIMEOUT_FOR_SLOW_STATEMENTS = 50; ITConnection createConnection() { - StringBuilder url = new StringBuilder(getBaseUrl()); ConnectionOptions options = ConnectionOptions.newBuilder() - .setUri(url.toString()) + .setUri(getBaseUrl()) .setConfigurator( - new SpannerOptionsConfigurator() { - @Override - public void configure(Builder options) { - options + optionsConfigurator -> + optionsConfigurator .getDatabaseAdminStubSettingsBuilder() .updateDatabaseDdlOperationSettings() .setPollingAlgorithm( @@ -101,9 +96,7 @@ public void configure(Builder options) { .setMaxRetryDelay(Duration.ofMillis(1L)) .setRetryDelayMultiplier(1.0) .setTotalTimeout(Duration.ofMinutes(10L)) - .build())); - } - }) + .build()))) .build(); return createITConnection(options); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITAsyncTransactionRetryTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITAsyncTransactionRetryTest.java index 721dccc6512..fa44ad6f5d9 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITAsyncTransactionRetryTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITAsyncTransactionRetryTest.java @@ -29,7 +29,6 @@ import com.google.cloud.spanner.AbortedException; import com.google.cloud.spanner.AsyncResultSet; import com.google.cloud.spanner.AsyncResultSet.CallbackResponse; -import com.google.cloud.spanner.AsyncResultSet.ReadyCallback; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.KeySet; import com.google.cloud.spanner.Mutation; @@ -192,19 +191,16 @@ private ApiFuture getTestRecordCountAsync(Connection connection) { connection.executeQueryAsync(Statement.of("SELECT COUNT(*) AS C FROM TEST WHERE ID=1"))) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - count.set(resultSet.getLong("C")); - break; - } + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + count.set(resultSet.getLong("C")); + break; } } }); @@ -327,25 +323,22 @@ public void testQueryAborted() { connection.executeQueryAsync(Statement.of("SELECT COUNT(*) AS C FROM TEST WHERE ID=1"))) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - countAfterInsert.set(resultSet.getLong("C")); - break; - } + resultSet -> { + try { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + countAfterInsert.set(resultSet.getLong("C")); + break; } - } catch (Throwable t) { - countAfterInsert.setException(t); - return CallbackResponse.DONE; } + } catch (Throwable t) { + countAfterInsert.setException(t); + return CallbackResponse.DONE; } }); } @@ -447,24 +440,21 @@ public void testAbortAfterSelect() { connection.executeQueryAsync(Statement.of("SELECT * FROM TEST WHERE ID=1"))) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - initialRecord.set(resultSet.getCurrentRowAsStruct()); - } + resultSet -> { + try { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + initialRecord.set(resultSet.getCurrentRowAsStruct()); } - } catch (Throwable t) { - initialRecord.setException(t); - return CallbackResponse.DONE; } + } catch (Throwable t) { + initialRecord.setException(t); + return CallbackResponse.DONE; } }); } @@ -480,24 +470,21 @@ public CallbackResponse cursorReady(AsyncResultSet resultSet) { connection.executeQueryAsync(Statement.of("SELECT * FROM TEST WHERE ID=1"))) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - secondRecord.set(resultSet.getCurrentRowAsStruct()); - } + resultSet -> { + try { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + secondRecord.set(resultSet.getCurrentRowAsStruct()); } - } catch (Throwable t) { - secondRecord.setException(t); - return CallbackResponse.DONE; } + } catch (Throwable t) { + secondRecord.setException(t); + return CallbackResponse.DONE; } }); } @@ -565,18 +552,15 @@ public void testAbortWithResultSetFullyConsumed() { // do nothing, just consume the result set rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - break; - } + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + break; } } }); @@ -611,18 +595,15 @@ public void testAbortWithConcurrentInsert() { get( rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - break; - } + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + break; } } })); @@ -670,18 +651,15 @@ public void testAbortWithConcurrentDelete() { get( rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - break; - } + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + break; } } })); @@ -727,18 +705,15 @@ public void testAbortWithConcurrentUpdate() { get( rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - break; - } + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + break; } } })); @@ -795,34 +770,31 @@ public void testAbortWithUnseenConcurrentInsert() throws InterruptedException { ApiFuture finished = rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - count.incrementAndGet(); - lastSeenId.set(resultSet.getLong("ID")); - break; - } - if (count.get() == 1) { - // Let the other transaction proceed. - latch1.countDown(); - // Wait until the transaction has been aborted and retried. - if (!latch2.await(120L, TimeUnit.SECONDS)) { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.DEADLINE_EXCEEDED, "Timeout while waiting for latch2"); - } + resultSet -> { + try { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + count.incrementAndGet(); + lastSeenId.set(resultSet.getLong("ID")); + break; + } + if (count.get() == 1) { + // Let the other transaction proceed. + latch1.countDown(); + // Wait until the transaction has been aborted and retried. + if (!latch2.await(120L, TimeUnit.SECONDS)) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.DEADLINE_EXCEEDED, "Timeout while waiting for latch2"); } } - } catch (Throwable t) { - throw SpannerExceptionFactory.asSpannerException(t); } + } catch (Throwable t) { + throw SpannerExceptionFactory.asSpannerException(t); } }); // Open a new connection and transaction and do an additional insert. This insert will be @@ -885,19 +857,16 @@ public void testRetryLargeResultSet() { ApiFuture finished = rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - // do nothing, just consume the result set - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - break; - } + resultSet -> { + // do nothing, just consume the result set + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + break; } } }); @@ -952,19 +921,16 @@ public void testRetryHighAbortRate() { ApiFuture finished = rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - // do nothing, just consume the result set - while (true) { - switch (resultSet.tryNext()) { - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - break; - } + resultSet -> { + // do nothing, just consume the result set + while (true) { + switch (resultSet.tryNext()) { + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + break; } } }); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncAPITest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncAPITest.java index c32846725c7..ab24219d7ed 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncAPITest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncAPITest.java @@ -29,10 +29,8 @@ import com.google.cloud.spanner.AbortedException; import com.google.cloud.spanner.AsyncResultSet; import com.google.cloud.spanner.AsyncResultSet.CallbackResponse; -import com.google.cloud.spanner.AsyncResultSet.ReadyCallback; import com.google.cloud.spanner.AsyncRunner; import com.google.cloud.spanner.AsyncTransactionManager; -import com.google.cloud.spanner.AsyncTransactionManager.AsyncTransactionFunction; import com.google.cloud.spanner.AsyncTransactionManager.TransactionContextFuture; import com.google.cloud.spanner.Database; import com.google.cloud.spanner.DatabaseClient; @@ -49,13 +47,13 @@ import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.Struct; import com.google.cloud.spanner.TimestampBound; -import com.google.cloud.spanner.TransactionContext; import com.google.cloud.spanner.Type; import com.google.cloud.spanner.Type.StructField; import com.google.cloud.spanner.testing.RemoteSpannerHelper; import com.google.common.util.concurrent.SettableFuture; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -107,7 +105,7 @@ public static void cleanup() { @Before public void setupData() { - client.write(Arrays.asList(Mutation.delete(TABLE_NAME, KeySet.all()))); + client.write(Collections.singletonList(Mutation.delete(TABLE_NAME, KeySet.all()))); // Includes k0..k14. Note that strings k{10,14} sort between k1 and k2. List mutations = new ArrayList<>(); for (int i = 0; i < 15; ++i) { @@ -134,26 +132,23 @@ public void emptyReadAsync() throws Exception { ALL_COLUMNS); resultSet.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - while (true) { - switch (resultSet.tryNext()) { - case OK: - fail("received unexpected data"); - case NOT_READY: - return CallbackResponse.CONTINUE; - case DONE: - assertThat(resultSet.getType()).isEqualTo(TABLE_TYPE); - result.set(true); - return CallbackResponse.DONE; - } + rs -> { + try { + while (true) { + switch (rs.tryNext()) { + case OK: + fail("received unexpected data"); + case NOT_READY: + return CallbackResponse.CONTINUE; + case DONE: + assertThat(rs.getType()).isEqualTo(TABLE_TYPE); + result.set(true); + return CallbackResponse.DONE; } - } catch (Throwable t) { - result.setException(t); - return CallbackResponse.DONE; } + } catch (Throwable t) { + result.setException(t); + return CallbackResponse.DONE; } }); assertThat(result.get()).isTrue(); @@ -172,26 +167,23 @@ public void indexEmptyReadAsync() throws Exception { ALL_COLUMNS); resultSet.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - while (true) { - switch (resultSet.tryNext()) { - case OK: - fail("received unexpected data"); - case NOT_READY: - return CallbackResponse.CONTINUE; - case DONE: - assertThat(resultSet.getType()).isEqualTo(TABLE_TYPE); - result.set(true); - return CallbackResponse.DONE; - } + rs -> { + try { + while (true) { + switch (rs.tryNext()) { + case OK: + fail("received unexpected data"); + case NOT_READY: + return CallbackResponse.CONTINUE; + case DONE: + assertThat(rs.getType()).isEqualTo(TABLE_TYPE); + result.set(true); + return CallbackResponse.DONE; } - } catch (Throwable t) { - result.setException(t); - return CallbackResponse.DONE; } + } catch (Throwable t) { + result.setException(t); + return CallbackResponse.DONE; } }); assertThat(result.get()).isTrue(); @@ -310,7 +302,8 @@ public void asyncRunnerFireAndForgetInvalidUpdate() throws Exception { assertThat(res.get()).isEqualTo(1L); assertThat(client.singleUse().readRow("TestTable", Key.of("k999"), ALL_COLUMNS)).isNotNull(); } finally { - client.writeAtLeastOnce(Arrays.asList(Mutation.delete("TestTable", Key.of("k999")))); + client.writeAtLeastOnce( + Collections.singletonList(Mutation.delete("TestTable", Key.of("k999")))); assertThat(client.singleUse().readRow("TestTable", Key.of("k999"), ALL_COLUMNS)).isNull(); } } @@ -346,19 +339,15 @@ public void testAsyncTransactionManagerReturnsCommitStats() throws InterruptedEx get( context .then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext transaction, Void input) - throws Exception { - transaction.buffer( - Mutation.newInsertOrUpdateBuilder(TABLE_NAME) - .set("Key") - .to("k_commit_stats") - .set("StringValue") - .to("Should return commit stats") - .build()); - return ApiFutures.immediateFuture(null); - } + (transaction, ignored) -> { + transaction.buffer( + Mutation.newInsertOrUpdateBuilder(TABLE_NAME) + .set("Key") + .to("k_commit_stats") + .set("StringValue") + .to("Should return commit stats") + .build()); + return ApiFutures.immediateFuture(null); }, executor) .commitAsync()); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncExamplesTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncExamplesTest.java index ba6f55497a3..c340ebd21ed 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncExamplesTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITAsyncExamplesTest.java @@ -19,7 +19,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; -import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.core.SettableApiFuture; @@ -39,8 +38,6 @@ import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.Struct; -import com.google.cloud.spanner.StructReader; -import com.google.common.base.Function; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import java.util.ArrayList; @@ -336,15 +333,7 @@ public void readOnlyTransaction() throws Exception { .bind("keys") .toStringArray(keys1) .build())) { - values1 = - rs.toListAsync( - new Function() { - @Override - public String apply(StructReader input) { - return input.getString("StringValue"); - } - }, - executor); + values1 = rs.toListAsync(input -> input.getString("StringValue"), executor); } try (AsyncResultSet rs = tx.executeQueryAsync( @@ -352,35 +341,15 @@ public String apply(StructReader input) { .bind("keys") .toStringArray(keys2) .build())) { - values2 = - rs.toListAsync( - new Function() { - @Override - public String apply(StructReader input) { - return input.getString("StringValue"); - } - }, - executor); + values2 = rs.toListAsync(input -> input.getString("StringValue"), executor); } } ApiFuture> allValues = ApiFutures.transform( ApiFutures.allAsList(Arrays.asList(values1, values2)), - new ApiFunction>, Iterable>() { - @Override - public Iterable apply(List> input) { - return Iterables.mergeSorted( - input, - new Comparator() { - @Override - public int compare(String o1, String o2) { - // Compare based on numerical order (i.e. without the preceding 'v'). - return Integer.valueOf(o1.substring(1)) - .compareTo(Integer.valueOf(o2.substring(1))); - } - }); - } - }, + input -> + Iterables.mergeSorted( + input, Comparator.comparing(o -> Integer.valueOf(o.substring(1)))), executor); assertThat(allValues.get()).containsExactly("v1", "v2", "v3", "v10", "v11", "v12"); } @@ -404,59 +373,53 @@ public void pauseResume() throws Exception { AsyncResultSet unevenRs = tx.executeQueryAsync(unevenStatement)) { evenRs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - evenFinished.set(true); - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - synchronized (lock) { - allValues.add(resultSet.getString("StringValue")); - } - evenReturnedFirstRow.countDown(); - return CallbackResponse.PAUSE; - } + resultSet -> { + try { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + evenFinished.set(true); + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + synchronized (lock) { + allValues.add(resultSet.getString("StringValue")); + } + evenReturnedFirstRow.countDown(); + return CallbackResponse.PAUSE; } - } catch (Throwable t) { - evenFinished.setException(t); - return CallbackResponse.DONE; } + } catch (Throwable t) { + evenFinished.setException(t); + return CallbackResponse.DONE; } }); unevenRs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - // Make sure the even result set has returned the first before we start the uneven - // results. - evenReturnedFirstRow.await(); - while (true) { - switch (resultSet.tryNext()) { - case DONE: - unevenFinished.set(true); - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - synchronized (lock) { - allValues.add(resultSet.getString("StringValue")); - } - return CallbackResponse.PAUSE; - } + resultSet -> { + try { + // Make sure the even result set has returned the first before we start the uneven + // results. + evenReturnedFirstRow.await(); + while (true) { + switch (resultSet.tryNext()) { + case DONE: + unevenFinished.set(true); + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + synchronized (lock) { + allValues.add(resultSet.getString("StringValue")); + } + return CallbackResponse.PAUSE; } - } catch (Throwable t) { - unevenFinished.setException(t); - return CallbackResponse.DONE; } + } catch (Throwable t) { + unevenFinished.setException(t); + return CallbackResponse.DONE; } }); while (!(evenFinished.isDone() && unevenFinished.isDone())) { @@ -493,28 +456,25 @@ public void cancel() throws Exception { try (AsyncResultSet rs = client.singleUse().readAsync(TABLE_NAME, KeySet.all(), ALL_COLUMNS)) { rs.setCallback( executor, - new ReadyCallback() { - @Override - public CallbackResponse cursorReady(AsyncResultSet resultSet) { - try { - while (true) { - switch (resultSet.tryNext()) { - case DONE: - finished.set(true); - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - case OK: - values.add(resultSet.getString("StringValue")); - receivedFirstRow.countDown(); - cancelled.await(); - break; - } + resultSet -> { + try { + while (true) { + switch (resultSet.tryNext()) { + case DONE: + finished.set(true); + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + case OK: + values.add(resultSet.getString("StringValue")); + receivedFirstRow.countDown(); + cancelled.await(); + break; } - } catch (Throwable t) { - finished.setException(t); - return CallbackResponse.DONE; } + } catch (Throwable t) { + finished.setException(t); + return CallbackResponse.DONE; } }); receivedFirstRow.await(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBackupTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBackupTest.java index 9c360851431..6ccce161f08 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBackupTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBackupTest.java @@ -51,7 +51,6 @@ import com.google.cloud.spanner.encryption.EncryptionConfigs; import com.google.cloud.spanner.testing.RemoteSpannerHelper; import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; import com.google.common.base.Stopwatch; import com.google.common.collect.Iterables; import com.google.longrunning.Operation; @@ -62,7 +61,6 @@ import com.google.spanner.admin.database.v1.RestoreSourceType; import io.grpc.Status; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -228,7 +226,8 @@ public void testBackups() throws InterruptedException, ExecutionException { dbAdminClient.createDatabase( testHelper.getInstanceId().getInstance(), testHelper.getUniqueDatabaseId() + "_db2", - Arrays.asList("CREATE TABLE BAR (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")); + Collections.singletonList( + "CREATE TABLE BAR (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")); // Make sure all databases are created before we try to create any backups. Database db1 = dbOp1.get(); Database db2 = dbOp2.get(); @@ -237,7 +236,7 @@ public void testBackups() throws InterruptedException, ExecutionException { // Insert some data into db2 to make sure the backup will have a size>0. DatabaseClient client = testHelper.getDatabaseClient(db2); client.writeAtLeastOnce( - Arrays.asList( + Collections.singletonList( Mutation.newInsertOrUpdateBuilder("BAR") .set("ID") .to(1L) @@ -281,8 +280,8 @@ public void testBackups() throws InterruptedException, ExecutionException { // Ensure both backups have been created before we proceed. logger.info("Waiting for backup operations to finish"); - Backup backup1 = null; - Backup backup2 = null; + Backup backup1; + Backup backup2; Stopwatch watch = Stopwatch.createStarted(); try { backup1 = op1.get(6L, TimeUnit.MINUTES); @@ -320,7 +319,7 @@ public void testBackups() throws InterruptedException, ExecutionException { // Insert some more data into db2 to get a timestamp from the server. Timestamp commitTs = client.writeAtLeastOnce( - Arrays.asList( + Collections.singletonList( Mutation.newInsertOrUpdateBuilder("BAR") .set("ID") .to(2L) @@ -732,42 +731,22 @@ private void verifyRestoreOperations( assertThat( Iterables.any( instance.listBackupOperations().iterateAll(), - new Predicate() { - @Override - public boolean apply(Operation input) { - return input.getName().equals(backupOperationName); - } - })) + input -> input.getName().equals(backupOperationName))) .isTrue(); assertThat( Iterables.any( instance.listBackupOperations().iterateAll(), - new Predicate() { - @Override - public boolean apply(Operation input) { - return input.getName().equals(restoreOperationName); - } - })) + input -> input.getName().equals(restoreOperationName))) .isFalse(); assertThat( Iterables.any( instance.listDatabaseOperations().iterateAll(), - new Predicate() { - @Override - public boolean apply(Operation input) { - return input.getName().equals(backupOperationName); - } - })) + input -> input.getName().equals(backupOperationName))) .isFalse(); assertThat( Iterables.any( instance.listDatabaseOperations().iterateAll(), - new Predicate() { - @Override - public boolean apply(Operation input) { - return input.getName().equals(restoreOperationName); - } - })) + input -> input.getName().equals(restoreOperationName))) .isTrue(); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBatchDmlTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBatchDmlTest.java index dada7a0aff4..3cd9917e1a8 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBatchDmlTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBatchDmlTest.java @@ -31,7 +31,7 @@ import com.google.cloud.spanner.TransactionRunner.TransactionCallable; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.junit.After; import org.junit.Assert; @@ -67,14 +67,16 @@ public static void createDatabase() { public void createTable() throws Exception { String ddl = "CREATE TABLE T (" + " K STRING(MAX) NOT NULL," + " V INT64," + ") PRIMARY KEY (K)"; - OperationFuture op = db.updateDdl(Arrays.asList(ddl), null); + OperationFuture op = + db.updateDdl(Collections.singletonList(ddl), null); op.get(); } @After public void dropTable() throws Exception { String ddl = "DROP TABLE T"; - OperationFuture op = db.updateDdl(Arrays.asList(ddl), null); + OperationFuture op = + db.updateDdl(Collections.singletonList(ddl), null); op.get(); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBatchReadTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBatchReadTest.java index f12e2733842..94c3723439a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBatchReadTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBatchReadTest.java @@ -158,7 +158,11 @@ public void readUsingIndex() { batchTxn = client.batchReadOnlyTransaction(bound); List partitions = batchTxn.partitionReadUsingIndex( - partitionParams, TABLE_NAME, INDEX_NAME, KeySet.all(), Arrays.asList("Fingerprint")); + partitionParams, + TABLE_NAME, + INDEX_NAME, + KeySet.all(), + Collections.singletonList("Fingerprint")); BatchTransactionId txnID = batchTxn.getBatchTransactionId(); int numRowsRead = 0; for (Partition p : partitions) { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITCommitTimestampTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITCommitTimestampTest.java index 4db58268ad5..5a3b5c14707 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITCommitTimestampTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITCommitTimestampTest.java @@ -37,6 +37,7 @@ import com.google.cloud.spanner.testing.RemoteSpannerHelper; import com.google.common.collect.ImmutableList; import java.util.Arrays; +import java.util.Collections; import java.util.concurrent.ExecutionException; import org.junit.After; import org.junit.AfterClass; @@ -89,7 +90,7 @@ public void deleteAllTestRecords() { } private Timestamp write(Mutation m) { - return client.write(Arrays.asList(m)); + return client.write(Collections.singletonList(m)); } private Struct readRow(DatabaseClient client, String table, Key key, String... columns) { @@ -316,7 +317,7 @@ public void interleavedTableHierarchy1() { // error_catalog error CommitTimestampOptionNotEnabled try { client.write( - Arrays.asList( + Collections.singletonList( Mutation.newInsertOrUpdateBuilder("T3") .set("ts") .to(Value.COMMIT_TIMESTAMP) @@ -343,7 +344,7 @@ public void interleavedTableHierarchy2() { // error_catalog error CommitTimestampOptionNotEnabled try { client.write( - Arrays.asList( + Collections.singletonList( Mutation.newInsertOrUpdateBuilder("T1") .set("ts") .to(Value.COMMIT_TIMESTAMP) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDMLTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDMLTest.java index 81452e07d07..2a94ed82abb 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDMLTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDMLTest.java @@ -36,7 +36,7 @@ import com.google.cloud.spanner.TimestampBound; import com.google.cloud.spanner.TransactionRunner; import com.google.cloud.spanner.TransactionRunner.TransactionCallable; -import java.util.Arrays; +import java.util.Collections; import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; @@ -80,7 +80,7 @@ public static void setUpDatabase() { @Before public void increaseTestIdAndDeleteTestData() { - client.writeAtLeastOnce(Arrays.asList(Mutation.delete("T", KeySet.all()))); + client.writeAtLeastOnce(Collections.singletonList(Mutation.delete("T", KeySet.all()))); id++; } @@ -136,7 +136,7 @@ public void partitionedDML() { assertThat( client .singleUse(TimestampBound.strong()) - .readRow("T", Key.of(String.format("%d-boo1", id)), Arrays.asList("V")) + .readRow("T", Key.of(String.format("%d-boo1", id)), Collections.singletonList("V")) .getLong(0)) .isEqualTo(1); @@ -147,7 +147,7 @@ public void partitionedDML() { assertThat( client .singleUse(TimestampBound.strong()) - .readRow("T", Key.of(String.format("%d-boo1", id)), Arrays.asList("V")) + .readRow("T", Key.of(String.format("%d-boo1", id)), Collections.singletonList("V")) .getLong(0)) .isEqualTo(100); @@ -156,7 +156,7 @@ public void partitionedDML() { assertThat( client .singleUse(TimestampBound.strong()) - .readRow("T", Key.of(String.format("%d-boo1", id)), Arrays.asList("V"))) + .readRow("T", Key.of(String.format("%d-boo1", id)), Collections.singletonList("V"))) .isNull(); } @@ -166,21 +166,21 @@ public void standardDML() { assertThat( client .singleUse(TimestampBound.strong()) - .readRow("T", Key.of(String.format("%d-boo1", id)), Arrays.asList("V")) + .readRow("T", Key.of(String.format("%d-boo1", id)), Collections.singletonList("V")) .getLong(0)) .isEqualTo(1); executeUpdate(DML_COUNT, updateDml()); assertThat( client .singleUse(TimestampBound.strong()) - .readRow("T", Key.of(String.format("%d-boo1", id)), Arrays.asList("V")) + .readRow("T", Key.of(String.format("%d-boo1", id)), Collections.singletonList("V")) .getLong(0)) .isEqualTo(100); executeUpdate(DML_COUNT, deleteDml()); assertThat( client .singleUse(TimestampBound.strong()) - .readRow("T", Key.of(String.format("%d-boo1", id)), Arrays.asList("V"))) + .readRow("T", Key.of(String.format("%d-boo1", id)), Collections.singletonList("V"))) .isNull(); } @@ -210,7 +210,7 @@ public void standardDMLWithDuplicates() { assertThat( client .singleUse(TimestampBound.strong()) - .readRow("T", Key.of(String.format("%d-boo1", id)), Arrays.asList("V")) + .readRow("T", Key.of(String.format("%d-boo1", id)), Collections.singletonList("V")) .getLong(0)) .isEqualTo(500); @@ -229,7 +229,8 @@ public void standardDMLReadYourWrites() { assertThat(rowCount).isEqualTo(1); assertThat( transaction - .readRow("T", Key.of(String.format("%d-boo2", id)), Arrays.asList("v")) + .readRow( + "T", Key.of(String.format("%d-boo2", id)), Collections.singletonList("v")) .getLong(0)) .isEqualTo(2 * 2); return null; @@ -270,7 +271,7 @@ class UserException extends Exception { .read( "T", KeySet.range(KeyRange.prefix(Key.of(String.format("%d-boo", id)))), - Arrays.asList("K")); + Collections.singletonList("K")); assertThat(resultSet.next()).isFalse(); } @@ -297,7 +298,9 @@ public void standardDMLAndMutations() { KeySet.Builder keys = KeySet.newBuilder(); keys.addKey(Key.of(key1)).addKey(Key.of(key2)); ResultSet resultSet = - client.singleUse(TimestampBound.strong()).read("T", keys.build(), Arrays.asList("K")); + client + .singleUse(TimestampBound.strong()) + .read("T", keys.build(), Collections.singletonList("K")); int rowCount = 0; while (resultSet.next()) { rowCount++; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseAdminTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseAdminTest.java index 0d8809116b8..48837d21cec 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseAdminTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseAdminTest.java @@ -126,7 +126,7 @@ public void databaseOperations() throws Exception { dbAdminClient.dropDatabase(instanceId, dbId); dbs.clear(); try { - db = dbAdminClient.getDatabase(testHelper.getInstanceId().getInstance(), dbId); + dbAdminClient.getDatabase(testHelper.getInstanceId().getInstance(), dbId); fail("Expected exception"); } catch (SpannerException ex) { assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); @@ -199,7 +199,7 @@ public void listPagination() throws Exception { String instanceId = testHelper.getInstanceId().getInstance(); for (String dbId : dbIds) { - dbs.add(dbAdminClient.createDatabase(instanceId, dbId, ImmutableList.of()).get()); + dbs.add(dbAdminClient.createDatabase(instanceId, dbId, ImmutableList.of()).get()); } Page page = dbAdminClient.listDatabases(instanceId, Options.pageSize(1)); List dbIdsGot = new ArrayList<>(); @@ -307,7 +307,7 @@ public void testRetryNonIdempotentRpcsReturningLongRunningOperations() throws Ex client.createDatabase( testHelper.getInstanceId().getInstance(), initialDatabaseId, - Collections.emptyList()); + Collections.emptyList()); databases.add(op.get()); // Keep track of the original create time of this database, as we will drop this database // later and create another one with the exact same name. That means that the ListOperations @@ -406,7 +406,7 @@ public void testRetryNonIdempotentRpcsReturningLongRunningOperations() throws Ex client.createDatabase( testHelper.getInstanceId().getInstance(), initialDatabaseId, - Collections.emptyList()); + Collections.emptyList()); // Check that the second database was created and has a greater creation time than the // first. Timestamp secondCreationTime = op.get().getCreateTime(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseTest.java index 49ce8f18f07..48e1d77fc2f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseTest.java @@ -109,7 +109,7 @@ public void databaseDeletedTest() throws Exception { .createDatabase( db.getId().getInstanceId().getInstance(), db.getId().getDatabase(), - Collections.emptyList()); + Collections.emptyList()); Database newDb = op.get(); // Queries using the same DatabaseClient should still return DatabaseNotFoundExceptions. diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDirectPathFallback.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDirectPathFallback.java index 80234cbc1a0..ae2c99b3e1a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDirectPathFallback.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDirectPathFallback.java @@ -19,7 +19,6 @@ import static com.google.common.truth.Truth.assertWithMessage; import static com.google.common.truth.TruthJUnit.assume; -import com.google.api.core.ApiFunction; import com.google.api.gax.core.FixedCredentialsProvider; import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; import com.google.auth.oauth2.ComputeEngineCredentials; @@ -124,15 +123,12 @@ public void setup() { .setEndpoint(DIRECT_PATH_ENDPOINT) .setPoolSize(1) .setChannelConfigurator( - new ApiFunction() { - @Override - public ManagedChannelBuilder apply(ManagedChannelBuilder builder) { - injectNettyChannelHandler(builder); - // Fail fast when blackhole is active - builder.keepAliveTime(1, TimeUnit.SECONDS); - builder.keepAliveTimeout(1, TimeUnit.SECONDS); - return builder; - } + managedChannelBuilder -> { + injectNettyChannelHandler(managedChannelBuilder); + // Fail fast when blackhole is active + managedChannelBuilder.keepAliveTime(1, TimeUnit.SECONDS); + managedChannelBuilder.keepAliveTimeout(1, TimeUnit.SECONDS); + return managedChannelBuilder; }) .build()); // Forcefully ignore GOOGLE_APPLICATION_CREDENTIALS @@ -197,7 +193,7 @@ public void testFallback() throws InterruptedException, TimeoutException { assertWithMessage("Failed to upgrade back to DirectPath").that(exerciseDirectPath()).isTrue(); } - private boolean exerciseDirectPath() throws InterruptedException, TimeoutException { + private boolean exerciseDirectPath() throws InterruptedException { Stopwatch stopwatch = Stopwatch.createStarted(); numDpAddrRead.set(0); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITPitrUpdateDatabaseTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITPitrUpdateDatabaseTest.java index 72a52b39078..333dead4c22 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITPitrUpdateDatabaseTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITPitrUpdateDatabaseTest.java @@ -71,7 +71,7 @@ public static void setUp() throws Exception { databaseId = testHelper.getUniqueDatabaseId(); dbAdminClient = testHelper.getClient().getDatabaseAdminClient(); - createDatabase(dbAdminClient, instanceId, databaseId, Collections.emptyList()); + createDatabase(dbAdminClient, instanceId, databaseId, Collections.emptyList()); metadata = updateVersionRetentionPeriod( dbAdminClient, instanceId, databaseId, VERSION_RETENTION_PERIOD); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITQueryTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITQueryTest.java index 6ef53ea7cd9..1900f042138 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITQueryTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITQueryTest.java @@ -50,6 +50,7 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.junit.BeforeClass; import org.junit.ClassRule; @@ -316,7 +317,7 @@ public void bindBoolArray() { public void bindBoolArrayEmpty() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toBoolArray(Arrays.asList()), + Statement.newBuilder("SELECT @v").bind("v").toBoolArray(Collections.emptyList()), Type.array(Type.bool())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getBooleanList(0)).containsExactly(); @@ -345,7 +346,7 @@ public void bindInt64Array() { public void bindInt64ArrayEmpty() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toInt64Array(Arrays.asList()), + Statement.newBuilder("SELECT @v").bind("v").toInt64Array(Collections.emptyList()), Type.array(Type.int64())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getLongList(0)).containsExactly(); @@ -386,7 +387,7 @@ public void bindFloat64Array() { public void bindFloat64ArrayEmpty() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toFloat64Array(Arrays.asList()), + Statement.newBuilder("SELECT @v").bind("v").toFloat64Array(Collections.emptyList()), Type.array(Type.float64())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getDoubleList(0)).containsExactly(); @@ -415,7 +416,7 @@ public void bindStringArray() { public void bindStringArrayEmpty() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toStringArray(Arrays.asList()), + Statement.newBuilder("SELECT @v").bind("v").toStringArray(Collections.emptyList()), Type.array(Type.string())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getStringList(0)).containsExactly(); @@ -447,7 +448,7 @@ public void bindBytesArray() { public void bindBytesArrayEmpty() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toBytesArray(Arrays.asList()), + Statement.newBuilder("SELECT @v").bind("v").toBytesArray(Collections.emptyList()), Type.array(Type.bytes())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getBytesList(0)).isEmpty(); @@ -479,9 +480,7 @@ public void bindTimestampArray() { public void bindTimestampArrayEmpty() { Struct row = execute( - Statement.newBuilder("SELECT @v") - .bind("v") - .toTimestampArray(Arrays.asList()), + Statement.newBuilder("SELECT @v").bind("v").toTimestampArray(Collections.emptyList()), Type.array(Type.timestamp())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getTimestampList(0)).containsExactly(); @@ -513,7 +512,7 @@ public void bindDateArray() { public void bindDateArrayEmpty() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toDateArray(Arrays.asList()), + Statement.newBuilder("SELECT @v").bind("v").toDateArray(Collections.emptyList()), Type.array(Type.date())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getDateList(0)).containsExactly(); @@ -546,7 +545,7 @@ public void bindNumericArrayEmpty() { assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator()); Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toNumericArray(Arrays.asList()), + Statement.newBuilder("SELECT @v").bind("v").toNumericArray(Collections.emptyList()), Type.array(Type.numeric())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getBigDecimalList(0)).containsExactly(); @@ -601,7 +600,10 @@ public void unsupportedSelectArrayStructValue() { Struct p = structValue(); try { execute( - Statement.newBuilder("SELECT @p").bind("p").toStructArray(p.getType(), asList(p)).build(), + Statement.newBuilder("SELECT @p") + .bind("p") + .toStructArray(p.getType(), Collections.singletonList(p)) + .build(), p.getType()); fail("Expected exception"); } catch (SpannerException ex) { @@ -760,8 +762,8 @@ public void bindStructWithDuplicateFieldNames() { @Test public void bindEmptyArrayOfStruct() { - Type elementType = Type.struct(asList(Type.StructField.of("f1", Type.date()))); - List p = asList(); + Type elementType = Type.struct(Collections.singletonList(StructField.of("f1", Type.date()))); + List p = Collections.emptyList(); assertThat(p).isEmpty(); List rows = diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITReadOnlyTxnTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITReadOnlyTxnTest.java index db68b5ec88c..c93e53f212b 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITReadOnlyTxnTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITReadOnlyTxnTest.java @@ -34,7 +34,7 @@ import com.google.cloud.spanner.Struct; import com.google.cloud.spanner.TimestampBound; import com.google.common.collect.ImmutableList; -import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.NavigableMap; import java.util.TreeMap; @@ -101,7 +101,7 @@ private static void writeNewValue( String value = "v" + i; Mutation m = Mutation.newInsertOrUpdateBuilder(TABLE_NAME).set("StringValue").to(value).build(); long minCommitNanoTime = System.nanoTime(); - Timestamp timestamp = client.writeAtLeastOnce(Arrays.asList(m)); + Timestamp timestamp = client.writeAtLeastOnce(Collections.singletonList(m)); if (historyBuilder != null) { historyBuilder.add(new History(timestamp, value, minCommitNanoTime)); } @@ -114,7 +114,7 @@ public void setUp() { } private static Struct readRow(ReadContext ctx) { - return ctx.readRow(TABLE_NAME, Key.of(), Arrays.asList("StringValue")); + return ctx.readRow(TABLE_NAME, Key.of(), Collections.singletonList("StringValue")); } private static Struct queryRow(ReadContext ctx) { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITSpannerOptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITSpannerOptionsTest.java index db8c725fc51..399fd62a6d8 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITSpannerOptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITSpannerOptionsTest.java @@ -41,12 +41,12 @@ public class ITSpannerOptionsTest { private static Database db; @BeforeClass - public static void setUp() throws Exception { + public static void setUp() { db = env.getTestHelper().createTestDatabase(); } @AfterClass - public static void tearDown() throws Exception { + public static void tearDown() { db.drop(); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionManagerAsyncTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionManagerAsyncTest.java index caa3e51e2ce..c1e8a903ea5 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionManagerAsyncTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionManagerAsyncTest.java @@ -22,11 +22,9 @@ import static org.junit.Assert.fail; import static org.junit.Assume.assumeFalse; -import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.cloud.spanner.AbortedException; import com.google.cloud.spanner.AsyncTransactionManager; -import com.google.cloud.spanner.AsyncTransactionManager.AsyncTransactionFunction; import com.google.cloud.spanner.AsyncTransactionManager.AsyncTransactionStep; import com.google.cloud.spanner.AsyncTransactionManager.TransactionContextFuture; import com.google.cloud.spanner.Database; @@ -40,12 +38,12 @@ import com.google.cloud.spanner.Spanner; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.Struct; -import com.google.cloud.spanner.TransactionContext; import com.google.cloud.spanner.TransactionManager.TransactionState; import com.google.common.collect.ImmutableList; import com.google.common.util.concurrent.MoreExecutors; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -109,19 +107,15 @@ public void testSimpleInsert() throws ExecutionException, InterruptedException { assertThat(manager.getState()).isEqualTo(TransactionState.STARTED); try { txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - txn.buffer( - Mutation.newInsertBuilder("T") - .set("K") - .to("Key1") - .set("BoolValue") - .to(true) - .build()); - return ApiFutures.immediateFuture(null); - } + (transaction, ignored) -> { + transaction.buffer( + Mutation.newInsertBuilder("T") + .set("K") + .to("Key1") + .set("BoolValue") + .to(true) + .build()); + return ApiFutures.immediateFuture(null); }, executor) .commitAsync() @@ -147,19 +141,15 @@ public void testInvalidInsert() throws InterruptedException { while (true) { try { txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - txn.buffer( - Mutation.newInsertBuilder("InvalidTable") - .set("K") - .to("Key1") - .set("BoolValue") - .to(true) - .build()); - return ApiFutures.immediateFuture(null); - } + (transaction, ignored) -> { + transaction.buffer( + Mutation.newInsertBuilder("InvalidTable") + .set("K") + .to("Key1") + .set("BoolValue") + .to(true) + .build()); + return ApiFutures.immediateFuture(null); }, executor) .commitAsync() @@ -193,18 +183,15 @@ public void testRollback() throws InterruptedException { TransactionContextFuture txn = manager.beginAsync(); while (true) { txn.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) throws Exception { - txn.buffer( - Mutation.newInsertBuilder("T") - .set("K") - .to("Key2") - .set("BoolValue") - .to(true) - .build()); - return ApiFutures.immediateFuture(null); - } + (transaction, ignored) -> { + transaction.buffer( + Mutation.newInsertBuilder("T") + .set("K") + .to("Key2") + .set("BoolValue") + .to(true) + .build()); + return ApiFutures.immediateFuture(null); }, executor); try { @@ -232,7 +219,7 @@ public void testAbortAndRetry() throws InterruptedException, ExecutionException isUsingEmulator()); client.write( - Arrays.asList( + Collections.singletonList( Mutation.newInsertBuilder("T").set("K").to("Key3").set("BoolValue").to(true).build())); try (AsyncTransactionManager manager1 = client.transactionManagerAsync()) { TransactionContextFuture txn1 = manager1.beginAsync(); @@ -243,42 +230,30 @@ public void testAbortAndRetry() throws InterruptedException, ExecutionException try { AsyncTransactionStep txn1Step1 = txn1.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - return txn.readRowAsync("T", Key.of("Key3"), Arrays.asList("K", "BoolValue")); - } - }, + (transaction, ignored) -> + transaction.readRowAsync( + "T", Key.of("Key3"), Arrays.asList("K", "BoolValue")), executor); manager2 = client.transactionManagerAsync(); txn2 = manager2.beginAsync(); txn2Step1 = txn2.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) - throws Exception { - return txn.readRowAsync("T", Key.of("Key3"), Arrays.asList("K", "BoolValue")); - } - }, + (transaction, ignored) -> + transaction.readRowAsync( + "T", Key.of("Key3"), Arrays.asList("K", "BoolValue")), executor); AsyncTransactionStep txn1Step2 = txn1Step1.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Struct input) - throws Exception { - txn.buffer( - Mutation.newUpdateBuilder("T") - .set("K") - .to("Key3") - .set("BoolValue") - .to(false) - .build()); - return ApiFutures.immediateFuture(null); - } + (transaction, ignored) -> { + transaction.buffer( + Mutation.newUpdateBuilder("T") + .set("K") + .to("Key3") + .set("BoolValue") + .to(false) + .build()); + return ApiFutures.immediateFuture(null); }, executor); @@ -305,18 +280,15 @@ public ApiFuture apply(TransactionContext txn, Struct input) } AsyncTransactionStep txn2Step2 = txn2.then( - new AsyncTransactionFunction() { - @Override - public ApiFuture apply(TransactionContext txn, Void input) throws Exception { - txn.buffer( - Mutation.newUpdateBuilder("T") - .set("K") - .to("Key3") - .set("BoolValue") - .to(true) - .build()); - return ApiFutures.immediateFuture(null); - } + (transaction, ignored) -> { + transaction.buffer( + Mutation.newUpdateBuilder("T") + .set("K") + .to("Key3") + .set("BoolValue") + .to(true) + .build()); + return ApiFutures.immediateFuture(null); }, executor); txn2Step2.commitAsync().get(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionManagerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionManagerTest.java index 7f2c8350608..bb70864d3c3 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionManagerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionManagerTest.java @@ -39,6 +39,7 @@ import com.google.cloud.spanner.TransactionManager.TransactionState; import com.google.common.collect.ImmutableList; import java.util.Arrays; +import java.util.Collections; import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; @@ -165,7 +166,7 @@ public void abortAndRetry() throws InterruptedException { isUsingEmulator()); client.write( - Arrays.asList( + Collections.singletonList( Mutation.newInsertBuilder("T").set("K").to("Key3").set("BoolValue").to(true).build())); try (TransactionManager manager1 = client.transactionManager()) { TransactionContext txn1 = manager1.begin(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionTest.java index 1b401dcedff..2cfb9cbbc5b 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionTest.java @@ -54,6 +54,7 @@ import com.google.common.util.concurrent.Uninterruptibles; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Vector; import java.util.concurrent.CountDownLatch; @@ -90,7 +91,7 @@ public static void setUpDatabase() { @Before public void removeTestData() { - client.writeAtLeastOnce(Arrays.asList(Mutation.delete("T", KeySet.all()))); + client.writeAtLeastOnce(Collections.singletonList(Mutation.delete("T", KeySet.all()))); } private static String uniqueKey() { @@ -106,7 +107,8 @@ private void doBasicsTest(final ReadStrategy strategy) throws InterruptedExcepti // Initial value. client.write( - Arrays.asList(Mutation.newInsertBuilder("T").set("K").to(key).set("V").to(0).build())); + Collections.singletonList( + Mutation.newInsertBuilder("T").set("K").to(key).set("V").to(0).build())); final int numThreads = 3; @@ -155,7 +157,7 @@ public void run() { assertThat( client .singleUse(TimestampBound.strong()) - .readRow("T", Key.of(key), Arrays.asList("V")) + .readRow("T", Key.of(key), Collections.singletonList("V")) .getLong(0)) .isEqualTo((long) numThreads); } @@ -165,12 +167,7 @@ public void basicsUsingRead() throws InterruptedException { assumeFalse("Emulator does not support multiple parallel transactions", isUsingEmulator()); doBasicsTest( - new ReadStrategy() { - @Override - public Struct read(ReadContext ctx, String key) { - return ctx.readRow("T", Key.of(key), Arrays.asList("V")); - } - }); + (context, key) -> context.readRow("T", Key.of(key), Collections.singletonList("V"))); } @Test @@ -178,20 +175,17 @@ public void basicsUsingQuery() throws InterruptedException { assumeFalse("Emulator does not support multiple parallel transactions", isUsingEmulator()); doBasicsTest( - new ReadStrategy() { - @Override - public Struct read(ReadContext ctx, String key) { - ResultSet resultSet = - ctx.executeQuery( - Statement.newBuilder("SELECT V FROM T WHERE K = @key") - .bind("key") - .to(key) - .build()); - assertThat(resultSet.next()).isTrue(); - Struct row = resultSet.getCurrentRowAsStruct(); - assertThat(resultSet.next()).isFalse(); - return row; - } + (context, key) -> { + ResultSet resultSet = + context.executeQuery( + Statement.newBuilder("SELECT V FROM T WHERE K = @key") + .bind("key") + .to(key) + .build()); + assertThat(resultSet.next()).isTrue(); + Struct row = resultSet.getCurrentRowAsStruct(); + assertThat(resultSet.next()).isFalse(); + return row; }); } @@ -221,7 +215,9 @@ class UserException extends Exception { } Struct row = - client.singleUse(TimestampBound.strong()).readRow("T", Key.of(key), Arrays.asList("K")); + client + .singleUse(TimestampBound.strong()) + .readRow("T", Key.of(key), Collections.singletonList("K")); assertThat(row).isNull(); } @@ -244,7 +240,9 @@ public void userExceptionIsSpannerException() { } Struct row = - client.singleUse(TimestampBound.strong()).readRow("T", Key.of(key), Arrays.asList("K")); + client + .singleUse(TimestampBound.strong()) + .readRow("T", Key.of(key), Collections.singletonList("K")); assertThat(row).isNull(); } @@ -276,82 +274,82 @@ public void readAbort() throws Exception { // second read, which will abort. Both threads will mask SpannerExceptions to ensure that // the implementation does not require TransactionCallable to propagate them. Thread t1 = - new Thread() { - @Override - public void run() { - try { - client - .readWriteTransaction() - .run( - transaction -> { - try { - Struct row = transaction.readRow("T", Key.of(key1), Arrays.asList("V")); - t1Started.countDown(); - Uninterruptibles.awaitUninterruptibly(t2Running); - transaction.buffer( - Mutation.newUpdateBuilder("T") - .set("K") - .to(key1) - .set("V") - .to(row.getLong(0) + 1) - .build()); - return null; - } catch (SpannerException e) { - if (e.getErrorCode() == ErrorCode.ABORTED) { - assertThat(e).isInstanceOf(AbortedException.class); - assertThat(((AbortedException) e).getRetryDelayInMillis()) - .isNotEqualTo(-1L); + new Thread( + () -> { + try { + client + .readWriteTransaction() + .run( + transaction -> { + try { + Struct row = + transaction.readRow( + "T", Key.of(key1), Collections.singletonList("V")); + t1Started.countDown(); + Uninterruptibles.awaitUninterruptibly(t2Running); + transaction.buffer( + Mutation.newUpdateBuilder("T") + .set("K") + .to(key1) + .set("V") + .to(row.getLong(0) + 1) + .build()); + return null; + } catch (SpannerException e) { + if (e.getErrorCode() == ErrorCode.ABORTED) { + assertThat(e).isInstanceOf(AbortedException.class); + assertThat(e.getRetryDelayInMillis()).isNotEqualTo(-1L); + } + throw new RuntimeException("Swallowed exception: " + e.getMessage()); } - throw new RuntimeException("Swallowed exception: " + e.getMessage()); - } - }); - t1Result.set(null); - } catch (Throwable t) { - t1Result.setException(t); - } finally { - t1Done.countDown(); - } - } - }; + }); + t1Result.set(null); + } catch (Throwable t) { + t1Result.setException(t); + } finally { + t1Done.countDown(); + } + }); Thread t2 = - new Thread() { - @Override - public void run() { - try { - client - .readWriteTransaction() - .run( - transaction -> { - try { - Struct r1 = transaction.readRow("T", Key.of(key1), Arrays.asList("V")); - t2Running.countDown(); - Uninterruptibles.awaitUninterruptibly(t1Done); - Struct r2 = transaction.readRow("T", Key.of(key2), Arrays.asList("V")); - transaction.buffer( - Mutation.newUpdateBuilder("T") - .set("K") - .to(key2) - .set("V") - .to(r1.getLong(0) + r2.getLong(0)) - .build()); - return null; - } catch (SpannerException e) { - if (e.getErrorCode() == ErrorCode.ABORTED) { - assertThat(e).isInstanceOf(AbortedException.class); - assertThat(((AbortedException) e).getRetryDelayInMillis()) - .isNotEqualTo(-1L); + new Thread( + () -> { + try { + client + .readWriteTransaction() + .run( + transaction -> { + try { + Struct r1 = + transaction.readRow( + "T", Key.of(key1), Collections.singletonList("V")); + t2Running.countDown(); + Uninterruptibles.awaitUninterruptibly(t1Done); + Struct r2 = + transaction.readRow( + "T", Key.of(key2), Collections.singletonList("V")); + transaction.buffer( + Mutation.newUpdateBuilder("T") + .set("K") + .to(key2) + .set("V") + .to(r1.getLong(0) + r2.getLong(0)) + .build()); + return null; + } catch (SpannerException e) { + if (e.getErrorCode() == ErrorCode.ABORTED) { + assertThat(e).isInstanceOf(AbortedException.class); + assertThat(e.getRetryDelayInMillis()).isNotEqualTo(-1L); + } + throw new RuntimeException("Swallowed exception: " + e.getMessage()); } - throw new RuntimeException("Swallowed exception: " + e.getMessage()); - } - }); - t2Result.set(null); - } catch (Throwable t) { - t2Result.setException(t); - } finally { - t2Done.countDown(); - } - } - }; + }); + t2Result.set(null); + } catch (Throwable t) { + t2Result.setException(t); + } finally { + t2Done.countDown(); + } + }); t1.start(); Uninterruptibles.awaitUninterruptibly(t1Started); @@ -365,13 +363,13 @@ public void run() { assertThat( client .singleUse(TimestampBound.strong()) - .readRow("T", Key.of(key1), Arrays.asList("V")) + .readRow("T", Key.of(key1), Collections.singletonList("V")) .getLong(0)) .isEqualTo(1); assertThat( client .singleUse(TimestampBound.strong()) - .readRow("T", Key.of(key2), Arrays.asList("V")) + .readRow("T", Key.of(key2), Collections.singletonList("V")) .getLong(0)) .isEqualTo(2); } @@ -433,7 +431,7 @@ public void nestedBatchTxnThrows() { "Test", "Index", KeySet.all(), - Arrays.asList("Fingerprint")); + Collections.singletonList("Fingerprint")); return null; }); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITVPCNegativeTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITVPCNegativeTest.java index 230a252bb9d..584ab0ff86f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITVPCNegativeTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITVPCNegativeTest.java @@ -49,7 +49,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.logging.Logger; @@ -189,7 +189,7 @@ public void deniedRead() { ResultSet rs = databaseClient .singleUse() - .read("nonexistent-table", KeySet.all(), Arrays.asList("nonexistent-col")); + .read("nonexistent-table", KeySet.all(), Collections.singletonList("nonexistent-col")); try { // Tests that the initial create session request returns a permission denied. rs.next(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITWriteTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITWriteTest.java index 7e9916ae9e8..fd9fc78ef3f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITWriteTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITWriteTest.java @@ -47,6 +47,7 @@ import io.grpc.Context; import java.math.BigDecimal; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -133,7 +134,7 @@ private static String uniqueString() { private String lastKey; private Timestamp write(Mutation m) { - return client.write(Arrays.asList(m)); + return client.write(Collections.singletonList(m)); } private Mutation.WriteBuilder baseInsert() { @@ -149,7 +150,7 @@ private Struct readLastRow(String... columns) { @Test public void writeAtLeastOnce() { client.writeAtLeastOnce( - Arrays.asList( + Collections.singletonList( Mutation.newInsertOrUpdateBuilder("T") .set("K") .to(lastKey = uniqueString()) @@ -166,7 +167,7 @@ public void testWriteReturnsCommitStats() { assumeFalse("Emulator does not return commit statistics", isUsingEmulator()); CommitResponse response = client.writeWithOptions( - Arrays.asList( + Collections.singletonList( Mutation.newInsertOrUpdateBuilder("T") .set("K") .to(lastKey = uniqueString()) @@ -185,7 +186,7 @@ public void testWriteAtLeastOnceReturnsCommitStats() { assumeFalse("Emulator does not return commit statistics", isUsingEmulator()); CommitResponse response = client.writeAtLeastOnceWithOptions( - Arrays.asList( + Collections.singletonList( Mutation.newInsertOrUpdateBuilder("T") .set("K") .to(lastKey = uniqueString()) @@ -202,7 +203,7 @@ public void testWriteAtLeastOnceReturnsCommitStats() { @Test public void writeAlreadyExists() { client.write( - Arrays.asList( + Collections.singletonList( Mutation.newInsertBuilder("T") .set("K") .to(lastKey = "key1") @@ -215,7 +216,7 @@ public void writeAlreadyExists() { try { client.write( - Arrays.asList( + Collections.singletonList( Mutation.newInsertBuilder("T") .set("K") .to(lastKey) @@ -235,7 +236,7 @@ public void writeAlreadyExists() { @Test public void emptyWrite() { try { - client.write(Arrays.asList()); + client.write(Collections.emptyList()); fail("Expected exception"); } catch (SpannerException ex) { assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); @@ -570,7 +571,7 @@ public void writeStringArrayNull() { @Test public void writeStringArrayEmpty() { - write(baseInsert().set("StringArrayValue").toStringArray(Arrays.asList()).build()); + write(baseInsert().set("StringArrayValue").toStringArray(Collections.emptyList()).build()); Struct row = readLastRow("StringArrayValue"); assertThat(row.isNull(0)).isFalse(); assertThat(row.getStringList(0)).containsExactly(); @@ -594,7 +595,7 @@ public void writeBytesArrayNull() { @Test public void writeBytesArrayEmpty() { - write(baseInsert().set("BytesArrayValue").toBytesArray(Arrays.asList()).build()); + write(baseInsert().set("BytesArrayValue").toBytesArray(Collections.emptyList()).build()); Struct row = readLastRow("BytesArrayValue"); assertThat(row.isNull(0)).isFalse(); assertThat(row.getBytesList(0)).containsExactly(); @@ -619,10 +620,7 @@ public void writeTimestampArrayNull() { @Test public void writeTimestampArrayEmpty() { write( - baseInsert() - .set("TimestampArrayValue") - .toTimestampArray(Arrays.asList()) - .build()); + baseInsert().set("TimestampArrayValue").toTimestampArray(Collections.emptyList()).build()); Struct row = readLastRow("TimestampArrayValue"); assertThat(row.isNull(0)).isFalse(); assertThat(row.getTimestampList(0)).containsExactly(); @@ -651,7 +649,7 @@ public void writeDateArrayNull() { @Test public void writeDateArrayEmpty() { - write(baseInsert().set("DateArrayValue").toDateArray(Arrays.asList()).build()); + write(baseInsert().set("DateArrayValue").toDateArray(Collections.emptyList()).build()); Struct row = readLastRow("DateArrayValue"); assertThat(row.isNull(0)).isFalse(); assertThat(row.getDateList(0)).containsExactly(); @@ -678,11 +676,7 @@ public void writeNumericArrayNull() { @Test public void writeNumericArrayEmpty() { assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator()); - write( - baseInsert() - .set("NumericArrayValue") - .toNumericArray(ImmutableList.of()) - .build()); + write(baseInsert().set("NumericArrayValue").toNumericArray(ImmutableList.of()).build()); Struct row = readLastRow("NumericArrayValue"); assertThat(row.isNull(0)).isFalse(); assertThat(row.getBigDecimalList(0)).containsExactly(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java index 71f988fb39b..39e16fcca40 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java @@ -23,7 +23,6 @@ import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; -import com.google.api.core.ApiFunction; import com.google.api.gax.core.GaxProperties; import com.google.api.gax.rpc.ApiCallContext; import com.google.api.gax.rpc.HeaderProvider; @@ -43,7 +42,6 @@ import com.google.cloud.spanner.SpannerExceptionFactory; import com.google.cloud.spanner.SpannerOptions; import com.google.cloud.spanner.SpannerOptions.CallContextConfigurator; -import com.google.cloud.spanner.SpannerOptions.CallCredentialsProvider; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.admin.database.v1.MockDatabaseAdminImpl; import com.google.cloud.spanner.admin.instance.v1.MockInstanceAdminImpl; @@ -64,10 +62,8 @@ import com.google.spanner.v1.StructType; import com.google.spanner.v1.StructType.Field; import com.google.spanner.v1.TypeCode; -import io.grpc.CallCredentials; import io.grpc.Context; import io.grpc.Contexts; -import io.grpc.ManagedChannelBuilder; import io.grpc.Metadata; import io.grpc.Metadata.Key; import io.grpc.MethodDescriptor; @@ -319,13 +315,7 @@ public void testCallCredentialsProviderPreferenceAboveCredentials() { SpannerOptions.newBuilder() .setProjectId("some-project") .setCredentials(STATIC_CREDENTIALS) - .setCallCredentialsProvider( - new CallCredentialsProvider() { - @Override - public CallCredentials getCallCredentials() { - return MoreCallCredentials.from(VARIABLE_CREDENTIALS); - } - }) + .setCallCredentialsProvider(() -> MoreCallCredentials.from(VARIABLE_CREDENTIALS)) .build(); GapicSpannerRpc rpc = new GapicSpannerRpc(options); // GoogleAuthLibraryCallCredentials doesn't implement equals, so we can only check for the @@ -348,13 +338,7 @@ public void testCallCredentialsProviderReturnsNull() { SpannerOptions.newBuilder() .setProjectId("some-project") .setCredentials(STATIC_CREDENTIALS) - .setCallCredentialsProvider( - new CallCredentialsProvider() { - @Override - public CallCredentials getCallCredentials() { - return null; - } - }) + .setCallCredentialsProvider(() -> null) .build(); GapicSpannerRpc rpc = new GapicSpannerRpc(options); assertThat( @@ -511,13 +495,10 @@ public void testDefaultUserAgent() { public void testCustomUserAgent() { for (String headerId : new String[] {"user-agent", "User-Agent", "USER-AGENT"}) { final HeaderProvider userAgentHeaderProvider = - new HeaderProvider() { - @Override - public Map getHeaders() { - final Map headers = new HashMap<>(); - headers.put(headerId, "test-agent"); - return headers; - } + () -> { + final Map headers = new HashMap<>(); + headers.put(headerId, "test-agent"); + return headers; }; final SpannerOptions options = createSpannerOptions().toBuilder().setHeaderProvider(userAgentHeaderProvider).build(); @@ -535,32 +516,22 @@ public Map getHeaders() { } } - @SuppressWarnings("rawtypes") private SpannerOptions createSpannerOptions() { String endpoint = address.getHostString() + ":" + server.getPort(); return SpannerOptions.newBuilder() .setProjectId("[PROJECT]") // Set a custom channel configurator to allow http instead of https. .setChannelConfigurator( - new ApiFunction() { - @Override - public ManagedChannelBuilder apply(ManagedChannelBuilder input) { - input.usePlaintext(); - return input; - } + input -> { + input.usePlaintext(); + return input; }) .setHost("https://" + endpoint) // Set static credentials that will return the static OAuth test token. .setCredentials(STATIC_CREDENTIALS) // Also set a CallCredentialsProvider. These credentials should take precedence above // the static credentials. - .setCallCredentialsProvider( - new CallCredentialsProvider() { - @Override - public CallCredentials getCallCredentials() { - return MoreCallCredentials.from(VARIABLE_CREDENTIALS); - } - }) + .setCallCredentialsProvider(() -> MoreCallCredentials.from(VARIABLE_CREDENTIALS)) .build(); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/SpannerMetadataProviderTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/SpannerMetadataProviderTest.java index a76e6e7ebb7..07e13626c18 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/SpannerMetadataProviderTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/SpannerMetadataProviderTest.java @@ -44,7 +44,7 @@ public void testGetHeadersAsMetadata() { @Test public void testGetResourceHeaderValue() { SpannerMetadataProvider metadataProvider = - SpannerMetadataProvider.create(ImmutableMap.of(), "header3"); + SpannerMetadataProvider.create(ImmutableMap.of(), "header3"); assertEquals("projects/p", getResourceHeaderValue(metadataProvider, "garbage")); assertEquals("projects/p", getResourceHeaderValue(metadataProvider, "projects/p")); @@ -75,11 +75,11 @@ public void testGetResourceHeaderValue() { @Test public void testNewExtraHeaders() { SpannerMetadataProvider metadataProvider = - SpannerMetadataProvider.create(ImmutableMap.of(), "header1"); + SpannerMetadataProvider.create(ImmutableMap.of(), "header1"); Map> extraHeaders = metadataProvider.newExtraHeaders(null, "value1"); assertThat(extraHeaders) .containsExactlyEntriesIn( - ImmutableMap.>of("header1", ImmutableList.of("value1"))); + ImmutableMap.>of("header1", ImmutableList.of("value1"))); } private String getResourceHeaderValue( From 85bd0cf11eab7b2ec47a082a4c2c0c4d9cea01d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Mon, 3 May 2021 08:46:56 +0200 Subject: [PATCH 07/27] docs: close Spanner instance when it is no longer needed (#1116) The CreateInstance example opened a Spanner instance without closing it. That was spamming the test logs with a lot of warnings. --- .../main/java/com/example/spanner/CreateInstanceExample.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/samples/snippets/src/main/java/com/example/spanner/CreateInstanceExample.java b/samples/snippets/src/main/java/com/example/spanner/CreateInstanceExample.java index fe7e6ec4248..44e36a8b274 100644 --- a/samples/snippets/src/main/java/com/example/spanner/CreateInstanceExample.java +++ b/samples/snippets/src/main/java/com/example/spanner/CreateInstanceExample.java @@ -65,6 +65,8 @@ static void createInstance(String projectId, String instanceId) { instanceInfo.getId(), e.getMessage()); } catch (InterruptedException e) { System.out.println("Error: Waiting for createInstance operation to finish was interrupted"); + } finally { + spanner.close(); } } } From 1d2f478a6042cf8e4785111cfb3f1f6684b30b4b Mon Sep 17 00:00:00 2001 From: Thiago Nunes Date: Mon, 3 May 2021 17:04:44 +1000 Subject: [PATCH 08/27] chore: adds branch 3.3.x as stable (#1123) * chore: adds branch 3.3.x as stable Also removes clirr / linkage monitor from non master branches since they only work for the master branch. * chore: adds branch 3.3.x to release please config --- .github/release-please.yml | 3 +++ .github/sync-repo-settings.yaml | 31 +++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/.github/release-please.yml b/.github/release-please.yml index 30330ae5169..d7589c23dac 100644 --- a/.github/release-please.yml +++ b/.github/release-please.yml @@ -4,6 +4,9 @@ branches: - branch: 3.1.x releaseType: java-yoshi bumpMinorPreMajor: true +- branch: 3.3.x + releaseType: java-yoshi + bumpMinorPreMajor: true - branch: 4.0.x releaseType: java-yoshi bumpMinorPreMajor: true diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index 11a26167e3b..dff2e8609ba 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -57,9 +57,32 @@ branchProtectionRules: requiredStatusCheckContexts: - "dependencies (8)" - "dependencies (11)" - - "linkage-monitor" - "lint" - - "clirr" + - "units (7)" + - "units (8)" + - "units (11)" + - "Kokoro - Test: Integration" + - "cla/google" + +# Identifies the protection rule pattern. Name of the branch to be protected. +# Defaults to `master` +- pattern: 3.3.x + # Can admins overwrite branch protection. + # Defaults to `true` + isAdminEnforced: true + # Number of approving reviews required to update matching branches. + # Defaults to `1` + requiredApprovingReviewCount: 1 + # Are reviews from code owners required to update matching branches. + # Defaults to `false` + requiresCodeOwnerReviews: true + # Require up to date branches + requiresStrictStatusChecks: false + # List of required status check contexts that must pass for commits to be accepted to matching branches. + requiredStatusCheckContexts: + - "dependencies (8)" + - "dependencies (11)" + - "lint" - "units (7)" - "units (8)" - "units (11)" @@ -84,9 +107,7 @@ branchProtectionRules: requiredStatusCheckContexts: - "dependencies (8)" - "dependencies (11)" - - "linkage-monitor" - "lint" - - "clirr" - "units (7)" - "units (8)" - "units (11)" @@ -111,9 +132,7 @@ branchProtectionRules: requiredStatusCheckContexts: - "dependencies (8)" - "dependencies (11)" - - "linkage-monitor" - "lint" - - "clirr" - "units (7)" - "units (8)" - "units (11)" From 7564c11dcf4e06a85d288c88754fe0f0acf47e26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Mon, 3 May 2021 23:53:45 +0200 Subject: [PATCH 09/27] test: move begin() outside retry loop (#1134) The begin() call should be before the retry loop, and not inside. The catch clause for an AbortedException should reset the transaction manager and assign the new transaction context to the original transaction context variable. Fixes #1125 --- .../cloud/spanner/DatabaseClientImplTest.java | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java index ed0af902a98..991e2c6cb68 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java @@ -894,32 +894,34 @@ public void runAsyncWithException() throws Exception { executor.shutdown(); } + @SuppressWarnings("resource") @Test public void testTransactionManager() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); try (TransactionManager manager = client.transactionManager()) { + TransactionContext transaction = manager.begin(); while (true) { - TransactionContext transaction = manager.begin(); try { transaction.executeUpdate(UPDATE_STATEMENT); manager.commit(); assertNotNull(manager.getCommitTimestamp()); break; } catch (AbortedException e) { - manager.resetForRetry(); + transaction = manager.resetForRetry(); } } } } + @SuppressWarnings("resource") @Test public void testTransactionManager_returnsCommitStats() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); try (TransactionManager manager = client.transactionManager(Options.commitStats())) { + TransactionContext transaction = manager.begin(); while (true) { - TransactionContext transaction = manager.begin(); try { transaction.buffer(Mutation.delete("FOO", Key.of("foo"))); manager.commit(); @@ -928,12 +930,13 @@ public void testTransactionManager_returnsCommitStats() { assertEquals(1L, manager.getCommitResponse().getCommitStats().getMutationCount()); break; } catch (AbortedException e) { - manager.resetForRetry(); + transaction = manager.resetForRetry(); } } } } + @SuppressWarnings("resource") @Test public void transactionManagerIsNonBlocking() throws Exception { mockSpanner.freeze(); @@ -941,16 +944,16 @@ public void transactionManagerIsNonBlocking() throws Exception { spannerWithEmptySessionPool.getDatabaseClient( DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); try (TransactionManager txManager = client.transactionManager()) { + mockSpanner.unfreeze(); + TransactionContext transaction = txManager.begin(); while (true) { - mockSpanner.unfreeze(); - TransactionContext tx = txManager.begin(); try { - tx.executeUpdate(UPDATE_STATEMENT); + transaction.executeUpdate(UPDATE_STATEMENT); txManager.commit(); break; } catch (AbortedException e) { Thread.sleep(e.getRetryDelayInMillis()); - txManager.resetForRetry(); + transaction = txManager.resetForRetry(); } } } @@ -962,10 +965,10 @@ public void transactionManagerExecuteQueryAsync() throws Exception { spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); final AtomicInteger rowCount = new AtomicInteger(); try (TransactionManager txManager = client.transactionManager()) { + TransactionContext transaction = txManager.begin(); while (true) { - TransactionContext tx = txManager.begin(); try { - try (AsyncResultSet rs = tx.executeQueryAsync(SELECT1)) { + try (AsyncResultSet rs = transaction.executeQueryAsync(SELECT1)) { rs.setCallback( executor, resultSet -> { @@ -990,7 +993,7 @@ public void transactionManagerExecuteQueryAsync() throws Exception { break; } catch (AbortedException e) { Thread.sleep(e.getRetryDelayInMillis()); - txManager.resetForRetry(); + transaction = txManager.resetForRetry(); } } } From 699a4260e3b1a4cf53fc690910aeeadac293e469 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Thu, 6 May 2021 06:24:47 +0200 Subject: [PATCH 10/27] deps: update dependency org.openjdk.jmh:jmh-core to v1.30 (#1137) --- google-cloud-spanner/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index 014f79bae3e..d295b62d36e 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -305,7 +305,7 @@ org.openjdk.jmh jmh-core - 1.29 + 1.30 test From b3ebfcfc4acae43af85a62252e78b60426dd6802 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Thu, 6 May 2021 08:06:57 +0200 Subject: [PATCH 11/27] chore: use assertThrows with lambda instead of try-catch (#1139) Fixes #1124 --- .../AbstractStructReaderTypesTest.java | 52 +-- .../cloud/spanner/AsyncResultSetImplTest.java | 52 +-- .../cloud/spanner/AsyncRunnerImplTest.java | 40 +- .../google/cloud/spanner/AsyncRunnerTest.java | 76 ++-- .../spanner/AsyncTransactionManagerTest.java | 121 ++--- .../google/cloud/spanner/BackupIdTest.java | 11 +- .../com/google/cloud/spanner/BackupTest.java | 19 +- .../spanner/DatabaseAdminClientImplTest.java | 33 +- .../spanner/DatabaseAdminClientTest.java | 104 ++--- .../cloud/spanner/DatabaseClientImplTest.java | 168 +++---- .../google/cloud/spanner/DatabaseIdTest.java | 11 +- .../cloud/spanner/GrpcResultSetTest.java | 29 +- .../spanner/InlineBeginTransactionTest.java | 429 +++++++++--------- .../cloud/spanner/InstanceConfigIdTest.java | 11 +- .../google/cloud/spanner/InstanceIdTest.java | 11 +- .../google/cloud/spanner/KeyRangeTest.java | 22 +- .../spanner/LazySpannerInitializerTest.java | 18 +- .../google/cloud/spanner/MutationTest.java | 48 +- .../google/cloud/spanner/OperationTest.java | 27 +- .../com/google/cloud/spanner/OptionsTest.java | 38 +- .../cloud/spanner/PartitionOptionsTest.java | 24 +- .../PartitionedDmlTransactionTest.java | 86 ++-- .../google/cloud/spanner/ReadAsyncTest.java | 46 +- ...adWriteTransactionWithInlineBeginTest.java | 116 +++-- .../google/cloud/spanner/ResultSetsTest.java | 52 +-- .../spanner/ResumableStreamIteratorTest.java | 19 +- .../google/cloud/spanner/SessionImplTest.java | 226 +++++---- .../cloud/spanner/SessionPoolLeakTest.java | 29 +- .../google/cloud/spanner/SessionPoolTest.java | 43 +- .../com/google/cloud/spanner/SpanTest.java | 42 +- .../cloud/spanner/SpannerApiFuturesTest.java | 54 +-- .../cloud/spanner/SpannerGaxRetryTest.java | 76 +--- .../google/cloud/spanner/SpannerImplTest.java | 28 +- .../cloud/spanner/SpannerOptionsTest.java | 43 +- .../cloud/spanner/SpannerRetryHelperTest.java | 55 +-- .../google/cloud/spanner/StatementTest.java | 35 +- .../cloud/spanner/TimestampBoundTest.java | 24 +- .../spanner/TransactionManagerImplTest.java | 88 ++-- .../spanner/TransactionRunnerImplTest.java | 48 +- .../com/google/cloud/spanner/TypeTest.java | 38 +- .../com/google/cloud/spanner/ValueTest.java | 390 ++++++---------- 41 files changed, 1121 insertions(+), 1761 deletions(-) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractStructReaderTypesTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractStructReaderTypesTest.java index 5873d466d35..74f0a67b806 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractStructReaderTypesTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractStructReaderTypesTest.java @@ -20,7 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import static org.junit.runners.Parameterized.Parameter; import com.google.cloud.ByteArray; @@ -408,22 +408,24 @@ public void getterForIncorrectType() { // Skip allowed getters. continue; } - try { - getterByIndex(method.getName(), columnIndex); - fail("Expected " + IllegalStateException.class.getSimpleName() + " for " + method); - } catch (IllegalStateException e) { - assertWithMessage("Exception for " + method).that(e.getMessage()).contains("was " + type); - assertWithMessage("Exception for " + method) - .that(e.getMessage()) - .contains("Column " + columnIndex); - } - try { - getterByName(method.getName(), "F1"); - fail("Expected ISE for " + method); - } catch (IllegalStateException e) { - assertWithMessage("Exception for " + method).that(e.getMessage()).contains("was " + type); - assertWithMessage("Exception for " + method).that(e.getMessage()).contains("Column F1"); - } + IllegalStateException getterByIndexException = + assertThrows( + IllegalStateException.class, () -> getterByIndex(method.getName(), columnIndex)); + assertWithMessage("Exception for " + method) + .that(getterByIndexException.getMessage()) + .contains("was " + type); + assertWithMessage("Exception for " + method) + .that(getterByIndexException.getMessage()) + .contains("Column " + columnIndex); + + IllegalStateException getterByNameException = + assertThrows(IllegalStateException.class, () -> getterByName(method.getName(), "F1")); + assertWithMessage("Exception for " + method) + .that(getterByNameException.getMessage()) + .contains("was " + type); + assertWithMessage("Exception for " + method) + .that(getterByNameException.getMessage()) + .contains("Column F1"); } } @@ -431,23 +433,15 @@ public void getterForIncorrectType() { public void getterWhenNull() { Mockito.when(reader.getType()).thenReturn(Type.struct(StructField.of("F1", type))); Mockito.when(reader.isNull(0)).thenReturn(true); - try { - getterByIndex(0); - fail("Expected exception"); - } catch (NullPointerException ex) { - assertNotNull(ex.getMessage()); - } + NullPointerException ex = assertThrows(NullPointerException.class, () -> getterByIndex(0)); + assertNotNull(ex.getMessage()); } @Test public void getterByNameWhenNull() { Mockito.when(reader.getType()).thenReturn(Type.struct(StructField.of("F1", type))); Mockito.when(reader.isNull(0)).thenReturn(true); - try { - getterByName("F1"); - fail("Expected exception"); - } catch (NullPointerException ex) { - assertNotNull(ex.getMessage()); - } + NullPointerException ex = assertThrows(NullPointerException.class, () -> getterByName("F1")); + assertNotNull(ex.getMessage()); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncResultSetImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncResultSetImplTest.java index 28a46d8951d..e9f5ac73728 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncResultSetImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncResultSetImplTest.java @@ -17,7 +17,7 @@ package com.google.cloud.spanner; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -68,24 +68,13 @@ public void close() { rs.close(); // The following methods are not allowed to call after closing the result set. - try { - rs.setCallback(mock(Executor.class), mock(ReadyCallback.class)); - fail("missing expected exception"); - } catch (IllegalStateException e) { - // Expected exception - } - try { - rs.toList(mock(Function.class)); - fail("missing expected exception"); - } catch (IllegalStateException e) { - // Expected exception - } - try { - rs.toListAsync(mock(Function.class), mock(Executor.class)); - fail("missing expected exception"); - } catch (IllegalStateException e) { - // Expected exception - } + assertThrows( + IllegalStateException.class, + () -> rs.setCallback(mock(Executor.class), mock(ReadyCallback.class))); + assertThrows(IllegalStateException.class, () -> rs.toList(mock(Function.class))); + assertThrows( + IllegalStateException.class, + () -> rs.toListAsync(mock(Function.class), mock(Executor.class))); // The following methods are allowed on a closed result set. AsyncResultSetImpl rs2 = @@ -103,13 +92,8 @@ public void tryNextNotAllowed() { new AsyncResultSetImpl( mockedProvider, mock(ResultSet.class), AsyncResultSetImpl.DEFAULT_BUFFER_SIZE)) { rs.setCallback(mock(Executor.class), mock(ReadyCallback.class)); - try { - rs.tryNext(); - fail("missing expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage()) - .contains("tryNext may only be called from a DataReady callback."); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> rs.tryNext()); + assertThat(e.getMessage()).contains("tryNext may only be called from a DataReady callback."); } } @@ -134,9 +118,8 @@ public void toListPropagatesError() { ErrorCode.INVALID_ARGUMENT, "invalid query")); try (AsyncResultSetImpl rs = new AsyncResultSetImpl(simpleProvider, delegate, AsyncResultSetImpl.DEFAULT_BUFFER_SIZE)) { - rs.toList(ignored -> new Object()); - fail("missing expected exception"); - } catch (SpannerException e) { + SpannerException e = + assertThrows(SpannerException.class, () -> rs.toList(ignored -> new Object())); assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); assertThat(e.getMessage()).contains("invalid query"); } @@ -166,9 +149,10 @@ public void toListAsyncPropagatesError() throws InterruptedException { ErrorCode.INVALID_ARGUMENT, "invalid query")); try (AsyncResultSetImpl rs = new AsyncResultSetImpl(simpleProvider, delegate, AsyncResultSetImpl.DEFAULT_BUFFER_SIZE)) { - rs.toListAsync(ignored -> new Object(), executor).get(); - fail("missing expected exception"); - } catch (ExecutionException e) { + ExecutionException e = + assertThrows( + ExecutionException.class, + () -> rs.toListAsync(ignored -> new Object(), executor).get()); assertThat(e.getCause()).isInstanceOf(SpannerException.class); SpannerException se = (SpannerException) e.getCause(); assertThat(se.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); @@ -386,9 +370,7 @@ public void callbackReturnsError() throws InterruptedException { callbackCounter.incrementAndGet(); throw new RuntimeException("async test"); }); - rs.getResult().get(); - fail("missing expected exception"); - } catch (ExecutionException e) { + ExecutionException e = assertThrows(ExecutionException.class, () -> rs.getResult().get()); assertThat(e.getCause()).isInstanceOf(SpannerException.class); SpannerException se = (SpannerException) e.getCause(); assertThat(se.getErrorCode()).isEqualTo(ErrorCode.UNKNOWN); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncRunnerImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncRunnerImplTest.java index af8fd8e5329..e1057663df5 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncRunnerImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncRunnerImplTest.java @@ -19,8 +19,8 @@ import static com.google.cloud.spanner.SpannerApiFutures.get; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -68,24 +68,18 @@ public void testAsyncRunReturnsResultAndCommitResponse() { public void testGetCommitTimestampReturnsErrorBeforeRun() { TransactionRunnerImpl delegate = mock(TransactionRunnerImpl.class); AsyncRunnerImpl runner = new AsyncRunnerImpl(delegate); - try { - runner.getCommitTimestamp(); - fail("missing expected exception"); - } catch (IllegalStateException e) { - assertTrue(e.getMessage().contains("runAsync() has not yet been called")); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> runner.getCommitTimestamp()); + assertTrue(e.getMessage().contains("runAsync() has not yet been called")); } @Test public void testGetCommitResponseReturnsErrorBeforeRun() { TransactionRunnerImpl delegate = mock(TransactionRunnerImpl.class); AsyncRunnerImpl runner = new AsyncRunnerImpl(delegate); - try { - runner.getCommitResponse(); - fail("missing expected exception"); - } catch (IllegalStateException e) { - assertTrue(e.getMessage().contains("runAsync() has not yet been called")); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> runner.getCommitResponse()); + assertTrue(e.getMessage().contains("runAsync() has not yet been called")); } @Test @@ -99,12 +93,9 @@ public void testGetCommitResponseReturnsErrorIfRunFails() { AsyncRunnerImpl runner = new AsyncRunnerImpl(delegate); runner.runAsync(txn -> ApiFutures.immediateFailedFuture(expectedException), executor); - try { - get(runner.getCommitResponse()); - fail("missing expected exception"); - } catch (SpannerException e) { - assertSame(expectedException, e); - } + SpannerException e = + assertThrows(SpannerException.class, () -> get(runner.getCommitResponse())); + assertSame(expectedException, e); } @SuppressWarnings("unchecked") @@ -117,11 +108,10 @@ public void testRunAsyncFailsIfCalledMultipleTimes() { AsyncRunnerImpl runner = new AsyncRunnerImpl(delegate); runner.runAsync(txn -> ApiFutures.immediateFuture(result), executor); - try { - runner.runAsync(txn -> ApiFutures.immediateFuture(null), executor); - fail("missing expected exception"); - } catch (IllegalStateException e) { - assertTrue(e.getMessage().contains("runAsync() can only be called once")); - } + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> runner.runAsync(txn -> ApiFutures.immediateFuture(null), executor)); + assertTrue(e.getMessage().contains("runAsync() can only be called once")); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncRunnerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncRunnerTest.java index 8caa3feffb7..c1012d7ff8f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncRunnerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncRunnerTest.java @@ -18,8 +18,8 @@ import static com.google.cloud.spanner.MockSpannerTestUtil.*; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; @@ -54,23 +54,17 @@ public class AsyncRunnerTest extends AbstractAsyncTransactionTest { @Test public void testAsyncRunner_doesNotReturnCommitTimestampBeforeCommit() { AsyncRunner runner = client().runAsync(); - try { - runner.getCommitTimestamp(); - fail("missing expected exception"); - } catch (IllegalStateException e) { - assertTrue(e.getMessage().contains("runAsync() has not yet been called")); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> runner.getCommitTimestamp()); + assertTrue(e.getMessage().contains("runAsync() has not yet been called")); } @Test public void testAsyncRunner_doesNotReturnCommitResponseBeforeCommit() { AsyncRunner runner = client().runAsync(); - try { - runner.getCommitResponse(); - fail("missing expected exception"); - } catch (IllegalStateException e) { - assertTrue(e.getMessage().contains("runAsync() has not yet been called")); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> runner.getCommitResponse()); + assertTrue(e.getMessage().contains("runAsync() has not yet been called")); } @Test @@ -103,15 +97,11 @@ public void asyncRunnerInvalidUpdate() throws Exception { AsyncRunner runner = client().runAsync(); ApiFuture updateCount = runner.runAsync(txn -> txn.executeUpdateAsync(INVALID_UPDATE_STATEMENT), executor); - try { - updateCount.get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - SpannerException se = (SpannerException) e.getCause(); - assertThat(se.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - assertThat(se.getMessage()).contains("invalid statement"); - } + ExecutionException e = assertThrows(ExecutionException.class, () -> updateCount.get()); + assertThat(e.getCause()).isInstanceOf(SpannerException.class); + SpannerException se = (SpannerException) e.getCause(); + assertThat(se.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); + assertThat(se.getMessage()).contains("invalid statement"); } @Test @@ -233,15 +223,11 @@ public void asyncRunnerCommitFails() throws Exception { return txn.executeUpdateAsync(UPDATE_STATEMENT); }, executor); - try { - updateCount.get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - SpannerException se = (SpannerException) e.getCause(); - assertThat(se.getErrorCode()).isEqualTo(ErrorCode.RESOURCE_EXHAUSTED); - assertThat(se.getMessage()).contains("mutation limit exceeded"); - } + ExecutionException e = assertThrows(ExecutionException.class, () -> updateCount.get()); + assertThat(e.getCause()).isInstanceOf(SpannerException.class); + SpannerException se = (SpannerException) e.getCause(); + assertThat(se.getErrorCode()).isEqualTo(ErrorCode.RESOURCE_EXHAUSTED); + assertThat(se.getMessage()).contains("mutation limit exceeded"); } @Test @@ -295,15 +281,11 @@ public void asyncRunnerInvalidBatchUpdate() throws Exception { txn -> txn.batchUpdateAsync(ImmutableList.of(UPDATE_STATEMENT, INVALID_UPDATE_STATEMENT)), executor); - try { - updateCount.get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - SpannerException se = (SpannerException) e.getCause(); - assertThat(se.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - assertThat(se.getMessage()).contains("invalid statement"); - } + ExecutionException e = assertThrows(ExecutionException.class, () -> updateCount.get()); + assertThat(e.getCause()).isInstanceOf(SpannerException.class); + SpannerException se = (SpannerException) e.getCause(); + assertThat(se.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); + assertThat(se.getMessage()).contains("invalid statement"); } @Test @@ -423,15 +405,11 @@ public void asyncRunnerWithBatchUpdateCommitFails() throws Exception { return txn.batchUpdateAsync(ImmutableList.of(UPDATE_STATEMENT, UPDATE_STATEMENT)); }, executor); - try { - updateCount.get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - SpannerException se = (SpannerException) e.getCause(); - assertThat(se.getErrorCode()).isEqualTo(ErrorCode.RESOURCE_EXHAUSTED); - assertThat(se.getMessage()).contains("mutation limit exceeded"); - } + ExecutionException e = assertThrows(ExecutionException.class, () -> updateCount.get()); + assertThat(e.getCause()).isInstanceOf(SpannerException.class); + SpannerException se = (SpannerException) e.getCause(); + assertThat(se.getErrorCode()).isEqualTo(ErrorCode.RESOURCE_EXHAUSTED); + assertThat(se.getMessage()).contains("mutation limit exceeded"); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java index 82b46bdee45..345e58b7cbe 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AsyncTransactionManagerTest.java @@ -22,10 +22,11 @@ import static com.google.cloud.spanner.MockSpannerTestUtil.UPDATE_ABORTED_STATEMENT; import static com.google.cloud.spanner.MockSpannerTestUtil.UPDATE_COUNT; import static com.google.cloud.spanner.MockSpannerTestUtil.UPDATE_STATEMENT; +import static com.google.cloud.spanner.SpannerApiFutures.get; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutureCallback; @@ -271,26 +272,15 @@ public void asyncTransactionManagerIsNonBlocking() throws Exception { public void asyncTransactionManagerInvalidUpdate() throws Exception { try (AsyncTransactionManager manager = client().transactionManagerAsync()) { TransactionContextFuture txn = manager.beginAsync(); - while (true) { - try { - CommitTimestampFuture commitTimestamp = - txn.then( - AsyncTransactionManagerHelper.executeUpdateAsync(INVALID_UPDATE_STATEMENT), - executor) - .commitAsync(); - commitTimestamp.get(); - fail("missing expected exception"); - } catch (AbortedException e) { - txn = manager.resetForRetryAsync(); - } catch (ExecutionException e) { - manager.rollbackAsync(); - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - SpannerException se = (SpannerException) e.getCause(); - assertThat(se.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - assertThat(se.getMessage()).contains("invalid statement"); - break; - } - } + CommitTimestampFuture commitTimestamp = + txn.then( + (transaction, ignored) -> + transaction.executeUpdateAsync(INVALID_UPDATE_STATEMENT), + executor) + .commitAsync(); + SpannerException e = assertThrows(SpannerException.class, () -> get(commitTimestamp)); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); + assertThat(e.getMessage()).contains("invalid statement"); } } @@ -538,22 +528,17 @@ public void asyncTransactionManagerCommitFails() throws Exception { .asRuntimeException())); try (AsyncTransactionManager mgr = client().transactionManagerAsync()) { TransactionContextFuture txn = mgr.beginAsync(); - while (true) { - try { - txn.then(AsyncTransactionManagerHelper.executeUpdateAsync(UPDATE_STATEMENT), executor) - .commitAsync() - .get(); - fail("missing expected exception"); - } catch (AbortedException e) { - txn = mgr.resetForRetryAsync(); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - SpannerException se = (SpannerException) e.getCause(); - assertThat(se.getErrorCode()).isEqualTo(ErrorCode.RESOURCE_EXHAUSTED); - assertThat(se.getMessage()).contains("mutation limit exceeded"); - break; - } - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + get( + txn.then( + AsyncTransactionManagerHelper.executeUpdateAsync(UPDATE_STATEMENT), + executor) + .commitAsync())); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.RESOURCE_EXHAUSTED); + assertThat(e.getMessage()).contains("mutation limit exceeded"); } } @@ -635,25 +620,18 @@ public void asyncTransactionManagerInvalidBatchUpdate() throws Exception { SettableApiFuture result = SettableApiFuture.create(); try (AsyncTransactionManager mgr = client().transactionManagerAsync()) { TransactionContextFuture txn = mgr.beginAsync(); - while (true) { - try { - txn.then( - AsyncTransactionManagerHelper.batchUpdateAsync( - result, UPDATE_STATEMENT, INVALID_UPDATE_STATEMENT), - executor) - .commitAsync() - .get(); - fail("missing expected exception"); - } catch (AbortedException e) { - txn = mgr.resetForRetryAsync(); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - SpannerException se = (SpannerException) e.getCause(); - assertThat(se.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - assertThat(se.getMessage()).contains("invalid statement"); - break; - } - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + get( + txn.then( + AsyncTransactionManagerHelper.batchUpdateAsync( + result, UPDATE_STATEMENT, INVALID_UPDATE_STATEMENT), + executor) + .commitAsync())); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); + assertThat(e.getMessage()).contains("invalid statement"); } } @@ -884,25 +862,18 @@ public void asyncTransactionManagerWithBatchUpdateCommitFails() throws Exception .asRuntimeException())); try (AsyncTransactionManager mgr = clientWithEmptySessionPool().transactionManagerAsync()) { TransactionContextFuture txn = mgr.beginAsync(); - while (true) { - try { - txn.then( - AsyncTransactionManagerHelper.batchUpdateAsync( - UPDATE_STATEMENT, UPDATE_STATEMENT), - executor) - .commitAsync() - .get(); - fail("missing expected exception"); - } catch (AbortedException e) { - txn = mgr.resetForRetryAsync(); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - SpannerException se = (SpannerException) e.getCause(); - assertThat(se.getErrorCode()).isEqualTo(ErrorCode.RESOURCE_EXHAUSTED); - assertThat(se.getMessage()).contains("mutation limit exceeded"); - break; - } - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + get( + txn.then( + AsyncTransactionManagerHelper.batchUpdateAsync( + UPDATE_STATEMENT, UPDATE_STATEMENT), + executor) + .commitAsync())); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.RESOURCE_EXHAUSTED); + assertThat(e.getMessage()).contains("mutation limit exceeded"); } assertThat(mockSpanner.getRequestTypes()) .containsExactly( diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BackupIdTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BackupIdTest.java index 629d0261436..76ba64a2ff2 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BackupIdTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BackupIdTest.java @@ -17,7 +17,7 @@ package com.google.cloud.spanner; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import org.junit.Test; import org.junit.runner.RunWith; @@ -42,11 +42,8 @@ public void basics() { @Test public void badName() { - try { - BackupId.of("bad name"); - fail("Expected exception"); - } catch (IllegalArgumentException e) { - assertThat(e.getMessage().contains("projects")); - } + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> BackupId.of("bad name")); + assertThat(e.getMessage().contains("projects")); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BackupTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BackupTest.java index f5053fc8c99..2f12790437c 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BackupTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/BackupTest.java @@ -20,7 +20,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @@ -208,12 +208,9 @@ public void updateExpireTimeWithoutExpireTime() { dbClient .newBackupBuilder(BackupId.of("test-project", "test-instance", "test-backup")) .build(); - try { - backup.updateExpireTime(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertNotNull(e.getMessage()); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> backup.updateExpireTime()); + assertNotNull(e.getMessage()); } @Test @@ -233,12 +230,8 @@ public void restoreWithoutDestination() { dbClient .newBackupBuilder(BackupId.of("test-project", "test-instance", "test-backup")) .build(); - try { - backup.restore(null); - fail("Expected exception"); - } catch (NullPointerException e) { - assertNull(e.getMessage()); - } + NullPointerException e = assertThrows(NullPointerException.class, () -> backup.restore(null)); + assertNull(e.getMessage()); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java index fe8fb709912..4d44861b75b 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java @@ -17,7 +17,7 @@ package com.google.cloud.spanner; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @@ -256,14 +256,12 @@ public void listDatabasesError() { when(rpc.listDatabases(INSTANCE_NAME, 1, null)) .thenThrow( SpannerExceptionFactory.newSpannerException(ErrorCode.INVALID_ARGUMENT, "Test error")); - try { - client.listDatabases(INSTANCE_ID, Options.pageSize(1)); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getMessage()).contains(INSTANCE_NAME); - // Assert that the call was done without a page token. - assertThat(e.getMessage()).contains("with pageToken "); - } + SpannerException e = + assertThrows( + SpannerException.class, () -> client.listDatabases(INSTANCE_ID, Options.pageSize(1))); + assertThat(e.getMessage()).contains(INSTANCE_NAME); + // Assert that the call was done without a page token. + assertThat(e.getMessage()).contains("with pageToken "); } @Test @@ -274,14 +272,15 @@ public void listDatabaseErrorWithToken() { when(rpc.listDatabases(INSTANCE_NAME, 1, pageToken)) .thenThrow( SpannerExceptionFactory.newSpannerException(ErrorCode.INVALID_ARGUMENT, "Test error")); - try { - Lists.newArrayList(client.listDatabases(INSTANCE_ID, Options.pageSize(1)).iterateAll()); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getMessage()).contains(INSTANCE_NAME); - // Assert that the call was done without a page token. - assertThat(e.getMessage()).contains(String.format("with pageToken %s", pageToken)); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + Lists.newArrayList( + client.listDatabases(INSTANCE_ID, Options.pageSize(1)).iterateAll())); + assertThat(e.getMessage()).contains(INSTANCE_NAME); + // Assert that the call was done without a page token. + assertThat(e.getMessage()).contains(String.format("with pageToken %s", pageToken)); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java index a417b12d94c..3a18f24173f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java @@ -16,9 +16,11 @@ package com.google.cloud.spanner; +import static com.google.cloud.spanner.SpannerApiFutures.get; import static com.google.cloud.spanner.testing.TimestampHelper.afterDays; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import com.google.api.gax.longrunning.OperationFuture; import com.google.api.gax.longrunning.OperationSnapshot; @@ -323,39 +325,27 @@ public void databaseBackup() throws InterruptedException, ExecutionException { } @Test - public void dbAdminCreateBackupAlreadyExists() throws InterruptedException { + public void dbAdminCreateBackupAlreadyExists() { OperationFuture op = client.createBackup(INSTANCE_ID, BCK_ID, DB_ID, afterDays(7)); - try { - op.get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - assertThat(((SpannerException) e.getCause()).getErrorCode()) - .isEqualTo(ErrorCode.ALREADY_EXISTS); - } + SpannerException e = assertThrows(SpannerException.class, () -> get(op)); + assertEquals(ErrorCode.ALREADY_EXISTS, e.getErrorCode()); } @Test - public void backupCreateAlreadyExists() throws InterruptedException { + public void backupCreateAlreadyExists() { Backup backup = client .newBackupBuilder(BackupId.of(PROJECT_ID, INSTANCE_ID, BCK_ID)) .setDatabase(DatabaseId.of(PROJECT_ID, INSTANCE_ID, DB_ID)) .setExpireTime(afterDays(7)) .build(); - try { - backup.create().get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - assertThat(((SpannerException) e.getCause()).getErrorCode()) - .isEqualTo(ErrorCode.ALREADY_EXISTS); - } + SpannerException e = assertThrows(SpannerException.class, () -> get(backup.create())); + assertEquals(ErrorCode.ALREADY_EXISTS, e.getErrorCode()); } @Test - public void databaseBackupAlreadyExists() throws InterruptedException { + public void databaseBackupAlreadyExists() { Database db = client.getDatabase(INSTANCE_ID, DB_ID); OperationFuture op = db.backup( @@ -363,32 +353,21 @@ public void databaseBackupAlreadyExists() throws InterruptedException { .newBackupBuilder(BackupId.of(PROJECT_ID, INSTANCE_ID, BCK_ID)) .setExpireTime(afterDays(7)) .build()); - try { - op.get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - assertThat(((SpannerException) e.getCause()).getErrorCode()) - .isEqualTo(ErrorCode.ALREADY_EXISTS); - } + SpannerException e = assertThrows(SpannerException.class, () -> get(op)); + assertEquals(ErrorCode.ALREADY_EXISTS, e.getErrorCode()); } @Test - public void dbAdminCreateBackupDbNotFound() throws InterruptedException { + public void dbAdminCreateBackupDbNotFound() { final String backupId = "other-backup-id"; OperationFuture op = client.createBackup(INSTANCE_ID, backupId, "does-not-exist", afterDays(7)); - try { - op.get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - assertThat(((SpannerException) e.getCause()).getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); - } + SpannerException e = assertThrows(SpannerException.class, () -> get(op)); + assertEquals(ErrorCode.NOT_FOUND, e.getErrorCode()); } @Test - public void backupCreateDbNotFound() throws InterruptedException { + public void backupCreateDbNotFound() { final String backupId = "other-backup-id"; Backup backup = client @@ -396,13 +375,8 @@ public void backupCreateDbNotFound() throws InterruptedException { .setDatabase(DatabaseId.of(PROJECT_ID, INSTANCE_ID, "does-not-exist")) .setExpireTime(afterDays(7)) .build(); - try { - backup.create().get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - assertThat(((SpannerException) e.getCause()).getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); - } + SpannerException e = assertThrows(SpannerException.class, () -> get(backup.create())); + assertEquals(ErrorCode.NOT_FOUND, e.getErrorCode()); } @Test @@ -417,13 +391,8 @@ public void databaseBackupDbNotFound() throws InterruptedException { .newBackupBuilder(BackupId.of(PROJECT_ID, INSTANCE_ID, backupId)) .setExpireTime(afterDays(7)) .build()); - try { - op.get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - assertThat(((SpannerException) e.getCause()).getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); - } + SpannerException e = assertThrows(SpannerException.class, () -> get(op)); + assertEquals(ErrorCode.NOT_FOUND, e.getErrorCode()); } @Test @@ -444,24 +413,18 @@ public void backupDelete() { @Test public void dbAdminDeleteBackupNotFound() { - try { - client.deleteBackup(INSTANCE_ID, "does-not-exist"); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); - } + SpannerException e = + assertThrows( + SpannerException.class, () -> client.deleteBackup(INSTANCE_ID, "does-not-exist")); + assertEquals(ErrorCode.NOT_FOUND, e.getErrorCode()); } @Test public void backupDeleteNotFound() { Backup backup = client.newBackupBuilder(BackupId.of(PROJECT_ID, INSTANCE_ID, "does-not-exist")).build(); - try { - backup.delete(); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); - } + SpannerException e = assertThrows(SpannerException.class, () -> backup.delete()); + assertEquals(ErrorCode.NOT_FOUND, e.getErrorCode()); } @Test @@ -480,22 +443,17 @@ public void backupReload() { @Test public void dbAdminGetBackupNotFound() { - try { - client.getBackup(INSTANCE_ID, "does-not-exist"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); - } + SpannerException e = + assertThrows(SpannerException.class, () -> client.getBackup(INSTANCE_ID, "does-not-exist")); + assertEquals(ErrorCode.NOT_FOUND, e.getErrorCode()); } @Test public void backupReloadNotFound() { Backup backup = client.newBackupBuilder(BackupId.of(PROJECT_ID, INSTANCE_ID, "does-not-exist")).build(); - try { - backup.reload(); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); - } + SpannerException e = assertThrows(SpannerException.class, () -> backup.reload()); + assertEquals(ErrorCode.NOT_FOUND, e.getErrorCode()); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java index 991e2c6cb68..891f2265620 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java @@ -26,8 +26,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -47,6 +47,7 @@ import com.google.cloud.spanner.Options.TransactionOption; import com.google.cloud.spanner.ReadContext.QueryAnalyzeMode; import com.google.cloud.spanner.SessionPool.PooledSessionFuture; +import com.google.cloud.spanner.SpannerException.ResourceNotFoundException; import com.google.cloud.spanner.SpannerOptions.SpannerCallContextTimeoutConfigurator; import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableList; @@ -883,14 +884,12 @@ public void runAsyncWithException() throws Exception { runner.runAsync( txn -> ApiFutures.immediateFuture(txn.executeUpdate(INVALID_UPDATE_STATEMENT)), executor); - try { - fut.get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - SpannerException se = (SpannerException) e.getCause(); - assertThat(se.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - } + + ExecutionException e = assertThrows(ExecutionException.class, () -> fut.get()); + assertThat(e.getCause()).isInstanceOf(SpannerException.class); + SpannerException se = (SpannerException) e.getCause(); + assertThat(se.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); + executor.shutdown(); } @@ -1069,20 +1068,18 @@ public void testPartitionedDmlDoesNotTimeout() { assertThat(updateCount).isEqualTo(UPDATE_COUNT); // Normal DML should timeout. - try { - client - .readWriteTransaction() - .run( - transaction -> { - transaction.executeUpdate(UPDATE_STATEMENT); - return null; - }); - fail("expected DEADLINE_EXCEEDED"); - } catch (SpannerException e) { - if (e.getErrorCode() != ErrorCode.DEADLINE_EXCEEDED) { - fail("expected DEADLINE_EXCEEDED"); - } - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run( + transaction -> { + transaction.executeUpdate(UPDATE_STATEMENT); + return null; + })); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } @@ -1104,14 +1101,10 @@ public void testPartitionedDmlWithLowerTimeout() { // PDML should timeout with these settings. mockSpanner.setExecuteSqlExecutionTime( SimulatedExecutionTime.ofMinimumAndRandomTime(1000, 0)); - try { - client.executePartitionedUpdate(UPDATE_STATEMENT); - fail("expected DEADLINE_EXCEEDED"); - } catch (SpannerException e) { - if (e.getErrorCode() != ErrorCode.DEADLINE_EXCEEDED) { - fail("expected DEADLINE_EXCEEDED"); - } - } + SpannerException e = + assertThrows( + SpannerException.class, () -> client.executePartitionedUpdate(UPDATE_STATEMENT)); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); // Normal DML should not timeout. mockSpanner.setExecuteSqlExecutionTime(SimulatedExecutionTime.ofMinimumAndRandomTime(10, 0)); @@ -1159,14 +1152,14 @@ public void testPartitionedDmlWithHigherTimeout() { // Normal DML should timeout as it should use the ExecuteSQL RPC settings. mockSpanner.setExecuteSqlExecutionTime(SimulatedExecutionTime.ofMinimumAndRandomTime(100, 0)); - try { - client - .readWriteTransaction() - .run(transaction -> transaction.executeUpdate(UPDATE_STATEMENT)); - fail("missing expected DEADLINE_EXCEEDED exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.DEADLINE_EXCEEDED); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run(transaction -> transaction.executeUpdate(UPDATE_STATEMENT))); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.DEADLINE_EXCEEDED); assertThat(updateCount).isEqualTo(UPDATE_COUNT); } } @@ -1253,19 +1246,13 @@ public void testDatabaseOrInstanceDoesNotExistOnCreate() { DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); // The create session failure should propagate to the client and not retry. try (ResultSet rs = dbClient.singleUse().executeQuery(SELECT1)) { - rs.next(); - fail("missing expected exception"); - } catch (DatabaseNotFoundException | InstanceNotFoundException e) { + assertThrows(ResourceNotFoundException.class, () -> rs.next()); // The server should only receive one BatchCreateSessions request. assertThat(mockSpanner.getRequests()).hasSize(1); } - try { - dbClient.readWriteTransaction(); - fail("missing expected exception"); - } catch (DatabaseNotFoundException | InstanceNotFoundException e) { - // No additional requests should have been sent by the client. - assertThat(mockSpanner.getRequests()).hasSize(1); - } + assertThrows(ResourceNotFoundException.class, () -> dbClient.readWriteTransaction()); + // No additional requests should have been sent by the client. + assertThat(mockSpanner.getRequests()).hasSize(1); } mockSpanner.reset(); mockSpanner.removeAllExecutionTimes(); @@ -1359,36 +1346,22 @@ public void testDatabaseOrInstanceIsDeletedAndThenRecreated() throws Exception { // All subsequent calls should fail with a DatabaseNotFoundException. try (ResultSet rs = dbClient.singleUse().executeQuery(SELECT1)) { - while (rs.next()) {} - fail("missing expected exception"); - } catch (DatabaseNotFoundException | InstanceNotFoundException e) { - // Expected exception - } - try { - dbClient.readWriteTransaction().run(transaction -> null); - fail("missing expected exception"); - } catch (DatabaseNotFoundException | InstanceNotFoundException e) { - // Expected exception + assertThrows(ResourceNotFoundException.class, () -> rs.next()); } + assertThrows( + ResourceNotFoundException.class, + () -> dbClient.readWriteTransaction().run(transaction -> null)); // Now simulate that the database has been re-created. The database client should still - // throw - // DatabaseNotFoundExceptions, as it is not the same database. The server should not receive - // any new requests. + // throw DatabaseNotFoundExceptions, as it is not the same database. The server should not + // receive any new requests. mockSpanner.reset(); // All subsequent calls should fail with a DatabaseNotFoundException. - try (ResultSet rs = dbClient.singleUse().executeQuery(SELECT1)) { - while (rs.next()) {} - fail("missing expected exception"); - } catch (DatabaseNotFoundException | InstanceNotFoundException e) { - // Expected exception - } - try { - dbClient.readWriteTransaction().run(transaction -> null); - fail("missing expected exception"); - } catch (DatabaseNotFoundException | InstanceNotFoundException e) { - // Expected exception - } + assertThrows( + ResourceNotFoundException.class, () -> dbClient.singleUse().executeQuery(SELECT1)); + assertThrows( + ResourceNotFoundException.class, + () -> dbClient.readWriteTransaction().run(transaction -> null)); assertThat(mockSpanner.getRequests()).isEmpty(); // Now get a new database client. Normally multiple calls to Spanner#getDatabaseClient will // return the same instance, but not when the instance has been invalidated by a @@ -1437,15 +1410,13 @@ public void testGetInvalidatedClientMultipleTimes() { for (int useClient = 0; useClient < 2; useClient++) { // Using the same client multiple times should continue to return the same // ResourceNotFoundException, even though the session pool has been invalidated. - try (ResultSet rs = dbClient.singleUse().executeQuery(SELECT1)) { - rs.next(); - fail("missing expected exception"); - } catch (DatabaseNotFoundException | InstanceNotFoundException e) { - // The server should only receive one BatchCreateSessions request for each run as we - // have set MinSessions=0. - assertThat(mockSpanner.getRequests()).hasSize(run + 1); - assertThat(dbClient.pool.isValid()).isFalse(); - } + assertThrows( + ResourceNotFoundException.class, + () -> dbClient.singleUse().executeQuery(SELECT1).next()); + // The server should only receive one BatchCreateSessions request for each run as we + // have set MinSessions=0. + assertThat(mockSpanner.getRequests()).hasSize(run + 1); + assertThat(dbClient.pool.isValid()).isFalse(); } } } @@ -1750,13 +1721,9 @@ public void testBatchCreateSessionsPermissionDenied() { DatabaseClient client = spanner.getDatabaseClient(databaseId); // The following call is non-blocking and will not generate an exception. ResultSet rs = client.singleUse().executeQuery(SELECT1); - try { - // Actually trying to get any results will cause an exception. - rs.next(); - fail("missing PERMISSION_DENIED exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.PERMISSION_DENIED); - } + // Actually trying to get any results will cause an exception. + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + assertEquals(ErrorCode.PERMISSION_DENIED, e.getErrorCode()); } } @@ -1772,9 +1739,7 @@ public void testExceptionIncludesStatement() { .singleUse() .executeQuery( Statement.newBuilder("SELECT * FROM FOO WHERE ID=@id").bind("id").to(1L).build())) { - rs.next(); - fail("missing expected exception"); - } catch (SpannerException e) { + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); assertThat(e.getMessage()).contains("Statement: 'SELECT * FROM FOO WHERE ID=@id'"); // The error message should normally not include the parameter values to prevent sensitive @@ -1793,9 +1758,7 @@ public void testExceptionIncludesStatement() { .executeQuery( Statement.newBuilder("SELECT * FROM FOO WHERE ID=@id").bind("id").to(1L).build())) { logger.setLevel(Level.FINEST); - rs.next(); - fail("missing expected exception"); - } catch (SpannerException e) { + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); // With log level set to FINEST the error should also include the parameter values. assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); assertThat(e.getMessage()).contains("Statement: 'SELECT * FROM FOO WHERE ID=@id {id: 1}'"); @@ -1813,9 +1776,7 @@ public void testReadDoesNotIncludeStatement() { spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); try (ResultSet rs = client.singleUse().read("FOO", KeySet.singleKey(Key.of(1L)), ImmutableList.of("BAR"))) { - rs.next(); - fail("missing expected exception"); - } catch (SpannerException e) { + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); assertThat(e.getMessage()).doesNotContain("Statement:"); } @@ -1836,9 +1797,7 @@ public void testSpecificTimeout() { () -> { // Query should fail with a timeout. try (ResultSet rs = client.singleUse().executeQuery(SELECT1)) { - rs.next(); - fail("missing expected DEADLINE_EXCEEDED exception"); - } catch (SpannerException e) { + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); assertThat(e.getErrorCode()).isEqualTo(ErrorCode.DEADLINE_EXCEEDED); } // Update should succeed. @@ -1860,10 +1819,7 @@ public void testBatchCreateSessionsFailure_shouldNotPropagateToCloseMethod() { // This will not cause any failure as getting a session from the pool is guaranteed to be // non-blocking, and any exceptions will be delayed until actual query execution. try (ResultSet rs = client.singleUse().executeQuery(SELECT1)) { - while (rs.next()) { - fail("Missing expected exception"); - } - } catch (SpannerException e) { + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); assertThat(e.getErrorCode()).isEqualTo(ErrorCode.RESOURCE_EXHAUSTED); } } finally { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseIdTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseIdTest.java index 7db3c6cef4e..69d3dce0c93 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseIdTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseIdTest.java @@ -17,7 +17,7 @@ package com.google.cloud.spanner; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import org.junit.Test; import org.junit.runner.RunWith; @@ -42,11 +42,8 @@ public void basics() { @Test public void badName() { - try { - DatabaseId.of("bad name"); - fail("Expected exception"); - } catch (IllegalArgumentException ex) { - assertThat(ex.getMessage()).contains("projects"); - } + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> DatabaseId.of("bad name")); + assertThat(e.getMessage()).contains("projects"); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GrpcResultSetTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GrpcResultSetTest.java index 25c8b8dc35d..3bcd10e2929 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GrpcResultSetTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GrpcResultSetTest.java @@ -18,7 +18,8 @@ import static com.google.common.testing.SerializableTester.reserialize; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import com.google.cloud.ByteArray; import com.google.cloud.Date; @@ -111,24 +112,16 @@ public void metadataFailure() { SpannerException t = SpannerExceptionFactory.newSpannerException(ErrorCode.DEADLINE_EXCEEDED, "outatime"); consumer.onError(t); - try { - resultSet.next(); - fail("Expected exception"); - } catch (SpannerException ex) { - assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.DEADLINE_EXCEEDED); - assertThat(ex.getMessage()).contains("outatime"); - } + SpannerException e = assertThrows(SpannerException.class, () -> resultSet.next()); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); + assertThat(e.getMessage()).contains("outatime"); } @Test public void noMetadata() { consumer.onCompleted(); - try { - resultSet.next(); - fail("Expected exception"); - } catch (SpannerException ex) { - assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); - } + SpannerException e = assertThrows(SpannerException.class, () -> resultSet.next()); + assertEquals(ErrorCode.INTERNAL, e.getErrorCode()); } @Test @@ -207,12 +200,8 @@ public void multiResponseChunkingStreamClosed() { .setChunkedValue(true) .build()); consumer.onCompleted(); - try { - resultSet.next(); - fail("Expected exception"); - } catch (SpannerException ex) { - assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); - } + SpannerException e = assertThrows(SpannerException.class, () -> resultSet.next()); + assertEquals(ErrorCode.INTERNAL, e.getErrorCode()); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InlineBeginTransactionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InlineBeginTransactionTest.java index 6ee90f4e475..021794e16f6 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InlineBeginTransactionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InlineBeginTransactionTest.java @@ -16,9 +16,11 @@ package com.google.cloud.spanner; +import static com.google.cloud.spanner.SpannerApiFutures.get; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; @@ -446,14 +448,9 @@ public void testAsyncTransactionManagerInlinedBeginTxWithError() throws Interrup .then( (transaction, ignored) -> transaction.executeUpdateAsync(UPDATE_STATEMENT), executor); - try { - updateCount.commitAsync().get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - SpannerException se = (SpannerException) e.getCause(); - assertThat(se.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - } + SpannerException e = + assertThrows(SpannerException.class, () -> get(updateCount.commitAsync())); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); break; } catch (AbortedException e) { txn = txMgr.resetForRetryAsync(); @@ -696,12 +693,11 @@ public void testInlinedBeginTxWithError() { .readWriteTransaction() .run( transaction -> { - try { - transaction.executeUpdate(INVALID_UPDATE_STATEMENT); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> transaction.executeUpdate(INVALID_UPDATE_STATEMENT)); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); return transaction.executeUpdate(UPDATE_STATEMENT); }); assertThat(updateCount).isEqualTo(UPDATE_COUNT); @@ -733,24 +729,25 @@ public void testInlinedBeginTxWithErrorOnFirstStatement_andThenErrorOnBeginTrans .asRuntimeException())); DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); - try { - client - .readWriteTransaction() - .run( - transaction -> { - try { - transaction.executeUpdate(INVALID_UPDATE_STATEMENT); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - } - return null; - }); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); - assertThat(e.getMessage()).contains("Begin transaction failed due to an internal error"); - } + SpannerException outerException = + assertThrows( + SpannerException.class, + () -> { + client + .readWriteTransaction() + .run( + transaction -> { + SpannerException innerException = + assertThrows( + SpannerException.class, + () -> transaction.executeUpdate(INVALID_UPDATE_STATEMENT)); + assertEquals(ErrorCode.INVALID_ARGUMENT, innerException.getErrorCode()); + return null; + }); + }); + assertEquals(ErrorCode.INTERNAL, outerException.getErrorCode()); + assertThat(outerException.getMessage()) + .contains("Begin transaction failed due to an internal error"); // The transaction will be retried because the first statement that also tried to include the // BeginTransaction statement failed and did not return a transaction. That forces a retry of // the entire transaction with an explicit BeginTransaction RPC. @@ -765,14 +762,14 @@ public void testInlinedBeginTxWithErrorOnFirstStatement_andThenErrorOnBeginTrans public void testInlinedBeginTxWithUncaughtError() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); - try { - client - .readWriteTransaction() - .run(transaction -> transaction.executeUpdate(INVALID_UPDATE_STATEMENT)); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run(transaction -> transaction.executeUpdate(INVALID_UPDATE_STATEMENT))); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); // The first update will start a transaction, but then fail the update statement. This will // start a transaction on the mock server, but that transaction will never be returned to the // client. @@ -789,20 +786,21 @@ public void testInlinedBeginTxWithUncaughtError() { public void testInlinedBeginTxWithUncaughtErrorAfterSuccessfulBegin() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); - try { - client - .readWriteTransaction() - .run( - transaction -> { - // This statement will start a transaction. - transaction.executeUpdate(UPDATE_STATEMENT); - // This statement will fail and cause a rollback as the exception is not caught. - return transaction.executeUpdate(INVALID_UPDATE_STATEMENT); - }); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run( + transaction -> { + // This statement will start a transaction. + transaction.executeUpdate(UPDATE_STATEMENT); + // This statement will fail and cause a rollback as the exception is not + // caught. + return transaction.executeUpdate(INVALID_UPDATE_STATEMENT); + })); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0); assertThat(countRequests(CommitRequest.class)).isEqualTo(0); assertThat(countRequests(ExecuteSqlRequest.class)).isEqualTo(2); @@ -819,14 +817,14 @@ public void testInlinedBeginTxBatchDmlWithErrorOnFirstStatement() { .readWriteTransaction() .run( transaction -> { - try { - transaction.batchUpdate( - ImmutableList.of(INVALID_UPDATE_STATEMENT, UPDATE_STATEMENT)); - fail("missing expected exception"); - } catch (SpannerBatchUpdateException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - assertThat(e.getUpdateCounts()).hasLength(0); - } + SpannerBatchUpdateException e = + assertThrows( + SpannerBatchUpdateException.class, + () -> + transaction.batchUpdate( + ImmutableList.of(INVALID_UPDATE_STATEMENT, UPDATE_STATEMENT))); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); + assertEquals(0, e.getUpdateCounts().length); return null; }); assertThat(res).isNull(); @@ -847,23 +845,19 @@ public void testInlinedBeginTxBatchDmlWithErrorOnSecondStatement() { .readWriteTransaction() .run( transaction -> { - try { - transaction.batchUpdate( - ImmutableList.of(UPDATE_STATEMENT, INVALID_UPDATE_STATEMENT)); - fail("missing expected exception"); - // The following line is needed as the compiler does not know that this is - // unreachable. - return -1L; - } catch (SpannerBatchUpdateException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - assertThat(e.getUpdateCounts()).hasLength(1); - return e.getUpdateCounts()[0]; - } + SpannerBatchUpdateException e = + assertThrows( + SpannerBatchUpdateException.class, + () -> + transaction.batchUpdate( + ImmutableList.of(UPDATE_STATEMENT, INVALID_UPDATE_STATEMENT))); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); + assertEquals(1, e.getUpdateCounts().length); + return e.getUpdateCounts()[0]; }); assertThat(updateCount).isEqualTo(UPDATE_COUNT); // Although the batch DML returned an error, that error was for the second statement. That - // means - // that the transaction was started by the first statement. + // means that the transaction was started by the first statement. assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0); assertThat(countRequests(ExecuteBatchDmlRequest.class)).isEqualTo(1); assertThat(countRequests(CommitRequest.class)).isEqualTo(1); @@ -880,10 +874,8 @@ public void testInlinedBeginTxWithErrorOnStreamingSql() { .run( transaction -> { try (ResultSet rs = transaction.executeQuery(INVALID_SELECT)) { - while (rs.next()) {} - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); } return null; }); @@ -906,8 +898,7 @@ public void testInlinedBeginTxWithErrorOnSecondPartialResultSet() { RandomResultSetGenerator generator = new RandomResultSetGenerator(2); mockSpanner.putStatementResult(StatementResult.query(statement, generator.generate())); // The first PartialResultSet will be returned successfully, and then a DATA_LOSS exception - // will - // be returned. + // will be returned. mockSpanner.setExecuteStreamingSqlExecutionTime( SimulatedExecutionTime.ofStreamException(Status.DATA_LOSS.asRuntimeException(), 1)); DatabaseClient client = @@ -918,10 +909,9 @@ public void testInlinedBeginTxWithErrorOnSecondPartialResultSet() { .run( transaction -> { try (ResultSet rs = transaction.executeQuery(statement)) { - while (rs.next()) {} - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.DATA_LOSS); + assertTrue(rs.next()); + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + assertEquals(ErrorCode.DATA_LOSS, e.getErrorCode()); } return null; }); @@ -1059,7 +1049,6 @@ public void testTransactionManagerInlinedBeginTxWithOnlyMutations() { assertThat(countTransactionsStarted()).isEqualTo(1); } - @SuppressWarnings("resource") @Test public void testTransactionManagerInlinedBeginTxWithError() { DatabaseClient client = @@ -1067,14 +1056,13 @@ public void testTransactionManagerInlinedBeginTxWithError() { try (TransactionManager txMgr = client.transactionManager()) { TransactionContext txn = txMgr.begin(); while (true) { + final TransactionContext txnToUse = txn; try { - try { - txn.executeUpdate(INVALID_UPDATE_STATEMENT); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - } - assertThat(txn.executeUpdate(UPDATE_STATEMENT)).isEqualTo(UPDATE_COUNT); + SpannerException e = + assertThrows( + SpannerException.class, () -> txnToUse.executeUpdate(INVALID_UPDATE_STATEMENT)); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); + assertEquals(UPDATE_COUNT, txnToUse.executeUpdate(UPDATE_STATEMENT)); txMgr.commit(); break; } catch (AbortedException e) { @@ -1086,28 +1074,19 @@ public void testTransactionManagerInlinedBeginTxWithError() { // the entire transaction, and the retry will do an explicit BeginTransaction RPC. assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(1); // The first statement will start a transaction, but it will never be returned to the client - // as - // the update statement fails. + // as the update statement fails. assertThat(countTransactionsStarted()).isEqualTo(2); } - @SuppressWarnings("resource") @Test public void testTransactionManagerInlinedBeginTxWithUncaughtError() { DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); try (TransactionManager txMgr = client.transactionManager()) { TransactionContext txn = txMgr.begin(); - while (true) { - try { - txn.executeUpdate(INVALID_UPDATE_STATEMENT); - fail("missing expected exception"); - } catch (AbortedException e) { - txn = txMgr.resetForRetry(); - } - } - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); + SpannerException e = + assertThrows(SpannerException.class, () -> txn.executeUpdate(INVALID_UPDATE_STATEMENT)); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); } assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0); assertThat(countTransactionsStarted()).isEqualTo(1); @@ -1349,21 +1328,22 @@ public void testQueryWithInlineBeginDidNotReturnTransaction() { // This will cause the first statement that requests a transaction to not return a transaction // id. mockSpanner.ignoreNextInlineBeginRequest(); - try { - client - .readWriteTransaction() - .run( - transaction -> { - try (ResultSet rs = transaction.executeQuery(SELECT1_UNION_ALL_SELECT2)) { - while (rs.next()) {} - } - return null; - }); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.FAILED_PRECONDITION); - assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run( + transaction -> { + try (ResultSet rs = + transaction.executeQuery(SELECT1_UNION_ALL_SELECT2)) { + while (rs.next()) {} + } + return null; + })); + assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); + assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG); assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0); assertThat(countRequests(ExecuteSqlRequest.class)).isEqualTo(1); assertThat(countRequests(CommitRequest.class)).isEqualTo(0); @@ -1375,19 +1355,18 @@ public void testReadWithInlineBeginDidNotReturnTransaction() { // This will cause the first statement that requests a transaction to not return a transaction // id. mockSpanner.ignoreNextInlineBeginRequest(); - try { - client - .readWriteTransaction() - .run( - transaction -> { - transaction.readRow("FOO", Key.of(1L), Collections.singletonList("BAR")); - return null; - }); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.FAILED_PRECONDITION); - assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run( + transaction -> + transaction.readRow( + "FOO", Key.of(1L), Collections.singletonList("BAR")))); + assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); + assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG); assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0); assertThat(countRequests(ReadRequest.class)).isEqualTo(1); assertThat(countRequests(CommitRequest.class)).isEqualTo(0); @@ -1399,19 +1378,15 @@ public void testUpdateWithInlineBeginDidNotReturnTransaction() { // This will cause the first statement that requests a transaction to not return a transaction // id. mockSpanner.ignoreNextInlineBeginRequest(); - try { - client - .readWriteTransaction() - .run( - transaction -> { - transaction.executeUpdate(UPDATE_STATEMENT); - return null; - }); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.FAILED_PRECONDITION); - assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run(transaction -> transaction.executeUpdate(UPDATE_STATEMENT))); + assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); + assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG); assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0); assertThat(countRequests(ExecuteSqlRequest.class)).isEqualTo(1); assertThat(countRequests(CommitRequest.class)).isEqualTo(0); @@ -1423,19 +1398,19 @@ public void testBatchUpdateWithInlineBeginDidNotReturnTransaction() { // This will cause the first statement that requests a transaction to not return a transaction // id. mockSpanner.ignoreNextInlineBeginRequest(); - try { - client - .readWriteTransaction() - .run( - transaction -> { - transaction.batchUpdate(Collections.singletonList(UPDATE_STATEMENT)); - return null; - }); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.FAILED_PRECONDITION); - assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run( + transaction -> { + transaction.batchUpdate(Collections.singletonList(UPDATE_STATEMENT)); + return null; + })); + assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); + assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG); assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0); assertThat(countRequests(ExecuteBatchDmlRequest.class)).isEqualTo(1); assertThat(countRequests(CommitRequest.class)).isEqualTo(0); @@ -1448,39 +1423,41 @@ public void testQueryAsyncWithInlineBeginDidNotReturnTransaction() { // This will cause the first statement that requests a transaction to not return a transaction // id. mockSpanner.ignoreNextInlineBeginRequest(); - try { - client - .readWriteTransaction() - .run( - transaction -> { - try (AsyncResultSet rs = - transaction.executeQueryAsync(SELECT1_UNION_ALL_SELECT2)) { - return SpannerApiFutures.get( - rs.setCallback( - executor, - resultSet -> { - try { - while (true) { - switch (resultSet.tryNext()) { - case OK: - break; - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - } - } - } catch (SpannerException e) { - return CallbackResponse.DONE; - } - })); - } - }); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.FAILED_PRECONDITION); - assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG); - } + SpannerException outerException = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run( + transaction -> { + try (AsyncResultSet rs = + transaction.executeQueryAsync(SELECT1_UNION_ALL_SELECT2)) { + return SpannerApiFutures.get( + rs.setCallback( + executor, + resultSet -> { + try { + while (true) { + switch (resultSet.tryNext()) { + case OK: + break; + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + } + } + } catch (SpannerException e) { + return CallbackResponse.DONE; + } + })); + } + })); + assertEquals(ErrorCode.FAILED_PRECONDITION, outerException.getErrorCode()); + assertThat(outerException.getMessage()) + .contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG); + assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0); assertThat(countRequests(ExecuteSqlRequest.class)).isEqualTo(1); assertThat(countRequests(CommitRequest.class)).isEqualTo(0); @@ -1492,17 +1469,18 @@ public void testUpdateAsyncWithInlineBeginDidNotReturnTransaction() { // This will cause the first statement that requests a transaction to not return a transaction // id. mockSpanner.ignoreNextInlineBeginRequest(); - try { - client - .readWriteTransaction() - .run( - transaction -> - SpannerApiFutures.get(transaction.executeUpdateAsync(UPDATE_STATEMENT))); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.FAILED_PRECONDITION); - assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run( + transaction -> + SpannerApiFutures.get( + transaction.executeUpdateAsync(UPDATE_STATEMENT)))); + assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); + assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG); assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0); assertThat(countRequests(ExecuteSqlRequest.class)).isEqualTo(1); assertThat(countRequests(CommitRequest.class)).isEqualTo(0); @@ -1514,18 +1492,19 @@ public void testBatchUpdateAsyncWithInlineBeginDidNotReturnTransaction() { // This will cause the first statement that requests a transaction to not return a transaction // id. mockSpanner.ignoreNextInlineBeginRequest(); - try { - client - .readWriteTransaction() - .run( - transaction -> - SpannerApiFutures.get( - transaction.batchUpdateAsync(Collections.singletonList(UPDATE_STATEMENT)))); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.FAILED_PRECONDITION); - assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run( + transaction -> + SpannerApiFutures.get( + transaction.batchUpdateAsync( + Collections.singletonList(UPDATE_STATEMENT))))); + assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); + assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG); assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0); assertThat(countRequests(ExecuteBatchDmlRequest.class)).isEqualTo(1); assertThat(countRequests(CommitRequest.class)).isEqualTo(0); @@ -1591,12 +1570,14 @@ public void testInlinedBeginTx_withStickyCancelledOnFirstStatement() { spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); // The CANCELLED error is thrown both on the first and second attempt. The second attempt will // not be retried, as it did not include a BeginTransaction option. - try { - client.readWriteTransaction().run(transaction -> transaction.executeUpdate(statement)); - fail("missing expected exception"); - } catch (SpannerException e) { - assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run(transaction -> transaction.executeUpdate(statement))); + assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); assertEquals(1, countRequests(BeginTransactionRequest.class)); // The update statement will be executed 2 times: assertEquals(2, countRequests(ExecuteSqlRequest.class)); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceConfigIdTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceConfigIdTest.java index 4110cbe6762..3f5114aea15 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceConfigIdTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceConfigIdTest.java @@ -18,7 +18,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import org.junit.Test; import org.junit.runner.RunWith; @@ -42,11 +42,8 @@ public void basic() { @Test public void badName() { - try { - InstanceConfigId.of("bad name"); - fail("Expected exception"); - } catch (IllegalArgumentException e) { - assertNotNull(e.getMessage()); - } + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> InstanceConfigId.of("bad name")); + assertNotNull(e.getMessage()); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceIdTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceIdTest.java index 2e921257f9b..01a609fb10f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceIdTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/InstanceIdTest.java @@ -18,8 +18,8 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; -import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -42,11 +42,8 @@ public void basic() { @Test public void badName() { - try { - InstanceId.of("bad name"); - Assert.fail("Expected exception"); - } catch (IllegalArgumentException e) { - assertNotNull(e.getMessage()); - } + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> InstanceId.of("bad name")); + assertNotNull(e.getMessage()); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/KeyRangeTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/KeyRangeTest.java index c89d08ef261..f11bb629520 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/KeyRangeTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/KeyRangeTest.java @@ -20,7 +20,7 @@ import static com.google.cloud.spanner.KeyRange.Endpoint.OPEN; import static com.google.common.testing.SerializableTester.reserializeAndAssert; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import com.google.common.testing.EqualsTester; import org.junit.Test; @@ -102,22 +102,18 @@ public void toBuilder() { @Test public void builderRequiresStart() { - try { - KeyRange.newBuilder().setEnd(Key.of("z")).build(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("start(Key)"); - } + IllegalStateException e = + assertThrows( + IllegalStateException.class, () -> KeyRange.newBuilder().setEnd(Key.of("z")).build()); + assertThat(e.getMessage()).contains("start(Key)"); } @Test public void builderRequiresEnd() { - try { - KeyRange.newBuilder().setStart(Key.of("a")).build(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("end(Key)"); - } + IllegalStateException e = + assertThrows( + IllegalStateException.class, () -> KeyRange.newBuilder().setStart(Key.of("a")).build()); + assertThat(e.getMessage()).contains("end(Key)"); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/LazySpannerInitializerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/LazySpannerInitializerTest.java index d9de9f1bab7..aa4879875e3 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/LazySpannerInitializerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/LazySpannerInitializerTest.java @@ -17,7 +17,7 @@ package com.google.cloud.spanner; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.mock; import com.google.common.util.concurrent.Futures; @@ -62,20 +62,8 @@ public Spanner initialize() throws IOException { throw new IOException("Could not find credentials file"); } }; - Throwable t1 = null; - try { - initializer.get(); - fail("Missing expected exception"); - } catch (Throwable t) { - t1 = t; - } - Throwable t2 = null; - try { - initializer.get(); - fail("Missing expected exception"); - } catch (Throwable t) { - t2 = t; - } + Throwable t1 = assertThrows(Throwable.class, () -> initializer.get()); + Throwable t2 = assertThrows(Throwable.class, () -> initializer.get()); assertThat(t1).isSameInstanceAs(t2); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MutationTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MutationTest.java index 16a0f87357e..53586641d4d 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MutationTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MutationTest.java @@ -18,7 +18,7 @@ import static com.google.common.testing.SerializableTester.reserializeAndAssert; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import com.google.cloud.ByteArray; import com.google.cloud.Date; @@ -121,22 +121,20 @@ public void replace() { @Test public void duplicateColumn() { - try { - Mutation.newInsertBuilder("T1").set("C1").to(true).set("C1").to(false).build(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("Duplicate column"); - } + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> Mutation.newInsertBuilder("T1").set("C1").to(true).set("C1").to(false).build()); + assertThat(e.getMessage()).contains("Duplicate column"); } @Test public void duplicateColumnCaseInsensitive() { - try { - Mutation.newInsertBuilder("T1").set("C1").to(true).set("c1").to(false).build(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("Duplicate column"); - } + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> Mutation.newInsertBuilder("T1").set("C1").to(true).set("c1").to(false).build()); + assertThat(e.getMessage()).contains("Duplicate column"); } @Test @@ -153,36 +151,24 @@ public void asMap() { public void unfinishedBindingV1() { Mutation.WriteBuilder b = Mutation.newInsertBuilder("T1"); b.set("C1"); - try { - b.build(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("Incomplete binding for column C1"); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> b.build()); + assertThat(e.getMessage()).contains("Incomplete binding for column C1"); } @Test public void unfinishedBindingV2() { Mutation.WriteBuilder b = Mutation.newInsertBuilder("T1"); b.set("C1"); - try { - b.set("C2"); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("Incomplete binding for column C1"); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> b.set("C2")); + assertThat(e.getMessage()).contains("Incomplete binding for column C1"); } @Test public void notInBinding() { ValueBinder binder = Mutation.newInsertBuilder("T1").set("C1"); binder.to(1234); - try { - binder.to(5678); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("No binding currently active"); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> binder.to(5678)); + assertThat(e.getMessage()).contains("No binding currently active"); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OperationTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OperationTest.java index 29e1ca81430..20fa72252f5 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OperationTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OperationTest.java @@ -18,7 +18,8 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.longrunning.Operation.newBuilder; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @@ -87,12 +88,8 @@ public void failedOperation() { assertThat(op.isDone()).isTrue(); assertThat(op.isSuccessful()).isFalse(); assertThat(op.getMetadata()).isNull(); - try { - op.getResult(); - fail("Expected exception"); - } catch (SpannerException ex) { - assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); - } + SpannerException e = assertThrows(SpannerException.class, () -> op.getResult()); + assertEquals(ErrorCode.NOT_FOUND, e.getErrorCode()); } @Test @@ -179,13 +176,13 @@ public void waitForTimeout() { Operation op = Operation.create(rpc, proto, new ParserImpl(), clock); when(rpc.getOperation("op1")).thenReturn(proto); when(clock.nanoTime()).thenReturn(0L, 50_000_000L, 100_000_000L, 150_000_000L); - try { - op.waitFor( - RetryOption.totalTimeout(Duration.ofMillis(100L)), - RetryOption.initialRetryDelay(Duration.ZERO)); - fail("Expected exception"); - } catch (SpannerException ex) { - assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.DEADLINE_EXCEEDED); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + op.waitFor( + RetryOption.totalTimeout(Duration.ofMillis(100L)), + RetryOption.initialRetryDelay(Duration.ZERO))); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OptionsTest.java index c57036adac4..04543d23247 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OptionsTest.java @@ -20,8 +20,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import com.google.cloud.spanner.Options.RpcPriority; import com.google.spanner.v1.RequestOptions.Priority; @@ -35,42 +35,30 @@ public class OptionsTest { @Test public void negativeLimitsNotAllowed() { - try { - Options.limit(-1); - fail("Expected exception"); - } catch (IllegalArgumentException ex) { - assertNotNull(ex.getMessage()); - } + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> Options.limit(-1)); + assertNotNull(e.getMessage()); } @Test public void zeroLimitNotAllowed() { - try { - Options.limit(0); - fail("Expected exception"); - } catch (IllegalArgumentException ex) { - assertNotNull(ex.getMessage()); - } + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> Options.limit(0)); + assertNotNull(e.getMessage()); } @Test public void negativePrefetchChunksNotAllowed() { - try { - Options.prefetchChunks(-1); - fail("Expected exception"); - } catch (IllegalArgumentException ex) { - assertNotNull(ex.getMessage()); - } + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> Options.prefetchChunks(-1)); + assertNotNull(e.getMessage()); } @Test public void zeroPrefetchChunksNotAllowed() { - try { - Options.prefetchChunks(0); - fail("Expected exception"); - } catch (IllegalArgumentException ex) { - assertNotNull(ex.getMessage()); - } + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> Options.prefetchChunks(0)); + assertNotNull(e.getMessage()); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/PartitionOptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/PartitionOptionsTest.java index e8c8dd001f0..1ea0387417d 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/PartitionOptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/PartitionOptionsTest.java @@ -19,7 +19,7 @@ import static com.google.common.testing.SerializableTester.reserializeAndAssert; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import com.google.common.testing.EqualsTester; import org.junit.Test; @@ -85,21 +85,19 @@ public void equalAndHashCode() { @Test public void invalidDesiredBytesPerBatch() { - try { - PartitionOptions.newBuilder().setPartitionSizeBytes(-1).build(); - fail("Expected exception"); - } catch (IllegalArgumentException ex) { - assertNotNull(ex.getMessage()); - } + IllegalArgumentException e = + assertThrows( + IllegalArgumentException.class, + () -> PartitionOptions.newBuilder().setPartitionSizeBytes(-1).build()); + assertNotNull(e.getMessage()); } @Test public void invalidMaxPartitionCount() { - try { - PartitionOptions.newBuilder().setMaxPartitions(-1).build(); - fail("Expected exception"); - } catch (IllegalArgumentException ex) { - assertNotNull(ex.getMessage()); - } + IllegalArgumentException e = + assertThrows( + IllegalArgumentException.class, + () -> PartitionOptions.newBuilder().setMaxPartitions(-1).build()); + assertNotNull(e.getMessage()); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/PartitionedDmlTransactionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/PartitionedDmlTransactionTest.java index b192ef77b50..badfaac640c 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/PartitionedDmlTransactionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/PartitionedDmlTransactionTest.java @@ -18,7 +18,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyMap; import static org.mockito.Mockito.mock; @@ -226,16 +226,15 @@ public void testExecuteStreamingPartitionedUpdateUnavailableAndThenDeadlineExcee .thenReturn(stream1); when(ticker.read()).thenReturn(0L, 1L, TimeUnit.NANOSECONDS.convert(10L, TimeUnit.MINUTES)); - try { - tx.executeStreamingPartitionedUpdate(Statement.of(sql), Duration.ofMinutes(10)); - fail("missing expected DEADLINE_EXCEEDED exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.DEADLINE_EXCEEDED); - verify(rpc).beginTransaction(any(BeginTransactionRequest.class), anyMap()); - verify(rpc) - .executeStreamingPartitionedDml( - Mockito.eq(executeRequestWithoutResumeToken), anyMap(), any(Duration.class)); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> tx.executeStreamingPartitionedUpdate(Statement.of(sql), Duration.ofMinutes(10))); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); + verify(rpc).beginTransaction(any(BeginTransactionRequest.class), anyMap()); + verify(rpc) + .executeStreamingPartitionedDml( + Mockito.eq(executeRequestWithoutResumeToken), anyMap(), any(Duration.class)); } @Test @@ -255,16 +254,15 @@ public void testExecuteStreamingPartitionedUpdateAbortedAndThenDeadlineExceeded( .thenReturn(stream1); when(ticker.read()).thenReturn(0L, 1L, TimeUnit.NANOSECONDS.convert(10L, TimeUnit.MINUTES)); - try { - tx.executeStreamingPartitionedUpdate(Statement.of(sql), Duration.ofMinutes(10)); - fail("missing expected DEADLINE_EXCEEDED exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.DEADLINE_EXCEEDED); - verify(rpc, times(2)).beginTransaction(any(BeginTransactionRequest.class), anyMap()); - verify(rpc) - .executeStreamingPartitionedDml( - Mockito.eq(executeRequestWithoutResumeToken), anyMap(), any(Duration.class)); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> tx.executeStreamingPartitionedUpdate(Statement.of(sql), Duration.ofMinutes(10))); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); + verify(rpc, times(2)).beginTransaction(any(BeginTransactionRequest.class), anyMap()); + verify(rpc) + .executeStreamingPartitionedDml( + Mockito.eq(executeRequestWithoutResumeToken), anyMap(), any(Duration.class)); } @Test @@ -293,19 +291,18 @@ public Long answer(InvocationOnMock invocation) { } }); - try { - tx.executeStreamingPartitionedUpdate(Statement.of(sql), Duration.ofMinutes(10)); - fail("missing expected DEADLINE_EXCEEDED exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.DEADLINE_EXCEEDED); - // It should start a transaction exactly 10 times (10 ticks == 10 minutes). - verify(rpc, times(10)).beginTransaction(any(BeginTransactionRequest.class), anyMap()); - // The last transaction should timeout before it starts the actual statement execution, which - // means that the execute method is only executed 9 times. - verify(rpc, times(9)) - .executeStreamingPartitionedDml( - Mockito.eq(executeRequestWithoutResumeToken), anyMap(), any(Duration.class)); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> tx.executeStreamingPartitionedUpdate(Statement.of(sql), Duration.ofMinutes(10))); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); + // It should start a transaction exactly 10 times (10 ticks == 10 minutes). + verify(rpc, times(10)).beginTransaction(any(BeginTransactionRequest.class), anyMap()); + // The last transaction should timeout before it starts the actual statement execution, which + // means that the execute method is only executed 9 times. + verify(rpc, times(9)) + .executeStreamingPartitionedDml( + Mockito.eq(executeRequestWithoutResumeToken), anyMap(), any(Duration.class)); } @Test @@ -363,17 +360,16 @@ public void testExecuteStreamingPartitionedUpdateGenericInternalException() { Mockito.eq(executeRequestWithoutResumeToken), anyMap(), any(Duration.class))) .thenReturn(stream1); - try { - PartitionedDmlTransaction tx = new PartitionedDmlTransaction(session, rpc, ticker); - tx.executeStreamingPartitionedUpdate(Statement.of(sql), Duration.ofMinutes(10)); - fail("missing expected INTERNAL exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); - verify(rpc).beginTransaction(any(BeginTransactionRequest.class), anyMap()); - verify(rpc) - .executeStreamingPartitionedDml( - Mockito.eq(executeRequestWithoutResumeToken), anyMap(), any(Duration.class)); - } + PartitionedDmlTransaction tx = new PartitionedDmlTransaction(session, rpc, ticker); + SpannerException e = + assertThrows( + SpannerException.class, + () -> tx.executeStreamingPartitionedUpdate(Statement.of(sql), Duration.ofMinutes(10))); + assertEquals(ErrorCode.INTERNAL, e.getErrorCode()); + verify(rpc).beginTransaction(any(BeginTransactionRequest.class), anyMap()); + verify(rpc) + .executeStreamingPartitionedDml( + Mockito.eq(executeRequestWithoutResumeToken), anyMap(), any(Duration.class)); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadAsyncTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadAsyncTest.java index 77a2b2fc549..bb8d1309142 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadAsyncTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadAsyncTest.java @@ -17,7 +17,9 @@ package com.google.cloud.spanner; import static com.google.cloud.spanner.MockSpannerTestUtil.*; +import static com.google.cloud.spanner.SpannerApiFutures.get; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; import com.google.api.core.ApiFuture; @@ -43,7 +45,6 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledThreadPoolExecutor; @@ -130,15 +131,9 @@ public void readAsyncPropagatesError() throws Exception { ErrorCode.CANCELLED, "Don't want the data"); }); } - try { - result.get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - SpannerException se = (SpannerException) e.getCause(); - assertThat(se.getErrorCode()).isEqualTo(ErrorCode.CANCELLED); - assertThat(se.getMessage()).contains("Don't want the data"); - } + SpannerException e = assertThrows(SpannerException.class, () -> get(result)); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.CANCELLED); + assertThat(e.getMessage()).contains("Don't want the data"); } @Test @@ -198,12 +193,7 @@ public void invalidDatabase() throws Exception { invalidClient .singleUse(TimestampBound.strong()) .readRowAsync(READ_TABLE_NAME, Key.of("k99"), READ_COLUMN_NAMES); - try { - row.get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(DatabaseNotFoundException.class); - } + assertThrows(DatabaseNotFoundException.class, () -> get(row)); } @Test @@ -217,15 +207,9 @@ public void tableNotFound() throws Exception { client .singleUse(TimestampBound.strong()) .readRowAsync("BadTableName", Key.of("k1"), READ_COLUMN_NAMES); - try { - row.get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - SpannerException se = (SpannerException) e.getCause(); - assertThat(se.getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); - assertThat(se.getMessage()).contains("BadTableName"); - } + SpannerException e = assertThrows(SpannerException.class, () -> get(row)); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); + assertThat(e.getMessage()).contains("BadTableName"); } /** @@ -448,14 +432,8 @@ public void cancel() throws Exception { rs.cancel(); } cancelled.countDown(); - try { - res.get(); - fail("missing expected exception"); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SpannerException.class); - SpannerException se = (SpannerException) e.getCause(); - assertThat(se.getErrorCode()).isEqualTo(ErrorCode.CANCELLED); - assertThat(values).containsExactly("v1"); - } + SpannerException e = assertThrows(SpannerException.class, () -> get(res)); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.CANCELLED); + assertThat(values).containsExactly("v1"); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadWriteTransactionWithInlineBeginTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadWriteTransactionWithInlineBeginTest.java index 28f6566dab8..95631572f4e 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadWriteTransactionWithInlineBeginTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ReadWriteTransactionWithInlineBeginTest.java @@ -17,7 +17,8 @@ package com.google.cloud.spanner; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import com.google.api.gax.grpc.testing.LocalChannelProvider; import com.google.cloud.NoCredentials; @@ -291,51 +292,51 @@ public void concurrentQueries() { @Test public void failedUpdate() { - try { - client - .readWriteTransaction() - .run(transaction -> transaction.executeUpdate(INVALID_UPDATE_STATEMENT)); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run(transaction -> transaction.executeUpdate(INVALID_UPDATE_STATEMENT))); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0); assertThat(countTransactionsStarted()).isEqualTo(1); } @Test public void failedBatchUpdate() { - try { - client - .readWriteTransaction() - .run( - transaction -> - transaction.batchUpdate( - Arrays.asList(INVALID_UPDATE_STATEMENT, UPDATE_STATEMENT))); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run( + transaction -> + transaction.batchUpdate( + Arrays.asList(INVALID_UPDATE_STATEMENT, UPDATE_STATEMENT)))); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0); assertThat(countTransactionsStarted()).isEqualTo(1); } @Test public void failedQuery() { - try { - client - .readWriteTransaction() - .run( - transaction -> { - try (ResultSet rs = transaction.executeQuery(INVALID_SELECT_STATEMENT)) { - rs.next(); - } - return null; - }); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run( + transaction -> { + try (ResultSet rs = transaction.executeQuery(INVALID_SELECT_STATEMENT)) { + rs.next(); + } + return null; + })); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0); assertThat(countTransactionsStarted()).isEqualTo(1); } @@ -347,16 +348,15 @@ public void failedUpdateAndThenUpdate() { .readWriteTransaction() .run( transaction -> { - try { - // This update statement carries the BeginTransaction, but fails. This will - // cause the entire transaction to be retried with an explicit - // BeginTransaction RPC to ensure all statements in the transaction are - // actually executed against the same transaction. - transaction.executeUpdate(INVALID_UPDATE_STATEMENT); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - } + // This update statement carries the BeginTransaction, but fails. This will + // cause the entire transaction to be retried with an explicit + // BeginTransaction RPC to ensure all statements in the transaction are + // actually executed against the same transaction. + SpannerException e = + assertThrows( + SpannerException.class, + () -> transaction.executeUpdate(INVALID_UPDATE_STATEMENT)); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); return transaction.executeUpdate(UPDATE_STATEMENT); }); assertThat(updateCount).isEqualTo(1L); @@ -371,17 +371,17 @@ public void failedBatchUpdateAndThenUpdate() { .readWriteTransaction() .run( transaction -> { - try { - // This update statement carries the BeginTransaction, but fails. This will - // cause the entire transaction to be retried with an explicit - // BeginTransaction RPC to ensure all statements in the transaction are - // actually executed against the same transaction. - transaction.batchUpdate( - Arrays.asList(INVALID_UPDATE_STATEMENT, UPDATE_STATEMENT)); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - } + // This update statement carries the BeginTransaction, but fails. This will + // cause the entire transaction to be retried with an explicit + // BeginTransaction RPC to ensure all statements in the transaction are + // actually executed against the same transaction. + SpannerException e = + assertThrows( + SpannerException.class, + () -> + transaction.batchUpdate( + Arrays.asList(INVALID_UPDATE_STATEMENT, UPDATE_STATEMENT))); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); return transaction.executeUpdate(UPDATE_STATEMENT); }); assertThat(updateCount).isEqualTo(1L); @@ -399,10 +399,8 @@ public void failedQueryAndThenUpdate() { // This query carries the BeginTransaction, but fails. The BeginTransaction will // then be carried by the subsequent statement. try (ResultSet rs = transaction.executeQuery(INVALID_SELECT_STATEMENT)) { - rs.next(); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); } return transaction.executeUpdate(UPDATE_STATEMENT); }); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResultSetsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResultSetsTest.java index dcf2f895553..7f36d8bad76 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResultSetsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResultSetsTest.java @@ -18,7 +18,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; @@ -174,12 +174,8 @@ public void resultSetIteration() { .build(); ResultSet rs = ResultSets.forRows(type, Arrays.asList(struct1, struct2)); - try { - rs.getType(); - fail("Exception expected"); - } catch (IllegalStateException e) { - assertThat(e.getMessage()).contains("Must be preceded by a next() call"); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> rs.getType()); + assertThat(e.getMessage()).contains("Must be preceded by a next() call"); assertThat(rs.next()).isTrue(); assertThat(rs.getType()).isEqualTo(type); @@ -279,13 +275,10 @@ public void resultSetIteration() { assertThat(rs.isNull(2)).isTrue(); assertThat(rs.next()).isFalse(); - try { - rs.getStats(); - fail("Exception expected"); - } catch (UnsupportedOperationException e) { - assertThat(e.getMessage()) - .contains("ResultSetStats are available only for results returned from analyzeQuery"); - } + UnsupportedOperationException unsupported = + assertThrows(UnsupportedOperationException.class, () -> rs.getStats()); + assertThat(unsupported.getMessage()) + .contains("ResultSetStats are available only for results returned from analyzeQuery"); } @Test @@ -298,13 +291,12 @@ public void resultSetIterationWithStructColumns() { Struct value1 = Struct.newBuilder().set("g1").to("abc").build(); Struct struct1 = Struct.newBuilder().set("f1").to(value1).set("f2").to((Long) null).build(); - try { - ResultSets.forRows(type, Collections.singletonList(struct1)); - fail("Expected exception"); - } catch (UnsupportedOperationException ex) { - assertThat(ex.getMessage()) - .contains("STRUCT-typed columns are not supported inside ResultSets."); - } + UnsupportedOperationException e = + assertThrows( + UnsupportedOperationException.class, + () -> ResultSets.forRows(type, Collections.singletonList(struct1))); + assertThat(e.getMessage()) + .contains("STRUCT-typed columns are not supported inside ResultSets."); } @Test @@ -377,12 +369,9 @@ public void closeResultSet() { Type.struct(Type.StructField.of("f1", Type.string())), Collections.singletonList(Struct.newBuilder().set("f1").to("x").build())); rs.close(); - try { - rs.getCurrentRowAsStruct(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertNotNull(ex.getMessage()); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> rs.getCurrentRowAsStruct()); + assertNotNull(e.getMessage()); } @Test @@ -391,12 +380,9 @@ public void exceptionIfNextIsNotCalled() { ResultSets.forRows( Type.struct(Type.StructField.of("f1", Type.string())), Collections.singletonList(Struct.newBuilder().set("f1").to("x").build())); - try { - rs.getCurrentRowAsStruct(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertNotNull(ex.getMessage()); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> rs.getCurrentRowAsStruct()); + assertNotNull(e.getMessage()); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResumableStreamIteratorTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResumableStreamIteratorTest.java index 4f38aee940d..8f4f0803bdf 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResumableStreamIteratorTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ResumableStreamIteratorTest.java @@ -17,7 +17,8 @@ package com.google.cloud.spanner; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -270,12 +271,8 @@ public void nonRetryableError() { Iterator strings = stringIterator(resumableStreamIterator); assertThat(strings.next()).isEqualTo("a"); assertThat(strings.next()).isEqualTo("b"); - try { - assertThat(strings.next()).isNotEqualTo("X"); - fail("Expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.FAILED_PRECONDITION); - } + SpannerException e = assertThrows(SpannerException.class, () -> strings.next()); + assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); } @Test @@ -378,12 +375,8 @@ public void bufferLimitMissingTokensUnsafeToRetry() { .thenThrow(new RetryableException(ErrorCode.UNAVAILABLE, "failed by test")); assertThat(consumeAtMost(3, resumableStreamIterator)).containsExactly("a", "b", "c").inOrder(); - try { - resumableStreamIterator.next(); - fail("Expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.UNAVAILABLE); - } + SpannerException e = assertThrows(SpannerException.class, () -> resumableStreamIterator.next()); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.UNAVAILABLE); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionImplTest.java index c97c2c2721f..0ba89f54a68 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionImplTest.java @@ -17,7 +17,9 @@ package com.google.cloud.spanner; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -128,48 +130,43 @@ private void doNestedRwTransaction() { @Test public void nestedReadWriteTxnThrows() { - try { - doNestedRwTransaction(); - fail("Expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); - assertThat(e.getMessage()).contains("not supported"); - } + SpannerException e = assertThrows(SpannerException.class, () -> doNestedRwTransaction()); + assertEquals(ErrorCode.INTERNAL, e.getErrorCode()); + assertThat(e.getMessage()).contains("not supported"); } @Test public void nestedReadOnlyTxnThrows() { - try { - session - .readWriteTransaction() - .run( - transaction -> { - session.readOnlyTransaction().getReadTimestamp(); - - return null; - }); - fail("Expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); - assertThat(e.getMessage()).contains("not supported"); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + session + .readWriteTransaction() + .run( + transaction -> { + session.readOnlyTransaction().getReadTimestamp(); + return null; + })); + assertEquals(ErrorCode.INTERNAL, e.getErrorCode()); + assertThat(e.getMessage()).contains("not supported"); } @Test public void nestedSingleUseReadTxnThrows() { - try { - session - .readWriteTransaction() - .run( - transaction -> { - session.singleUseReadOnlyTransaction(); - return null; - }); - fail("Expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); - assertThat(e.getMessage()).contains("not supported"); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + session + .readWriteTransaction() + .run( + transaction -> { + session.singleUseReadOnlyTransaction(); + return null; + })); + assertEquals(ErrorCode.INTERNAL, e.getErrorCode()); + assertThat(e.getMessage()).contains("not supported"); } @Test @@ -252,60 +249,55 @@ private static long utcTimeSeconds(int year, int month, int day, int hour, int m public void newSingleUseContextClosesOldSingleUseContext() { ReadContext ctx = session.singleUse(TimestampBound.strong()); session.singleUse(TimestampBound.strong()); - try { - ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("invalidated"); - } + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> ctx.read("Dummy", KeySet.all(), Collections.singletonList("C"))); + assertThat(e.getMessage()).contains("invalidated"); } @Test public void newSingleUseContextClosesOldSingleUseReadOnlyTransactionContext() { ReadContext ctx = session.singleUseReadOnlyTransaction(TimestampBound.strong()); session.singleUse(TimestampBound.strong()); - try { - ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("invalidated"); - } + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> ctx.read("Dummy", KeySet.all(), Collections.singletonList("C"))); + assertThat(e.getMessage()).contains("invalidated"); } @Test public void newSingleUseContextClosesOldMultiUseReadOnlyTransactionContext() { ReadContext ctx = session.singleUseReadOnlyTransaction(TimestampBound.strong()); session.singleUse(TimestampBound.strong()); - try { - ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("invalidated"); - } + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> ctx.read("Dummy", KeySet.all(), Collections.singletonList("C"))); + assertThat(e.getMessage()).contains("invalidated"); } @Test public void newSingleUseReadOnlyTransactionContextClosesOldSingleUseContext() { ReadContext ctx = session.singleUse(TimestampBound.strong()); session.singleUseReadOnlyTransaction(TimestampBound.strong()); - try { - ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("invalidated"); - } + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> ctx.read("Dummy", KeySet.all(), Collections.singletonList("C"))); + assertThat(e.getMessage()).contains("invalidated"); } @Test public void newMultiUseReadOnlyTransactionContextClosesOldSingleUseContext() { ReadContext ctx = session.singleUse(TimestampBound.strong()); session.readOnlyTransaction(TimestampBound.strong()); - try { - ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("invalidated"); - } + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> ctx.read("Dummy", KeySet.all(), Collections.singletonList("C"))); + assertThat(e.getMessage()).contains("invalidated"); } @Test @@ -318,12 +310,11 @@ public void writeClosesOldSingleUseContext() throws ParseException { .setCommitTimestamp(Timestamps.parse("2015-10-01T10:54:20.021Z")) .build()); session.writeAtLeastOnce(Collections.emptyList()); - try { - ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("invalidated"); - } + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> ctx.read("Dummy", KeySet.all(), Collections.singletonList("C"))); + assertThat(e.getMessage()).contains("invalidated"); } @Test @@ -332,12 +323,11 @@ public void transactionClosesOldSingleUseContext() { // Note that we don't even run the transaction - just preparing the runner is sufficient. session.readWriteTransaction(); - try { - ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("invalidated"); - } + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> ctx.read("Dummy", KeySet.all(), Collections.singletonList("C"))); + assertThat(e.getMessage()).contains("invalidated"); } @Test @@ -345,16 +335,16 @@ public void singleUseContextClosesTransaction() { TransactionRunner runner = session.readWriteTransaction(); session.singleUse(TimestampBound.strong()); - try { - runner.run( - transaction -> { - fail("Unexpected call to transaction body"); - return null; - }); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("invalidated"); - } + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> + runner.run( + transaction -> { + fail("Unexpected call to transaction body"); + return null; + })); + assertThat(e.getMessage()).contains("invalidated"); } @Test @@ -364,12 +354,11 @@ public void prepareClosesOldSingleUseContext() { Mockito.when(rpc.beginTransaction(Mockito.any(), Mockito.eq(options))) .thenReturn(Transaction.newBuilder().setId(ByteString.copyFromUtf8("t1")).build()); session.prepareReadWriteTransaction(); - try { - ctx.read("Dummy", KeySet.all(), Collections.singletonList("C")); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("invalidated"); - } + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> ctx.read("Dummy", KeySet.all(), Collections.singletonList("C"))); + assertThat(e.getMessage()).contains("invalidated"); } private static ResultSetMetadata newMetadata(Type type) { @@ -391,12 +380,9 @@ public void singleUseReadOnlyTransactionDoesntReturnTransactionMetadata() { // be better for the read to fail with an INTERNAL error, but we can't do that until txn // metadata is returned for failed reads (e.g., table-not-found) as well as successful ones. // TODO(user): Fix this. - try { - txn.getReadTimestamp(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertNotNull(ex.getMessage()); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> txn.getReadTimestamp()); + assertNotNull(e.getMessage()); } @Test @@ -411,12 +397,11 @@ public void singleUseReadOnlyTransactionReturnsEmptyTransactionMetadata() { mockRead(resultSet); ReadOnlyTransaction txn = session.singleUseReadOnlyTransaction(TimestampBound.strong()); - try { - txn.readRow("Dummy", Key.of(), Collections.singletonList("C")); - fail("Expected exception"); - } catch (SpannerException ex) { - assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> txn.readRow("Dummy", Key.of(), Collections.singletonList("C"))); + assertEquals(ErrorCode.INTERNAL, e.getErrorCode()); } private static class NoOpStreamingCall implements SpannerRpc.StreamingCall { @@ -450,12 +435,11 @@ public void multiUseReadOnlyTransactionReturnsEmptyTransactionMetadata() { mockRead(resultSet); ReadOnlyTransaction txn = session.readOnlyTransaction(TimestampBound.strong()); - try { - txn.readRow("Dummy", Key.of(), Collections.singletonList("C")); - fail("Expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> txn.readRow("Dummy", Key.of(), Collections.singletonList("C"))); + assertEquals(ErrorCode.INTERNAL, e.getErrorCode()); } @Test @@ -469,12 +453,11 @@ public void multiUseReadOnlyTransactionReturnsMissingTimestamp() { mockRead(resultSet); ReadOnlyTransaction txn = session.readOnlyTransaction(TimestampBound.strong()); - try { - txn.readRow("Dummy", Key.of(), Collections.singletonList("C")); - fail("Expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> txn.readRow("Dummy", Key.of(), Collections.singletonList("C"))); + assertEquals(ErrorCode.INTERNAL, e.getErrorCode()); } @Test @@ -489,11 +472,10 @@ public void multiUseReadOnlyTransactionReturnsMissingTransactionId() throws Pars mockRead(resultSet); ReadOnlyTransaction txn = session.readOnlyTransaction(TimestampBound.strong()); - try { - txn.readRow("Dummy", Key.of(), Collections.singletonList("C")); - fail("Expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> txn.readRow("Dummy", Key.of(), Collections.singletonList("C"))); + assertEquals(ErrorCode.INTERNAL, e.getErrorCode()); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolLeakTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolLeakTest.java index ab91a2c56ae..c8f648a1dc4 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolLeakTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolLeakTest.java @@ -19,7 +19,8 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import com.google.api.gax.grpc.testing.LocalChannelProvider; import com.google.cloud.NoCredentials; @@ -113,16 +114,13 @@ public void testReadWriteTransactionExceptionOnBegin() { private void readWriteTransactionTest( Runnable setup, int expectedNumberOfSessionsAfterExecution) { - assertThat(pool.getNumberOfSessionsInPool(), is(equalTo(0))); + assertEquals(0, pool.getNumberOfSessionsInPool()); setup.run(); - try { - client.readWriteTransaction().run(transaction -> null); - fail("missing FAILED_PRECONDITION exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode(), is(equalTo(ErrorCode.FAILED_PRECONDITION))); - } - assertThat( - pool.getNumberOfSessionsInPool(), is(equalTo(expectedNumberOfSessionsAfterExecution))); + SpannerException e = + assertThrows( + SpannerException.class, () -> client.readWriteTransaction().run(transaction -> null)); + assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); + assertEquals(expectedNumberOfSessionsAfterExecution, pool.getNumberOfSessionsInPool()); } @Test @@ -148,15 +146,12 @@ public void testTransactionManagerExceptionOnBegin() { } private void transactionManagerTest(Runnable setup, int expectedNumberOfSessionsAfterExecution) { - assertThat(pool.getNumberOfSessionsInPool(), is(equalTo(0))); + assertEquals(0, pool.getNumberOfSessionsInPool()); setup.run(); try (TransactionManager txManager = client.transactionManager()) { - txManager.begin(); - fail("missing FAILED_PRECONDITION exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode(), is(equalTo(ErrorCode.FAILED_PRECONDITION))); + SpannerException e = assertThrows(SpannerException.class, () -> txManager.begin()); + assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); } - assertThat( - pool.getNumberOfSessionsInPool(), is(equalTo(expectedNumberOfSessionsAfterExecution))); + assertEquals(expectedNumberOfSessionsAfterExecution, pool.getNumberOfSessionsInPool()); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java index 127d51f24d8..47ceb356193 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolTest.java @@ -23,7 +23,10 @@ import static com.google.cloud.spanner.MetricRegistryConstants.SPANNER_LABEL_KEYS; import static com.google.cloud.spanner.MetricRegistryConstants.SPANNER_LABEL_KEYS_WITH_TYPE; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; @@ -168,17 +171,13 @@ private void setupMockSessionCreation() { @Test public void testClosedPoolIncludesClosedException() { pool = createPool(); - assertThat(pool.isValid()).isTrue(); + assertTrue(pool.isValid()); closePoolWithStacktrace(); - try { - pool.getSession(); - fail("missing expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getCause()).isInstanceOf(ClosedException.class); - StringWriter sw = new StringWriter(); - e.getCause().printStackTrace(new PrintWriter(sw)); - assertThat(sw.toString()).contains("closePoolWithStacktrace"); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> pool.getSession()); + assertThat(e.getCause()).isInstanceOf(ClosedException.class); + StringWriter sw = new StringWriter(); + e.getCause().printStackTrace(new PrintWriter(sw)); + assertThat(sw.toString()).contains("closePoolWithStacktrace"); } private void closePoolWithStacktrace() { @@ -411,12 +410,8 @@ public void poolClosureFailsNewRequests() { // Suppress expected leakedSession warning. leakedSession.clearLeakedException(); pool.closeAsync(new SpannerImpl.ClosedException()); - try { - pool.getSession(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertNotNull(ex.getMessage()); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> pool.getSession()); + assertNotNull(e.getMessage()); } @Test @@ -452,12 +447,8 @@ public void creationExceptionPropagatesToReadSession() { .when(sessionClient) .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); pool = createPool(); - try { - pool.getSession().get(); - fail("Expected exception"); - } catch (SpannerException ex) { - assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.INTERNAL); - } + SpannerException e = assertThrows(SpannerException.class, () -> pool.getSession().get()); + assertEquals(ErrorCode.INTERNAL, e.getErrorCode()); } @Test @@ -482,12 +473,8 @@ public void failOnPoolExhaustion() { .asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class)); pool = createPool(); Session session1 = pool.getSession(); - try { - pool.getSession(); - fail("Expected exception"); - } catch (SpannerException ex) { - assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.RESOURCE_EXHAUSTED); - } + SpannerException e = assertThrows(SpannerException.class, () -> pool.getSession()); + assertEquals(ErrorCode.RESOURCE_EXHAUSTED, e.getErrorCode()); session1.close(); session1 = pool.getSession(); assertThat(session1).isNotNull(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpanTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpanTest.java index 7d8a2c1639b..1ba1e9c25ca 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpanTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpanTest.java @@ -17,7 +17,8 @@ package com.google.cloud.spanner; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import com.google.api.gax.grpc.testing.LocalChannelProvider; import com.google.api.gax.retrying.RetrySettings; @@ -203,13 +204,8 @@ public void tearDown() { public void singleUseNonRetryableErrorOnNext() { try (ResultSet rs = client.singleUse().executeQuery(SELECT1)) { mockSpanner.addException(FAILED_PRECONDITION); - while (rs.next()) { - // Just consume the result set. - fail("Expected exception"); - } - fail("Expected exception"); - } catch (SpannerException ex) { - assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.FAILED_PRECONDITION); + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); } } @@ -217,13 +213,8 @@ public void singleUseNonRetryableErrorOnNext() { public void singleUseExecuteStreamingSqlTimeout() { try (ResultSet rs = clientWithTimeout.singleUse().executeQuery(SELECT1)) { mockSpanner.setExecuteStreamingSqlExecutionTime(ONE_SECOND); - while (rs.next()) { - // Just consume the result set. - fail("Expected exception"); - } - fail("Expected exception"); - } catch (SpannerException ex) { - assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.DEADLINE_EXCEEDED); + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } @@ -263,11 +254,7 @@ public void multiUse() { @Test public void transactionRunner() { TransactionRunner runner = client.readWriteTransaction(); - runner.run( - transaction -> { - transaction.executeUpdate(UPDATE_STATEMENT); - return null; - }); + runner.run(transaction -> transaction.executeUpdate(UPDATE_STATEMENT)); Map spans = failOnOverkillTraceComponent.getSpans(); assertThat(spans).containsEntry("CloudSpanner.ReadWriteTransaction", true); assertThat(spans).containsEntry("CloudSpannerOperation.BatchCreateSessions", true); @@ -279,16 +266,11 @@ public void transactionRunner() { @Test public void transactionRunnerWithError() { TransactionRunner runner = client.readWriteTransaction(); - try { - runner.run( - transaction -> { - transaction.executeUpdate(INVALID_UPDATE_STATEMENT); - return null; - }); - fail("missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> runner.run(transaction -> transaction.executeUpdate(INVALID_UPDATE_STATEMENT))); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); Map spans = failOnOverkillTraceComponent.getSpans(); assertThat(spans.size()).isEqualTo(4); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerApiFuturesTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerApiFuturesTest.java index 33454da27a1..462464b2c38 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerApiFuturesTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerApiFuturesTest.java @@ -18,7 +18,8 @@ import static com.google.cloud.spanner.SpannerApiFutures.get; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; @@ -39,12 +40,7 @@ public void testGet() { @Test public void testGetNull() { - try { - get(null); - fail("Missing expected exception"); - } catch (NullPointerException e) { - // Ignore, this is the expected exception. - } + assertThrows(NullPointerException.class, () -> get(null)); } @Test @@ -58,26 +54,18 @@ public void testGetSpannerException() { ApiFutures.immediateFailedFuture( SpannerExceptionFactory.newSpannerException( ErrorCode.FAILED_PRECONDITION, "test exception")); - try { - get(fut); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.FAILED_PRECONDITION); - assertThat(e.getMessage()).contains("test exception"); - } + SpannerException e = assertThrows(SpannerException.class, () -> get(fut)); + assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); + assertThat(e.getMessage()).contains("test exception"); } @Test public void testGetOtherException() { ApiFuture fut = ApiFutures.immediateFailedFuture(new RuntimeException("test runtime exception")); - try { - get(fut); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.UNKNOWN); - assertThat(e.getMessage()).contains("test runtime exception"); - } + SpannerException e = assertThrows(SpannerException.class, () -> get(fut)); + assertEquals(ErrorCode.UNKNOWN, e.getErrorCode()); + assertThat(e.getMessage()).contains("test runtime exception"); } @Test @@ -88,14 +76,10 @@ public Void get() throws InterruptedException { throw new InterruptedException("test interrupted exception"); } }; - try { - get(fut); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.CANCELLED); - // The message of an interrupted exception is not included in the SpannerException. - assertThat(e.getMessage()).doesNotContain("test interrupted exception"); - } + SpannerException e = assertThrows(SpannerException.class, () -> get(fut)); + assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); + // The message of an interrupted exception is not included in the SpannerException. + assertThat(e.getMessage()).doesNotContain("test interrupted exception"); } @Test @@ -106,13 +90,9 @@ public Void get() { throw new CancellationException("test cancellation exception"); } }; - try { - get(fut); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.CANCELLED); - // The message of an cancellation exception is included in the SpannerException. - assertThat(e.getMessage()).contains("test cancellation exception"); - } + SpannerException e = assertThrows(SpannerException.class, () -> get(fut)); + assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); + // The message of an cancellation exception is included in the SpannerException. + assertThat(e.getMessage()).contains("test cancellation exception"); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerGaxRetryTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerGaxRetryTest.java index a227719e0b5..5dfde3503ac 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerGaxRetryTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerGaxRetryTest.java @@ -20,7 +20,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import com.google.api.gax.grpc.testing.LocalChannelProvider; import com.google.api.gax.retrying.RetrySettings; @@ -141,8 +141,8 @@ public void setUp() throws Exception { RetrySettings.newBuilder() .setInitialRetryDelay(Duration.ofMillis(1L)) .setMaxRetryDelay(Duration.ofMillis(1L)) - .setInitialRpcTimeout(Duration.ofMillis(75L)) - .setMaxRpcTimeout(Duration.ofMillis(75L)) + .setInitialRpcTimeout(Duration.ofMillis(175L)) + .setMaxRpcTimeout(Duration.ofMillis(175L)) .setMaxAttempts(3) .setTotalTimeout(Duration.ofMillis(200L)) .build(); @@ -209,11 +209,8 @@ private void warmUpSessionPool(DatabaseClient client) { public void singleUseTimeout() { mockSpanner.setBatchCreateSessionsExecutionTime(ONE_SECOND); try (ResultSet rs = clientWithTimeout.singleUse().executeQuery(SELECT1AND2)) { - while (rs.next()) { - fail("Expected exception"); - } - } catch (SpannerException ex) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, ex.getErrorCode()); + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } @@ -229,11 +226,8 @@ public void singleUseUnavailable() { public void singleUseNonRetryableError() { mockSpanner.addException(FAILED_PRECONDITION); try (ResultSet rs = client.singleUse().executeQuery(SELECT1AND2)) { - while (rs.next()) { - fail("Expected exception"); - } - } catch (SpannerException ex) { - assertEquals(ErrorCode.FAILED_PRECONDITION, ex.getErrorCode()); + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); } } @@ -241,11 +235,8 @@ public void singleUseNonRetryableError() { public void singleUseNonRetryableErrorOnNext() { try (ResultSet rs = client.singleUse().executeQuery(SELECT1AND2)) { mockSpanner.addException(FAILED_PRECONDITION); - while (rs.next()) { - fail("Expected exception"); - } - } catch (SpannerException ex) { - assertEquals(ErrorCode.FAILED_PRECONDITION, ex.getErrorCode()); + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); } } @@ -253,11 +244,8 @@ public void singleUseNonRetryableErrorOnNext() { public void singleUseInternal() { mockSpanner.addException(new IllegalArgumentException()); try (ResultSet rs = client.singleUse().executeQuery(SELECT1AND2)) { - while (rs.next()) { - fail("Expected exception"); - } - } catch (SpannerException ex) { - assertEquals(ErrorCode.INTERNAL, ex.getErrorCode()); + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + assertEquals(ErrorCode.INTERNAL, e.getErrorCode()); } } @@ -266,11 +254,8 @@ public void singleUseReadOnlyTransactionTimeout() { mockSpanner.setBatchCreateSessionsExecutionTime(ONE_SECOND); try (ResultSet rs = clientWithTimeout.singleUseReadOnlyTransaction().executeQuery(SELECT1AND2)) { - while (rs.next()) { - fail("Expected exception"); - } - } catch (SpannerException ex) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, ex.getErrorCode()); + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } @@ -286,11 +271,8 @@ public void singleUseReadOnlyTransactionUnavailable() { public void singleUseExecuteStreamingSqlTimeout() { try (ResultSet rs = clientWithTimeout.singleUse().executeQuery(SELECT1AND2)) { mockSpanner.setExecuteStreamingSqlExecutionTime(ONE_SECOND); - while (rs.next()) { - fail("Expected exception"); - } - } catch (SpannerException ex) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, ex.getErrorCode()); + SpannerException e = assertThrows(SpannerException.class, () -> rs.next()); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } @@ -305,13 +287,11 @@ public void singleUseExecuteStreamingSqlUnavailable() { @Test public void readWriteTransactionTimeout() { mockSpanner.setBeginTransactionExecutionTime(ONE_SECOND); - try { - TransactionRunner runner = clientWithTimeout.readWriteTransaction(); - runner.run(transaction -> null); - fail("Expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, ex.getErrorCode()); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> clientWithTimeout.readWriteTransaction().run(transaction -> null)); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } @Test @@ -376,24 +356,14 @@ public void readWriteTransactionUncheckedException() { }); } - @SuppressWarnings("resource") @Test public void transactionManagerTimeout() { mockSpanner.setExecuteSqlExecutionTime(ONE_SECOND); try (TransactionManager txManager = clientWithTimeout.transactionManager()) { TransactionContext tx = txManager.begin(); - while (true) { - try { - assertThat(tx.executeUpdate(UPDATE_STATEMENT), is(equalTo(UPDATE_COUNT))); - txManager.commit(); - break; - } catch (AbortedException e) { - tx = txManager.resetForRetry(); - } - } - fail("missing DEADLINE_EXCEEDED exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode(), is(equalTo(ErrorCode.DEADLINE_EXCEEDED))); + SpannerException e = + assertThrows(SpannerException.class, () -> tx.executeUpdate(UPDATE_STATEMENT)); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerImplTest.java index 2040f795366..c8a93d64eec 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerImplTest.java @@ -19,7 +19,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.when; import com.google.api.core.NanoClock; @@ -159,12 +159,9 @@ public void getDbclientAfterCloseThrows() { imp.close(); - try { - imp.getDatabaseClient(db); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage()).contains("Cloud Spanner client has been closed"); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> imp.getDatabaseClient(db)); + assertThat(e.getMessage()).contains("Cloud Spanner client has been closed"); } @Test @@ -263,15 +260,14 @@ public void testClosedException() { // thrown by the instance after it has been closed. closeSpannerAndIncludeStacktrace(spanner); assertThat(spanner.isClosed()).isTrue(); - try { - spanner.getDatabaseClient(DatabaseId.of("p", "i", "d")); - fail("missing expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getCause()).isInstanceOf(ClosedException.class); - StringWriter sw = new StringWriter(); - e.getCause().printStackTrace(new PrintWriter(sw)); - assertThat(sw.toString()).contains("closeSpannerAndIncludeStacktrace"); - } + IllegalStateException e = + assertThrows( + IllegalStateException.class, + () -> spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"))); + assertThat(e.getCause()).isInstanceOf(ClosedException.class); + StringWriter sw = new StringWriter(); + e.getCause().printStackTrace(new PrintWriter(sw)); + assertThat(sw.toString()).contains("closeSpannerAndIncludeStacktrace"); } private void closeSpannerAndIncludeStacktrace(Spanner spanner) { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java index 15bc446f0b4..74ce8d7cb0d 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java @@ -19,7 +19,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import com.google.api.gax.grpc.GrpcCallContext; import com.google.api.gax.retrying.RetrySettings; @@ -440,34 +440,31 @@ public void testInstanceAdminCustomRetrySettings() { @Test public void testInvalidTransport() { - try { - SpannerOptions.newBuilder().setTransportOptions(Mockito.mock(TransportOptions.class)); - fail("Expected exception"); - } catch (IllegalArgumentException ex) { - assertThat(ex.getMessage()).isNotNull(); - } + IllegalArgumentException e = + assertThrows( + IllegalArgumentException.class, + () -> + SpannerOptions.newBuilder() + .setTransportOptions(Mockito.mock(TransportOptions.class))); + assertThat(e.getMessage()).isNotNull(); } @Test public void testInvalidSessionLabels() { Map labels = new HashMap<>(); labels.put("env", null); - try { - SpannerOptions.newBuilder().setSessionLabels(labels); - fail("Expected exception"); - } catch (NullPointerException ex) { - assertThat(ex.getMessage()).isNotNull(); - } + NullPointerException e = + assertThrows( + NullPointerException.class, () -> SpannerOptions.newBuilder().setSessionLabels(labels)); + assertThat(e.getMessage()).isNotNull(); } @Test public void testNullSessionLabels() { - try { - SpannerOptions.newBuilder().setSessionLabels(null); - fail("Expected exception"); - } catch (NullPointerException ex) { - assertThat(ex.getMessage()).isNotNull(); - } + NullPointerException e = + assertThrows( + NullPointerException.class, () -> SpannerOptions.newBuilder().setSessionLabels(null)); + assertThat(e.getMessage()).isNotNull(); } @Test @@ -614,12 +611,8 @@ public void testCompressorName() { .build() .getCompressorName()) .isNull(); - try { - SpannerOptions.newBuilder().setCompressorName("foo"); - fail("missing expected exception"); - } catch (IllegalArgumentException e) { - // ignore, this is the expected exception. - } + assertThrows( + IllegalArgumentException.class, () -> SpannerOptions.newBuilder().setCompressorName("foo")); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerRetryHelperTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerRetryHelperTest.java index 4b5640c548a..a62355923be 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerRetryHelperTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerRetryHelperTest.java @@ -18,7 +18,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import com.google.api.core.ApiClock; import com.google.common.base.Stopwatch; @@ -89,14 +89,14 @@ public void testRetryDoesFailAfterMoreThanOneDay() { } return 1 + 1; }; - try { - SpannerRetryHelper.runTxWithRetriesOnAborted( - callable, SpannerRetryHelper.txRetrySettings, clock); - fail("missing expected exception"); - } catch (SpannerException e) { - assertEquals(ErrorCode.ABORTED, e.getErrorCode()); - assertEquals(1, attempts.get()); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + SpannerRetryHelper.runTxWithRetriesOnAborted( + callable, SpannerRetryHelper.txRetrySettings, clock)); + assertEquals(ErrorCode.ABORTED, e.getErrorCode()); + assertEquals(1, attempts.get()); } @Test @@ -115,17 +115,12 @@ public void testCancelledContext() { withCancellation.cancel(new InterruptedException()); return null; }); - try { - withCancellation.run(() -> SpannerRetryHelper.runTxWithRetriesOnAborted(callable)); - fail("missing expected exception"); - } catch (SpannerException e) { - if (e.getErrorCode() != ErrorCode.CANCELLED) { - fail( - String.format( - "unexpected error %s, expected %s", - e.getErrorCode().name(), ErrorCode.CANCELLED.name())); - } - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + withCancellation.run(() -> SpannerRetryHelper.runTxWithRetriesOnAborted(callable))); + assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); } @Test @@ -135,19 +130,13 @@ public void testTimedOutContext() { () -> { throw SpannerExceptionFactory.newSpannerException(ErrorCode.ABORTED, "test"); }; - try { - final CancellableContext withDeadline = - Context.current().withDeadline(Deadline.after(1L, TimeUnit.MILLISECONDS), service); - withDeadline.run(() -> SpannerRetryHelper.runTxWithRetriesOnAborted(callable)); - fail("missing expected exception"); - } catch (SpannerException e) { - if (e.getErrorCode() != ErrorCode.DEADLINE_EXCEEDED) { - fail( - String.format( - "unexpected error %s, expected %s", - e.getErrorCode().name(), ErrorCode.DEADLINE_EXCEEDED.name())); - } - } + final CancellableContext withDeadline = + Context.current().withDeadline(Deadline.after(1L, TimeUnit.MILLISECONDS), service); + SpannerException e = + assertThrows( + SpannerException.class, + () -> withDeadline.run(() -> SpannerRetryHelper.runTxWithRetriesOnAborted(callable))); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/StatementTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/StatementTest.java index 4e39d1271d2..b2c8244f64d 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/StatementTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/StatementTest.java @@ -19,7 +19,7 @@ import static com.google.common.testing.SerializableTester.reserializeAndAssert; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import com.google.cloud.ByteArray; import com.google.common.collect.ImmutableMap; @@ -102,47 +102,32 @@ public void bindReplacement() { public void incompleteBinding() { Statement.Builder builder = Statement.newBuilder("SELECT @v"); builder.bind("v"); - try { - builder.build(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).isNotNull(); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> builder.build()); + assertNotNull(e.getMessage()); } @Test public void bindingInProgress() { Statement.Builder builder = Statement.newBuilder("SELECT @v"); builder.bind("v"); - try { - builder.bind("y"); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).isNotNull(); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> builder.bind("y")); + assertNotNull(e.getMessage()); } @Test public void alreadyBound() { ValueBinder binder = Statement.newBuilder("SELECT @v").bind("v"); binder.to("abc"); - try { - binder.to("xyz"); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).isNotNull(); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> binder.to("xyz")); + assertNotNull(e.getMessage()); } @Test public void bindCommitTimestampFails() { ValueBinder binder = Statement.newBuilder("SELECT @v").bind("v"); - try { - binder.to(Value.COMMIT_TIMESTAMP); - fail("Expected exception"); - } catch (IllegalArgumentException ex) { - assertNotNull(ex.getMessage()); - } + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> binder.to(Value.COMMIT_TIMESTAMP)); + assertNotNull(e.getMessage()); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TimestampBoundTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TimestampBoundTest.java index 955485da5de..e56f85321bb 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TimestampBoundTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TimestampBoundTest.java @@ -20,7 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import com.google.cloud.Timestamp; import com.google.cloud.spanner.TimestampBound.Mode; @@ -89,12 +89,11 @@ public void exactStaleness() { @Test public void exactStalenessNegative() { - try { - TimestampBound.ofExactStaleness(-1, TimeUnit.SECONDS); - fail("Expected exception"); - } catch (IllegalArgumentException ex) { - assertNotNull(ex.getMessage()); - } + IllegalArgumentException e = + assertThrows( + IllegalArgumentException.class, + () -> TimestampBound.ofExactStaleness(-1, TimeUnit.SECONDS)); + assertNotNull(e.getMessage()); } @Test @@ -122,12 +121,11 @@ public void stalenessSourceUnits() { @Test public void maxStalenessNegative() { - try { - TimestampBound.ofMaxStaleness(-1, TimeUnit.SECONDS); - fail("Expected exception"); - } catch (IllegalArgumentException ex) { - assertNotNull(ex.getMessage()); - } + IllegalArgumentException e = + assertThrows( + IllegalArgumentException.class, + () -> TimestampBound.ofMaxStaleness(-1, TimeUnit.SECONDS)); + assertNotNull(e.getMessage()); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerImplTest.java index 6e2fa03960d..af2ad12df71 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionManagerImplTest.java @@ -17,8 +17,9 @@ package com.google.cloud.spanner; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -86,42 +87,27 @@ public void beginCalledTwiceFails() { when(session.newTransaction(Options.fromTransactionOptions())).thenReturn(txn); assertThat(manager.begin()).isEqualTo(txn); assertThat(manager.getState()).isEqualTo(TransactionState.STARTED); - try { - manager.begin(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertNotNull(ex.getMessage()); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> manager.begin()); + assertNotNull(e.getMessage()); } @Test public void commitBeforeBeginFails() { - try { - manager.commit(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertNotNull(ex.getMessage()); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> manager.commit()); + assertNotNull(e.getMessage()); } @Test public void rollbackBeforeBeginFails() { - try { - manager.rollback(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertNotNull(ex.getMessage()); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> manager.rollback()); + assertNotNull(e.getMessage()); } @Test public void resetBeforeBeginFails() { - try { - manager.resetForRetry(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertNotNull(ex.getMessage()); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> manager.resetForRetry()); + assertNotNull(e.getMessage()); } @Test @@ -150,12 +136,9 @@ public void resetAfterSuccessfulCommitFails() { when(session.newTransaction(Options.fromTransactionOptions())).thenReturn(txn); manager.begin(); manager.commit(); - try { - manager.resetForRetry(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertNotNull(ex.getMessage()); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> manager.resetForRetry()); + assertNotNull(e.getMessage()); } @Test @@ -163,12 +146,9 @@ public void resetAfterAbortSucceeds() { when(session.newTransaction(Options.fromTransactionOptions())).thenReturn(txn); manager.begin(); doThrow(SpannerExceptionFactory.newSpannerException(ErrorCode.ABORTED, "")).when(txn).commit(); - try { - manager.commit(); - fail("Expected AbortedException"); - } catch (AbortedException e) { - assertThat(manager.getState()).isEqualTo(TransactionState.ABORTED); - } + assertThrows(AbortedException.class, () -> manager.commit()); + assertEquals(TransactionState.ABORTED, manager.getState()); + txn = Mockito.mock(TransactionRunnerImpl.TransactionContextImpl.class); when(session.newTransaction(Options.fromTransactionOptions())).thenReturn(txn); assertThat(manager.resetForRetry()).isEqualTo(txn); @@ -180,18 +160,12 @@ public void resetAfterErrorFails() { when(session.newTransaction(Options.fromTransactionOptions())).thenReturn(txn); manager.begin(); doThrow(SpannerExceptionFactory.newSpannerException(ErrorCode.UNKNOWN, "")).when(txn).commit(); - try { - manager.commit(); - fail("Expected AbortedException"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.UNKNOWN); - } - try { - manager.resetForRetry(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertNotNull(ex.getMessage()); - } + SpannerException e = assertThrows(SpannerException.class, () -> manager.commit()); + assertEquals(ErrorCode.UNKNOWN, e.getErrorCode()); + + IllegalStateException illegal = + assertThrows(IllegalStateException.class, () -> manager.resetForRetry()); + assertNotNull(illegal.getMessage()); } @Test @@ -199,12 +173,8 @@ public void rollbackAfterCommitFails() { when(session.newTransaction(Options.fromTransactionOptions())).thenReturn(txn); manager.begin(); manager.commit(); - try { - manager.rollback(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertNotNull(ex.getMessage()); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> manager.rollback()); + assertNotNull(e.getMessage()); } @Test @@ -212,12 +182,8 @@ public void commitAfterRollbackFails() { when(session.newTransaction(Options.fromTransactionOptions())).thenReturn(txn); manager.begin(); manager.rollback(); - try { - manager.commit(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertNotNull(ex.getMessage()); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> manager.commit()); + assertNotNull(e.getMessage()); } @SuppressWarnings("unchecked") diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionRunnerImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionRunnerImplTest.java index 4398c8c864f..499825c190e 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionRunnerImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TransactionRunnerImplTest.java @@ -17,7 +17,9 @@ package com.google.cloud.spanner; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -220,30 +222,24 @@ public void commitFailsWithNonAbort() { SpannerExceptionFactory.newSpannerException(ErrorCode.UNKNOWN, "")); doThrow(error).when(txn).commit(); final AtomicInteger numCalls = new AtomicInteger(0); - try { - transactionRunner.run( - transaction -> { - numCalls.incrementAndGet(); - return null; - }); - fail("Expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.UNKNOWN); - } - assertThat(numCalls.get()).isEqualTo(1); + SpannerException e = + assertThrows( + SpannerException.class, + () -> transactionRunner.run(transaction -> numCalls.incrementAndGet())); + assertEquals(ErrorCode.UNKNOWN, e.getErrorCode()); + assertEquals(1, numCalls.get()); verify(txn, never()).ensureTxn(); verify(txn, times(1)).commit(); } @Test public void runResourceExhaustedNoRetry() { - try { - runTransaction( - new StatusRuntimeException(Status.fromCodeValue(Status.Code.RESOURCE_EXHAUSTED.value()))); - fail("Expected exception"); - } catch (SpannerException e) { - // expected. - } + assertThrows( + SpannerException.class, + () -> + runTransaction( + new StatusRuntimeException( + Status.fromCodeValue(Status.Code.RESOURCE_EXHAUSTED.value())))); verify(txn).rollback(); } @@ -257,14 +253,12 @@ public void batchDmlAborted() { @Test public void batchDmlFailedPrecondition() { - try { - batchDmlException(Code.FAILED_PRECONDITION_VALUE); - fail("Expected exception"); - } catch (SpannerBatchUpdateException e) { - assertThat(e.getUpdateCounts().length).isEqualTo(1); - assertThat(e.getUpdateCounts()[0]).isEqualTo(1L); - assertThat(e.getCode() == Code.FAILED_PRECONDITION_VALUE); - } + SpannerBatchUpdateException e = + assertThrows( + SpannerBatchUpdateException.class, + () -> batchDmlException(Code.FAILED_PRECONDITION_VALUE)); + assertArrayEquals(new long[] {1L}, e.getUpdateCounts()); + assertEquals(Code.FAILED_PRECONDITION_VALUE, e.getCode()); } @SuppressWarnings("unchecked") diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TypeTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TypeTest.java index e9f9009fe8d..b08545af49e 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TypeTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TypeTest.java @@ -20,7 +20,7 @@ import static com.google.common.testing.SerializableTester.reserializeAndAssert; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import com.google.spanner.v1.TypeCode; import org.hamcrest.MatcherAssert; @@ -308,46 +308,34 @@ public void emptyStruct() { @Test public void structFieldIndexNotFound() { Type t = Type.struct(StructField.of("f1", Type.int64())); - try { - t.getFieldIndex("f2"); - fail("Expected exception"); - } catch (IllegalArgumentException ex) { - assertThat(ex.getMessage().contains("Field not found: f2")); - } + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> t.getFieldIndex("f2")); + assertThat(e.getMessage().contains("Field not found: f2")); } @Test public void structFieldIndexAmbiguous() { Type t = Type.struct(StructField.of("f1", Type.int64()), StructField.of("f1", Type.string())); - try { - t.getFieldIndex("f1"); - fail("Expected exception"); - } catch (IllegalArgumentException ex) { - assertThat(ex.getMessage().contains("Ambiguous field name: f1")); - } + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> t.getFieldIndex("f1")); + assertThat(e.getMessage().contains("Ambiguous field name: f1")); } @Test public void parseErrorMissingTypeCode() { com.google.spanner.v1.Type proto = com.google.spanner.v1.Type.newBuilder().build(); - try { - Type.fromProto(proto); - fail("Expected exception"); - } catch (IllegalArgumentException ex) { - assertNotNull(ex.getMessage()); - } + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> Type.fromProto(proto)); + assertNotNull(e.getMessage()); } @Test public void parseErrorMissingArrayElementTypeProto() { com.google.spanner.v1.Type proto = com.google.spanner.v1.Type.newBuilder().setCode(TypeCode.ARRAY).build(); - try { - Type.fromProto(proto); - fail("Expected exception"); - } catch (IllegalArgumentException ex) { - assertNotNull(ex.getMessage()); - } + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> Type.fromProto(proto)); + assertNotNull(e.getMessage()); } private static void assertProtoEquals(com.google.spanner.v1.Type proto, String expected) { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java index 15a22e61cda..22aabbd82df 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java @@ -20,7 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import com.google.cloud.ByteArray; import com.google.cloud.Date; @@ -81,12 +81,8 @@ public void boolWrapperNull() { assertThat(v.getType()).isEqualTo(Type.bool()); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getBool(); - fail("Expected exception"); - } catch (IllegalStateException ex) { - assertThat(ex.getMessage()).contains("null value"); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getBool()); + assertThat(e.getMessage()).contains("null value"); } @Test @@ -101,34 +97,23 @@ public void int64() { @Test public void int64TryGetBool() { Value value = Value.int64(1234); - try { - value.getBool(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage()).contains("Expected: BOOL actual: INT64"); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> value.getBool()); + assertThat(e.getMessage()).contains("Expected: BOOL actual: INT64"); } @Test public void int64NullTryGetBool() { Value value = Value.int64(null); - try { - value.getBool(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage()).contains("Expected: BOOL actual: INT64"); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> value.getBool()); + assertThat(e.getMessage()).contains("Expected: BOOL actual: INT64"); } @Test public void int64TryGetInt64Array() { Value value = Value.int64(1234); - try { - value.getInt64Array(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage()).contains("Expected: ARRAY actual: INT64"); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> value.getInt64Array()); + assertThat(e.getMessage()).contains("Expected: ARRAY actual: INT64"); } @Test @@ -146,12 +131,8 @@ public void int64WrapperNull() { assertThat(v.getType()).isEqualTo(Type.int64()); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getInt64(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage()).contains("null value"); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getInt64()); + assertThat(e.getMessage()).contains("null value"); } @Test @@ -178,12 +159,8 @@ public void float64WrapperNull() { assertThat(v.getType()).isEqualTo(Type.float64()); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getFloat64(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage()).contains("null value"); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getFloat64()); + assertThat(e.getMessage()).contains("null value"); } @Test @@ -269,18 +246,16 @@ public void numericPrecisionAndScale() { BigDecimal sign = new BigDecimal(s); assertThat(Value.numeric(new BigDecimal(Strings.repeat("9", 29)).multiply(sign)).toString()) .isEqualTo((s == -1L ? "-" : "") + Strings.repeat("9", 29)); - try { - Value.numeric(new BigDecimal(Strings.repeat("9", 30)).multiply(sign)); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.OUT_OF_RANGE); - } - try { - Value.numeric(new BigDecimal("1" + Strings.repeat("0", 29)).multiply(sign)); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.OUT_OF_RANGE); - } + SpannerException e1 = + assertThrows( + SpannerException.class, + () -> Value.numeric(new BigDecimal(Strings.repeat("9", 30)).multiply(sign))); + assertThat(e1.getErrorCode()).isEqualTo(ErrorCode.OUT_OF_RANGE); + SpannerException e2 = + assertThrows( + SpannerException.class, + () -> Value.numeric(new BigDecimal("1" + Strings.repeat("0", 29)).multiply(sign))); + assertThat(e2.getErrorCode()).isEqualTo(ErrorCode.OUT_OF_RANGE); assertThat( Value.numeric(new BigDecimal("0." + Strings.repeat("9", 9)).multiply(sign)) @@ -296,12 +271,11 @@ public void numericPrecisionAndScale() { Value.numeric(new BigDecimal("0.1" + Strings.repeat("0", 20)).multiply(sign)) .toString()) .isEqualTo((s == -1L ? "-" : "") + "0.1" + Strings.repeat("0", 20)); - try { - Value.numeric(new BigDecimal("0." + Strings.repeat("9", 10)).multiply(sign)); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.OUT_OF_RANGE); - } + SpannerException e3 = + assertThrows( + SpannerException.class, + () -> Value.numeric(new BigDecimal("0." + Strings.repeat("9", 10)).multiply(sign))); + assertThat(e3.getErrorCode()).isEqualTo(ErrorCode.OUT_OF_RANGE); assertThat( Value.numeric( @@ -311,35 +285,36 @@ public void numericPrecisionAndScale() { .isEqualTo( (s == -1L ? "-" : "") + Strings.repeat("9", 29) + "." + Strings.repeat("9", 9)); - try { - Value.numeric( - new BigDecimal(Strings.repeat("9", 30) + "." + Strings.repeat("9", 9)).multiply(sign)); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.OUT_OF_RANGE); - } - try { - Value.numeric( - new BigDecimal("1" + Strings.repeat("0", 29) + "." + Strings.repeat("9", 9)) - .multiply(sign)); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.OUT_OF_RANGE); - } - - try { - Value.numeric( - new BigDecimal(Strings.repeat("9", 29) + "." + Strings.repeat("9", 10)).multiply(sign)); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.OUT_OF_RANGE); - } - try { - Value.numeric(new BigDecimal("1." + Strings.repeat("9", 10)).multiply(sign)); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.OUT_OF_RANGE); - } + SpannerException e4 = + assertThrows( + SpannerException.class, + () -> + Value.numeric( + new BigDecimal(Strings.repeat("9", 30) + "." + Strings.repeat("9", 9)) + .multiply(sign))); + assertThat(e4.getErrorCode()).isEqualTo(ErrorCode.OUT_OF_RANGE); + SpannerException e5 = + assertThrows( + SpannerException.class, + () -> + Value.numeric( + new BigDecimal("1" + Strings.repeat("0", 29) + "." + Strings.repeat("9", 9)) + .multiply(sign))); + assertThat(e5.getErrorCode()).isEqualTo(ErrorCode.OUT_OF_RANGE); + + SpannerException e6 = + assertThrows( + SpannerException.class, + () -> + Value.numeric( + new BigDecimal(Strings.repeat("9", 29) + "." + Strings.repeat("9", 10)) + .multiply(sign))); + assertThat(e6.getErrorCode()).isEqualTo(ErrorCode.OUT_OF_RANGE); + SpannerException e7 = + assertThrows( + SpannerException.class, + () -> Value.numeric(new BigDecimal("1." + Strings.repeat("9", 10)).multiply(sign))); + assertThat(e7.getErrorCode()).isEqualTo(ErrorCode.OUT_OF_RANGE); } } @@ -350,12 +325,8 @@ public void numericNull() { assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getNumeric(); - fail("missing expected IllegalStateException"); - } catch (IllegalStateException e) { - assertThat(e.getMessage()).contains("null value"); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getNumeric()); + assertThat(e.getMessage()).contains("null value"); } @Test @@ -372,12 +343,8 @@ public void stringNull() { assertThat(v.getType()).isEqualTo(Type.string()); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getString(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getString()); + assertThat(e.getMessage().contains("null value")); } @Test @@ -414,12 +381,8 @@ public void bytesNull() { assertThat(v.getType()).isEqualTo(Type.bytes()); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getBytes(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getBytes()); + assertThat(e.getMessage().contains("null value")); } @Test @@ -441,12 +404,8 @@ public void timestampNull() { assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); assertThat(v.isCommitTimestamp()).isFalse(); - try { - v.getTimestamp(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getTimestamp()); + assertThat(e.getMessage().contains("null value")); } @Test @@ -461,12 +420,8 @@ public void commitTimestamp() { com.google.protobuf.Value.newBuilder() .setStringValue("spanner.commit_timestamp()") .build()); - try { - v.getTimestamp(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("Commit timestamp value")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getTimestamp()); + assertThat(e.getMessage().contains("Commit timestamp value")); } @Test @@ -486,12 +441,8 @@ public void dateNull() { assertThat(v.getType()).isEqualTo(Type.date()); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getDate(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getDate()); + assertThat(e.getMessage().contains("null value")); } @Test @@ -515,12 +466,8 @@ public void boolArrayNull() { Value v = Value.boolArray((boolean[]) null); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getBoolArray(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getBoolArray()); + assertThat(e.getMessage().contains("null value")); } @Test @@ -536,12 +483,8 @@ public void boolArrayFromListNull() { Value v = Value.boolArray((Iterable) null); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getBoolArray(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getBoolArray()); + assertThat(e.getMessage().contains("null value")); } @Test @@ -564,12 +507,9 @@ public void boolArrayFromPlainIterable() { @Test public void boolArrayTryGetInt64Array() { Value value = Value.boolArray(Collections.singletonList(true)); - try { - value.getInt64Array(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("Expected: ARRAY actual: ARRAY")); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> value.getInt64Array()); + assertThat(e.getMessage().contains("Expected: ARRAY actual: ARRAY")); } @Test @@ -593,12 +533,8 @@ public void int64ArrayNull() { Value v = Value.int64Array((long[]) null); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getInt64Array(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getInt64Array()); + assertThat(e.getMessage().contains("null value")); } @Test @@ -614,34 +550,22 @@ public void int64ArrayWrapperNull() { Value v = Value.int64Array((Iterable) null); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getInt64Array(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getInt64Array()); + assertThat(e.getMessage().contains("null value")); } @Test public void int64ArrayTryGetBool() { Value value = Value.int64Array(Collections.singletonList(1234L)); - try { - value.getBool(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("Expected: BOOL actual: ARRAY")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> value.getBool()); + assertThat(e.getMessage().contains("Expected: BOOL actual: ARRAY")); } @Test public void int64ArrayNullTryGetBool() { Value value = Value.int64Array((Iterable) null); - try { - value.getBool(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("Expected: BOOL actual: ARRAY")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> value.getBool()); + assertThat(e.getMessage().contains("Expected: BOOL actual: ARRAY")); } @Test @@ -665,12 +589,8 @@ public void float64ArrayNull() { Value v = Value.float64Array((double[]) null); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getFloat64Array(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getFloat64Array()); + assertThat(e.getMessage().contains("null value")); } @Test @@ -686,23 +606,16 @@ public void float64ArrayWrapperNull() { Value v = Value.float64Array((Iterable) null); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getFloat64Array(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getFloat64Array()); + assertThat(e.getMessage().contains("null value")); } @Test public void float64ArrayTryGetInt64Array() { Value value = Value.float64Array(Collections.singletonList(.1)); - try { - value.getInt64Array(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("Expected: ARRAY actual: ARRAY")); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> value.getInt64Array()); + assertThat(e.getMessage().contains("Expected: ARRAY actual: ARRAY")); } @Test @@ -722,24 +635,17 @@ public void numericArrayNull() { assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getNumericArray(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("Expected: ARRAY actual: ARRAY")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getNumericArray()); + assertThat(e.getMessage().contains("Expected: ARRAY actual: ARRAY")); } @Test public void numericArrayTryGetInt64Array() { Value value = Value.numericArray(Collections.singletonList(BigDecimal.valueOf(1, 1))); - try { - value.getInt64Array(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("Expected: ARRAY actual: ARRAY")); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> value.getInt64Array()); + assertThat(e.getMessage().contains("Expected: ARRAY actual: ARRAY")); } @Test @@ -755,23 +661,16 @@ public void stringArrayNull() { Value v = Value.stringArray(null); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getStringArray(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getStringArray()); + assertThat(e.getMessage().contains("null value")); } @Test public void stringArrayTryGetBytesArray() { Value value = Value.stringArray(Collections.singletonList("a")); - try { - value.getBytesArray(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("Expected: ARRAY actual: ARRAY")); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> value.getBytesArray()); + assertThat(e.getMessage().contains("Expected: ARRAY actual: ARRAY")); } @Test @@ -789,23 +688,16 @@ public void bytesArrayNull() { Value v = Value.bytesArray(null); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getBytesArray(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getBytesArray()); + assertThat(e.getMessage().contains("null value")); } @Test public void bytesArrayTryGetStringArray() { Value value = Value.bytesArray(Collections.singletonList(newByteArray("a"))); - try { - value.getStringArray(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("Expected: ARRAY actual: ARRAY")); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> value.getStringArray()); + assertThat(e.getMessage().contains("Expected: ARRAY actual: ARRAY")); } @Test @@ -827,12 +719,9 @@ public void timestampArrayNull() { Value v = Value.timestampArray(null); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getTimestampArray(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> v.getTimestampArray()); + assertThat(e.getMessage().contains("null value")); } @Test @@ -853,12 +742,8 @@ public void dateArrayNull() { Value v = Value.dateArray(null); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getDateArray(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage().contains("null value")); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getDateArray()); + assertThat(e.getMessage().contains("null value")); } @Test @@ -872,13 +757,14 @@ public void struct() { Value v2 = Value.struct(struct.getType(), struct); assertThat(v2).isEqualTo(v1); - try { - Value.struct( - Type.struct(Collections.singletonList(StructField.of("f3", Type.string()))), struct); - fail("Expected exception"); - } catch (IllegalArgumentException e) { - assertThat(e.getMessage().contains("Mismatch between struct value and type.")); - } + IllegalArgumentException e = + assertThrows( + IllegalArgumentException.class, + () -> + Value.struct( + Type.struct(Collections.singletonList(StructField.of("f3", Type.string()))), + struct)); + assertThat(e.getMessage().contains("Mismatch between struct value and type.")); } @Test @@ -891,12 +777,8 @@ public void nullStruct() { assertThat(v.getType().getStructFields()).isEqualTo(fieldTypes); assertThat(v.isNull()).isTrue(); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - Value.struct(null); - fail("Expected exception"); - } catch (NullPointerException e) { - assertThat(e.getMessage().contains("Illegal call to create a NULL struct value.")); - } + NullPointerException e = assertThrows(NullPointerException.class, () -> Value.struct(null)); + assertThat(e.getMessage().contains("Illegal call to create a NULL struct value.")); } @Test @@ -907,12 +789,8 @@ public void nullStructGetter() { Value v = Value.struct(Type.struct(fieldTypes), null); assertThat(v.isNull()).isTrue(); - try { - v.getStruct(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage()).contains("Illegal call to getter of null value."); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getStruct()); + assertThat(e.getMessage()).contains("Illegal call to getter of null value."); } @Test @@ -994,12 +872,8 @@ public void structArrayNull() { assertThat(v.isNull()).isTrue(); assertThat(v.getType().getArrayElementType()).isEqualTo(elementType); assertThat(v.toString()).isEqualTo(NULL_STRING); - try { - v.getStructArray(); - fail("Expected exception"); - } catch (IllegalStateException e) { - assertThat(e.getMessage()).contains("Illegal call to getter of null value"); - } + IllegalStateException e = assertThrows(IllegalStateException.class, () -> v.getStructArray()); + assertThat(e.getMessage()).contains("Illegal call to getter of null value"); } @Test @@ -1014,12 +888,10 @@ public void structArrayInvalidType() { Arrays.asList( Struct.newBuilder().set("ff1").to("1").set("ff2").to(1).build(), Struct.newBuilder().set("ff1").to(2).set("ff2").to(3).build()); - try { - Value.structArray(elementType, arrayElements); - fail("Expected exception"); - } catch (IllegalArgumentException e) { - assertThat(e.getMessage()).contains("must have type STRUCT"); - } + IllegalArgumentException e = + assertThrows( + IllegalArgumentException.class, () -> Value.structArray(elementType, arrayElements)); + assertThat(e.getMessage()).contains("must have type STRUCT"); } @Test From 91cb003f68975e053601f2ca6cd5d02c3efd7c5c Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Fri, 7 May 2021 00:56:46 +0200 Subject: [PATCH 12/27] build(deps): update dependency org.jacoco:jacoco-maven-plugin to v0.8.7 (#1136) --- google-cloud-spanner/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index d295b62d36e..77ab722be3a 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -24,7 +24,7 @@ org.jacoco jacoco-maven-plugin - 0.8.6 + 0.8.7 From 223baa57ed548d740ee7817593ef52e1c87ff3ae Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Fri, 7 May 2021 09:09:15 -0700 Subject: [PATCH 13/27] chore: adding cloud-rad java xrefs (#1144) Source-Author: Emily Ball Source-Date: Thu May 6 11:48:47 2021 -0700 Source-Repo: googleapis/synthtool Source-Sha: 046994f491c02806aea60118e214a9edd67f5ab7 Source-Link: https://github.com/googleapis/synthtool/commit/046994f491c02806aea60118e214a9edd67f5ab7 --- .kokoro/release/publish_javadoc11.sh | 7 +++++++ synth.metadata | 5 ++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.kokoro/release/publish_javadoc11.sh b/.kokoro/release/publish_javadoc11.sh index 82f695f1a91..4454fbb9ced 100755 --- a/.kokoro/release/publish_javadoc11.sh +++ b/.kokoro/release/publish_javadoc11.sh @@ -49,6 +49,13 @@ pushd target/docfx-yml python3 -m docuploader create-metadata \ --name ${NAME} \ --version ${VERSION} \ + --xrefs devsite://java/gax \ + --xrefs devsite://java/google-cloud-core \ + --xrefs devsite://java/api-common \ + --xrefs devsite://java/proto-google-common-protos \ + --xrefs devsite://java/google-api-client \ + --xrefs devsite://java/google-http-client \ + --xrefs devsite://java/protobuf \ --language java # upload yml to production bucket diff --git a/synth.metadata b/synth.metadata index 8bfcbf6fa46..94b8998c643 100644 --- a/synth.metadata +++ b/synth.metadata @@ -4,7 +4,7 @@ "git": { "name": ".", "remote": "https://github.com/googleapis/java-spanner.git", - "sha": "1d4eed45eb0b09c816912977393ff7a551eb82d6" + "sha": "91cb003f68975e053601f2ca6cd5d02c3efd7c5c" } }, { @@ -19,7 +19,7 @@ "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "8285c2b4cdbc3771d031ad91e1c4ec9e55fff45d" + "sha": "046994f491c02806aea60118e214a9edd67f5ab7" } } ], @@ -57,7 +57,6 @@ ".github/ISSUE_TEMPLATE/feature_request.md", ".github/ISSUE_TEMPLATE/support_request.md", ".github/PULL_REQUEST_TEMPLATE.md", - ".github/blunderbuss.yml", ".github/generated-files-bot.yml", ".github/readme/synth.py", ".github/snippet-bot.yml", From f7c6e2625196af8c033d368cd83a86166068e69b Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Fri, 7 May 2021 09:46:03 -0700 Subject: [PATCH 14/27] chore: regenerate README (#1146) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-05-07 16:11:25,389 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-05-07 16:11:26,780 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/2ec5559e-6096-4620-9d59-9fa7bb76fd20/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) --- .github/readme/synth.metadata/synth.metadata | 4 ++-- README.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/readme/synth.metadata/synth.metadata b/.github/readme/synth.metadata/synth.metadata index f2a8e5e581d..8b6f29d0d31 100644 --- a/.github/readme/synth.metadata/synth.metadata +++ b/.github/readme/synth.metadata/synth.metadata @@ -4,14 +4,14 @@ "git": { "name": ".", "remote": "https://github.com/googleapis/java-spanner.git", - "sha": "fc3335c55eb504827e835b6e5a1d6fc5dea2c124" + "sha": "223baa57ed548d740ee7817593ef52e1c87ff3ae" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "06a8cd0ff7e81b05e6c503eab510ec622384caa7" + "sha": "046994f491c02806aea60118e214a9edd67f5ab7" } } ] diff --git a/README.md b/README.md index f26be8b5449..ad65e612fa3 100644 --- a/README.md +++ b/README.md @@ -51,12 +51,12 @@ compile 'com.google.cloud:google-cloud-spanner' ``` If you are using Gradle without BOM, add this to your dependencies ```Groovy -compile 'com.google.cloud:google-cloud-spanner:6.4.0' +compile 'com.google.cloud:google-cloud-spanner:4.0.3' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.4.0" +libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "4.0.3" ``` ## Authentication From 2e7f18a52ef2ed5de6a87169eeefd570844a4c55 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Tue, 11 May 2021 03:22:26 +0200 Subject: [PATCH 15/27] deps: update dependency com.google.cloud:google-cloud-shared-dependencies to v1.1.0 (#1152) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [com.google.cloud:google-cloud-shared-dependencies](https://togithub.com/googleapis/java-shared-dependencies) | `1.0.0` -> `1.1.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.1.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.1.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.1.0/compatibility-slim/1.0.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-shared-dependencies/1.1.0/confidence-slim/1.0.0)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
googleapis/java-shared-dependencies ### [`v1.1.0`](https://togithub.com/googleapis/java-shared-dependencies/blob/master/CHANGELOG.md#​110-httpswwwgithubcomgoogleapisjava-shared-dependenciescompare100v110-2021-05-10) [Compare Source](https://togithub.com/googleapis/java-shared-dependencies/compare/v1.0.0...v1.1.0) ##### Dependencies - update dependency com.google.protobuf:protobuf-bom to v3.16.0 ([#​348](https://www.github.com/googleapis/java-shared-dependencies/issues/348)) ([0aacfde](https://www.github.com/googleapis/java-shared-dependencies/commit/0aacfdeec70e30803734db8287c47e4fad5481ef)) - update gax.version to v1.64.0 ([#​345](https://www.github.com/googleapis/java-shared-dependencies/issues/345)) ([478bd35](https://www.github.com/googleapis/java-shared-dependencies/commit/478bd35296293e81c7e70157f50bfbebdc1bb54d)) - update iam.version to v1.0.13 ([#​343](https://www.github.com/googleapis/java-shared-dependencies/issues/343)) ([3637923](https://www.github.com/googleapis/java-shared-dependencies/commit/363792392b71deff5cc5731104b631122fba5e61))
--- ### Configuration 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻️ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner). --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3b56b269adb..8186d8e29ab 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ UTF-8 github google-cloud-spanner-parent - 1.0.0 + 1.1.0 From fd5e419a4f11311951fb562f4d8706526ad74263 Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Mon, 10 May 2021 19:04:04 -0700 Subject: [PATCH 16/27] chore: regenerate README (#1153) This PR was generated using Autosynth. :rainbow:
Log from Synthtool ``` 2021-05-11 01:27:08,000 synthtool [DEBUG] > Executing /root/.cache/synthtool/java-spanner/.github/readme/synth.py. On branch autosynth-readme nothing to commit, working tree clean 2021-05-11 01:27:09,104 synthtool [DEBUG] > Wrote metadata to .github/readme/synth.metadata/synth.metadata. ```
Full log will be available here: https://source.cloud.google.com/results/invocations/50b0ea29-b4d6-42d8-bb8b-93878d1952fc/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) --- .github/readme/synth.metadata/synth.metadata | 4 ++-- README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/readme/synth.metadata/synth.metadata b/.github/readme/synth.metadata/synth.metadata index 8b6f29d0d31..94ce341681c 100644 --- a/.github/readme/synth.metadata/synth.metadata +++ b/.github/readme/synth.metadata/synth.metadata @@ -4,14 +4,14 @@ "git": { "name": ".", "remote": "https://github.com/googleapis/java-spanner.git", - "sha": "223baa57ed548d740ee7817593ef52e1c87ff3ae" + "sha": "2e7f18a52ef2ed5de6a87169eeefd570844a4c55" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "046994f491c02806aea60118e214a9edd67f5ab7" + "sha": "6726988c677bb78385868bfc48dbfa2fe981d44a" } } ] diff --git a/README.md b/README.md index ad65e612fa3..a1ff8c3c105 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ If you are using Maven without BOM, add this to your dependencies: If you are using Gradle 5.x or later, add this to your dependencies ```Groovy -implementation platform('com.google.cloud:libraries-bom:20.2.0') +implementation platform('com.google.cloud:libraries-bom:20.3.0') compile 'com.google.cloud:google-cloud-spanner' ``` From 28909c095eeb7c790a9ca2c373190d64355db538 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Tue, 11 May 2021 07:16:39 +0200 Subject: [PATCH 17/27] chore(deps): update dependency com.google.cloud:libraries-bom to v20.3.0 (#1149) --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 2d10191e8d4..1c4709348fc 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -33,7 +33,7 @@ com.google.cloud libraries-bom - 20.2.0 + 20.3.0 pom import From cd4564309adcc55d00600f1512707420815b453a Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Mon, 10 May 2021 22:59:17 -0700 Subject: [PATCH 18/27] chore: regenerate README (#1154) --- .github/readme/synth.metadata/synth.metadata | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/readme/synth.metadata/synth.metadata b/.github/readme/synth.metadata/synth.metadata index 94ce341681c..cf160babddc 100644 --- a/.github/readme/synth.metadata/synth.metadata +++ b/.github/readme/synth.metadata/synth.metadata @@ -4,7 +4,7 @@ "git": { "name": ".", "remote": "https://github.com/googleapis/java-spanner.git", - "sha": "2e7f18a52ef2ed5de6a87169eeefd570844a4c55" + "sha": "28909c095eeb7c790a9ca2c373190d64355db538" } }, { diff --git a/README.md b/README.md index a1ff8c3c105..0f35e35869a 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ If you are using Maven with [BOM][libraries-bom], add this to your pom.xml file com.google.cloud libraries-bom - 20.2.0 + 20.3.0 pom import From 6ce4c2da0e1378011793fd1fa136f669624234a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Wed, 12 May 2021 00:11:28 +0200 Subject: [PATCH 19/27] test: improve execution speed of tests (#1151) * test: improve execution speed of tests * fix: address review comments + serialize scripts in ITs * fix: add last batch to list * fix: create new list instead of clearing it * build: remove custom skip tests variable * test: add test for retry admin requests --- google-cloud-spanner/pom.xml | 2 - .../google/cloud/spanner/SpannerOptions.java | 26 + .../cloud/spanner/spi/v1/GapicSpannerRpc.java | 377 ++--- .../spanner/DatabaseAdminClientTest.java | 60 +- .../cloud/spanner/DatabaseClientImplTest.java | 20 +- .../spanner/MockDatabaseAdminServiceImpl.java | 32 +- .../RetryOnInvalidatedSessionTest.java | 1420 +++++++---------- .../cloud/spanner/SpannerGaxRetryTest.java | 3 +- .../connection/AbstractMockServerTest.java | 33 +- .../connection/AbstractSqlScriptVerifier.java | 101 +- .../connection/ClientSideStatementsTest.java | 2 +- .../connection/ConnectionAsyncApiTest.java | 45 +- .../ConnectionImplGeneratedSqlScriptTest.java | 2 +- .../SetReadOnlyStalenessSqlScriptTest.java | 2 +- .../SetStatementTimeoutSqlScriptTest.java | 2 +- .../connection/StatementTimeoutTest.java | 660 ++++---- .../spanner/connection/it/ITDdlTest.java | 2 +- .../connection/it/ITReadOnlySpannerTest.java | 4 +- .../it/ITReadWriteAutocommitSpannerTest.java | 2 +- .../connection/it/ITSqlMusicScriptTest.java | 2 +- .../connection/it/ITSqlScriptTest.java | 47 +- .../connection/it/ITTransactionModeTest.java | 2 +- .../spanner/spi/v1/GapicSpannerRpcTest.java | 157 +- samples/README.md | 2 +- 24 files changed, 1425 insertions(+), 1580 deletions(-) diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index 77ab722be3a..ad37f479a99 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -15,7 +15,6 @@ google-cloud-spanner - false @@ -51,7 +50,6 @@ default-test com.google.cloud.spanner.TracerTest,com.google.cloud.spanner.IntegrationTest - ${skipUTs}
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java index 62cfa336e9e..88587c6428a 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java @@ -104,6 +104,7 @@ public class SpannerOptions extends ServiceOptions { private final DatabaseAdminStubSettings databaseAdminStubSettings; private final Duration partitionedDmlTimeout; private final boolean autoThrottleAdministrativeRequests; + private final RetrySettings retryAdministrativeRequestsSettings; private final boolean trackTransactionStarter; /** * These are the default {@link QueryOptions} defined by the user on this {@link SpannerOptions}. @@ -554,6 +555,7 @@ private SpannerOptions(Builder builder) { } partitionedDmlTimeout = builder.partitionedDmlTimeout; autoThrottleAdministrativeRequests = builder.autoThrottleAdministrativeRequests; + retryAdministrativeRequestsSettings = builder.retryAdministrativeRequestsSettings; trackTransactionStarter = builder.trackTransactionStarter; defaultQueryOptions = builder.defaultQueryOptions; envQueryOptions = builder.getEnvironmentQueryOptions(); @@ -606,6 +608,13 @@ public static class Builder extends ServiceOptions.Builder { static final int DEFAULT_PREFETCH_CHUNKS = 4; static final QueryOptions DEFAULT_QUERY_OPTIONS = QueryOptions.getDefaultInstance(); + static final RetrySettings DEFAULT_ADMIN_REQUESTS_LIMIT_EXCEEDED_RETRY_SETTINGS = + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.ofSeconds(5L)) + .setRetryDelayMultiplier(2.0) + .setMaxRetryDelay(Duration.ofSeconds(60L)) + .setMaxAttempts(10) + .build(); private final ImmutableSet allowedClientLibTokens = ImmutableSet.of( ServiceOptions.getGoogApiClientLibName(), @@ -632,6 +641,8 @@ public static class Builder private DatabaseAdminStubSettings.Builder databaseAdminStubSettingsBuilder = DatabaseAdminStubSettings.newBuilder(); private Duration partitionedDmlTimeout = Duration.ofHours(2L); + private RetrySettings retryAdministrativeRequestsSettings = + DEFAULT_ADMIN_REQUESTS_LIMIT_EXCEEDED_RETRY_SETTINGS; private boolean autoThrottleAdministrativeRequests = false; private boolean trackTransactionStarter = false; private Map defaultQueryOptions = new HashMap<>(); @@ -680,6 +691,7 @@ private Builder() { this.databaseAdminStubSettingsBuilder = options.databaseAdminStubSettings.toBuilder(); this.partitionedDmlTimeout = options.partitionedDmlTimeout; this.autoThrottleAdministrativeRequests = options.autoThrottleAdministrativeRequests; + this.retryAdministrativeRequestsSettings = options.retryAdministrativeRequestsSettings; this.trackTransactionStarter = options.trackTransactionStarter; this.defaultQueryOptions = options.defaultQueryOptions; this.callCredentialsProvider = options.callCredentialsProvider; @@ -892,6 +904,16 @@ public Builder setAutoThrottleAdministrativeRequests() { return this; } + /** + * Sets the retry settings for retrying administrative requests when the quote of administrative + * requests per minute has been exceeded. + */ + Builder setRetryAdministrativeRequestsSettings( + RetrySettings retryAdministrativeRequestsSettings) { + this.retryAdministrativeRequestsSettings = retryAdministrativeRequestsSettings; + return this; + } + /** * Instructs the client library to track the first request of each read/write transaction. This * statement will include a BeginTransaction option and will return a transaction id as part of @@ -1092,6 +1114,10 @@ public boolean isAutoThrottleAdministrativeRequests() { return autoThrottleAdministrativeRequests; } + public RetrySettings getRetryAdministrativeRequestsSettings() { + return retryAdministrativeRequestsSettings; + } + public boolean isTrackTransactionStarter() { return trackTransactionStarter; } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java index 29ee44bede3..ef7966beed1 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java @@ -273,6 +273,7 @@ private void awaitTermination() throws InterruptedException { private final ScheduledExecutorService spannerWatchdog; private final boolean throttleAdministrativeRequests; + private final RetrySettings retryAdministrativeRequestsSettings; private static final double ADMINISTRATIVE_REQUESTS_RATE_LIMIT = 1.0D; private static final ConcurrentMap ADMINISTRATIVE_REQUESTS_RATE_LIMITERS = new ConcurrentHashMap<>(); @@ -282,6 +283,10 @@ public static GapicSpannerRpc create(SpannerOptions options) { } public GapicSpannerRpc(final SpannerOptions options) { + this(options, true); + } + + GapicSpannerRpc(final SpannerOptions options, boolean initializeStubs) { this.projectId = options.getProjectId(); String projectNameStr = PROJECT_NAME_TEMPLATE.instantiate("project", this.projectId); try { @@ -296,6 +301,7 @@ public GapicSpannerRpc(final SpannerOptions options) { ADMINISTRATIVE_REQUESTS_RATE_LIMITERS.putIfAbsent( projectNameStr, RateLimiter.create(ADMINISTRATIVE_REQUESTS_RATE_LIMIT)); } + this.retryAdministrativeRequestsSettings = options.getRetryAdministrativeRequestsSettings(); // create a metadataProvider which combines both internal headers and // per-method-call extra headers for channelProvider to inject the headers @@ -322,173 +328,184 @@ public GapicSpannerRpc(final SpannerOptions options) { this.callCredentialsProvider = options.getCallCredentialsProvider(); this.compressorName = options.getCompressorName(); - // Create a managed executor provider. - this.executorProvider = - new ManagedInstantiatingExecutorProvider( - new ThreadFactoryBuilder() - .setDaemon(true) - .setNameFormat("Cloud-Spanner-TransportChannel-%d") - .build()); - // First check if SpannerOptions provides a TransportChannelProvider. Create one - // with information gathered from SpannerOptions if none is provided - InstantiatingGrpcChannelProvider.Builder defaultChannelProviderBuilder = - InstantiatingGrpcChannelProvider.newBuilder() - .setChannelConfigurator(options.getChannelConfigurator()) - .setEndpoint(options.getEndpoint()) - .setMaxInboundMessageSize(MAX_MESSAGE_SIZE) - .setMaxInboundMetadataSize(MAX_METADATA_SIZE) - .setPoolSize(options.getNumChannels()) - - // Before updating this method to setExecutor, please verify with a code owner on - // the lowest version of gax-grpc that needs to be supported. Currently v1.47.17, - // which doesn't support the setExecutor variant. - .setExecutorProvider(executorProvider) - - // Set a keepalive time of 120 seconds to help long running - // commit GRPC calls succeed - .setKeepAliveTime(Duration.ofSeconds(GRPC_KEEPALIVE_SECONDS)) - - // Then check if SpannerOptions provides an InterceptorProvider. Create a default - // SpannerInterceptorProvider if none is provided - .setInterceptorProvider( - SpannerInterceptorProvider.create( - MoreObjects.firstNonNull( - options.getInterceptorProvider(), - SpannerInterceptorProvider.createDefault())) - .withEncoding(compressorName)) - .setHeaderProvider(headerProviderWithUserAgent) - // Attempts direct access to spanner service over gRPC to improve throughput, - // whether the attempt is allowed is totally controlled by service owner. - .setAttemptDirectPath(true); - - TransportChannelProvider channelProvider = - MoreObjects.firstNonNull( - options.getChannelProvider(), defaultChannelProviderBuilder.build()); - - CredentialsProvider credentialsProvider = - GrpcTransportOptions.setUpCredentialsProvider(options); - - spannerWatchdog = - Executors.newSingleThreadScheduledExecutor( - new ThreadFactoryBuilder() - .setDaemon(true) - .setNameFormat("Cloud-Spanner-WatchdogProvider-%d") - .build()); - WatchdogProvider watchdogProvider = - InstantiatingWatchdogProvider.create() - .withExecutor(spannerWatchdog) - .withCheckInterval(checkInterval) - .withClock(NanoClock.getDefaultClock()); - - try { - this.spannerStub = - GrpcSpannerStub.create( - options - .getSpannerStubSettings() - .toBuilder() - .setTransportChannelProvider(channelProvider) - .setCredentialsProvider(credentialsProvider) - .setStreamWatchdogProvider(watchdogProvider) + if (initializeStubs) { + // Create a managed executor provider. + this.executorProvider = + new ManagedInstantiatingExecutorProvider( + new ThreadFactoryBuilder() + .setDaemon(true) + .setNameFormat("Cloud-Spanner-TransportChannel-%d") .build()); - partitionedDmlRetrySettings = - options - .getSpannerStubSettings() - .executeSqlSettings() - .getRetrySettings() - .toBuilder() - .setInitialRpcTimeout(options.getPartitionedDmlTimeout()) - .setMaxRpcTimeout(options.getPartitionedDmlTimeout()) - .setTotalTimeout(options.getPartitionedDmlTimeout()) - .setRpcTimeoutMultiplier(1.0) - .build(); - SpannerStubSettings.Builder pdmlSettings = options.getSpannerStubSettings().toBuilder(); - pdmlSettings - .setTransportChannelProvider(channelProvider) - .setCredentialsProvider(credentialsProvider) - .setStreamWatchdogProvider(watchdogProvider) - .executeSqlSettings() - .setRetrySettings(partitionedDmlRetrySettings); - pdmlSettings.executeStreamingSqlSettings().setRetrySettings(partitionedDmlRetrySettings); - // The stream watchdog will by default only check for a timeout every 10 seconds, so if the - // timeout is less than 10 seconds, it would be ignored for the first 10 seconds unless we - // also change the StreamWatchdogCheckInterval. - if (options - .getPartitionedDmlTimeout() - .dividedBy(10L) - .compareTo(pdmlSettings.getStreamWatchdogCheckInterval()) - < 0) { - pdmlSettings.setStreamWatchdogCheckInterval( - options.getPartitionedDmlTimeout().dividedBy(10)); - pdmlSettings.setStreamWatchdogProvider( - pdmlSettings - .getStreamWatchdogProvider() - .withCheckInterval(pdmlSettings.getStreamWatchdogCheckInterval())); - } - this.partitionedDmlStub = GrpcSpannerStub.create(pdmlSettings.build()); - - this.instanceAdminStub = - GrpcInstanceAdminStub.create( - options - .getInstanceAdminStubSettings() - .toBuilder() - .setTransportChannelProvider(channelProvider) - .setCredentialsProvider(credentialsProvider) - .setStreamWatchdogProvider(watchdogProvider) + // First check if SpannerOptions provides a TransportChannelProvider. Create one + // with information gathered from SpannerOptions if none is provided + InstantiatingGrpcChannelProvider.Builder defaultChannelProviderBuilder = + InstantiatingGrpcChannelProvider.newBuilder() + .setChannelConfigurator(options.getChannelConfigurator()) + .setEndpoint(options.getEndpoint()) + .setMaxInboundMessageSize(MAX_MESSAGE_SIZE) + .setMaxInboundMetadataSize(MAX_METADATA_SIZE) + .setPoolSize(options.getNumChannels()) + + // Before updating this method to setExecutor, please verify with a code owner on + // the lowest version of gax-grpc that needs to be supported. Currently v1.47.17, + // which doesn't support the setExecutor variant. + .setExecutorProvider(executorProvider) + + // Set a keepalive time of 120 seconds to help long running + // commit GRPC calls succeed + .setKeepAliveTime(Duration.ofSeconds(GRPC_KEEPALIVE_SECONDS)) + + // Then check if SpannerOptions provides an InterceptorProvider. Create a default + // SpannerInterceptorProvider if none is provided + .setInterceptorProvider( + SpannerInterceptorProvider.create( + MoreObjects.firstNonNull( + options.getInterceptorProvider(), + SpannerInterceptorProvider.createDefault())) + .withEncoding(compressorName)) + .setHeaderProvider(headerProviderWithUserAgent) + // Attempts direct access to spanner service over gRPC to improve throughput, + // whether the attempt is allowed is totally controlled by service owner. + .setAttemptDirectPath(true); + + TransportChannelProvider channelProvider = + MoreObjects.firstNonNull( + options.getChannelProvider(), defaultChannelProviderBuilder.build()); + + CredentialsProvider credentialsProvider = + GrpcTransportOptions.setUpCredentialsProvider(options); + + spannerWatchdog = + Executors.newSingleThreadScheduledExecutor( + new ThreadFactoryBuilder() + .setDaemon(true) + .setNameFormat("Cloud-Spanner-WatchdogProvider-%d") .build()); + WatchdogProvider watchdogProvider = + InstantiatingWatchdogProvider.create() + .withExecutor(spannerWatchdog) + .withCheckInterval(checkInterval) + .withClock(NanoClock.getDefaultClock()); - this.databaseAdminStubSettings = - options - .getDatabaseAdminStubSettings() - .toBuilder() - .setTransportChannelProvider(channelProvider) - .setCredentialsProvider(credentialsProvider) - .setStreamWatchdogProvider(watchdogProvider) - .build(); - - // Automatically retry RESOURCE_EXHAUSTED for GetOperation if auto-throttling of - // administrative requests has been set. The GetOperation RPC is called repeatedly by gax - // while polling long-running operations for their progress and can also cause these errors. - // The default behavior is not to retry these errors, and this option should normally only be - // enabled for (integration) testing. - if (options.isAutoThrottleAdministrativeRequests()) { - GrpcStubCallableFactory factory = - new GrpcDatabaseAdminCallableFactory() { - @Override - public UnaryCallable createUnaryCallable( - GrpcCallSettings grpcCallSettings, - UnaryCallSettings callSettings, - ClientContext clientContext) { - // Make GetOperation retry on RESOURCE_EXHAUSTED to prevent polling operations from - // failing with an Administrative requests limit exceeded error. - if (grpcCallSettings - .getMethodDescriptor() - .getFullMethodName() - .equals("google.longrunning.Operations/GetOperation")) { - Set codes = - ImmutableSet.builderWithExpectedSize( - callSettings.getRetryableCodes().size() + 1) - .addAll(callSettings.getRetryableCodes()) - .add(StatusCode.Code.RESOURCE_EXHAUSTED) - .build(); - callSettings = callSettings.toBuilder().setRetryableCodes(codes).build(); + try { + this.spannerStub = + GrpcSpannerStub.create( + options + .getSpannerStubSettings() + .toBuilder() + .setTransportChannelProvider(channelProvider) + .setCredentialsProvider(credentialsProvider) + .setStreamWatchdogProvider(watchdogProvider) + .build()); + partitionedDmlRetrySettings = + options + .getSpannerStubSettings() + .executeSqlSettings() + .getRetrySettings() + .toBuilder() + .setInitialRpcTimeout(options.getPartitionedDmlTimeout()) + .setMaxRpcTimeout(options.getPartitionedDmlTimeout()) + .setTotalTimeout(options.getPartitionedDmlTimeout()) + .setRpcTimeoutMultiplier(1.0) + .build(); + SpannerStubSettings.Builder pdmlSettings = options.getSpannerStubSettings().toBuilder(); + pdmlSettings + .setTransportChannelProvider(channelProvider) + .setCredentialsProvider(credentialsProvider) + .setStreamWatchdogProvider(watchdogProvider) + .executeSqlSettings() + .setRetrySettings(partitionedDmlRetrySettings); + pdmlSettings.executeStreamingSqlSettings().setRetrySettings(partitionedDmlRetrySettings); + // The stream watchdog will by default only check for a timeout every 10 seconds, so if the + // timeout is less than 10 seconds, it would be ignored for the first 10 seconds unless we + // also change the StreamWatchdogCheckInterval. + if (options + .getPartitionedDmlTimeout() + .dividedBy(10L) + .compareTo(pdmlSettings.getStreamWatchdogCheckInterval()) + < 0) { + pdmlSettings.setStreamWatchdogCheckInterval( + options.getPartitionedDmlTimeout().dividedBy(10)); + pdmlSettings.setStreamWatchdogProvider( + pdmlSettings + .getStreamWatchdogProvider() + .withCheckInterval(pdmlSettings.getStreamWatchdogCheckInterval())); + } + this.partitionedDmlStub = GrpcSpannerStub.create(pdmlSettings.build()); + + this.instanceAdminStub = + GrpcInstanceAdminStub.create( + options + .getInstanceAdminStubSettings() + .toBuilder() + .setTransportChannelProvider(channelProvider) + .setCredentialsProvider(credentialsProvider) + .setStreamWatchdogProvider(watchdogProvider) + .build()); + + this.databaseAdminStubSettings = + options + .getDatabaseAdminStubSettings() + .toBuilder() + .setTransportChannelProvider(channelProvider) + .setCredentialsProvider(credentialsProvider) + .setStreamWatchdogProvider(watchdogProvider) + .build(); + + // Automatically retry RESOURCE_EXHAUSTED for GetOperation if auto-throttling of + // administrative requests has been set. The GetOperation RPC is called repeatedly by gax + // while polling long-running operations for their progress and can also cause these errors. + // The default behavior is not to retry these errors, and this option should normally only + // be enabled for (integration) testing. + if (options.isAutoThrottleAdministrativeRequests()) { + GrpcStubCallableFactory factory = + new GrpcDatabaseAdminCallableFactory() { + @Override + public UnaryCallable createUnaryCallable( + GrpcCallSettings grpcCallSettings, + UnaryCallSettings callSettings, + ClientContext clientContext) { + // Make GetOperation retry on RESOURCE_EXHAUSTED to prevent polling operations + // from failing with an Administrative requests limit exceeded error. + if (grpcCallSettings + .getMethodDescriptor() + .getFullMethodName() + .equals("google.longrunning.Operations/GetOperation")) { + Set codes = + ImmutableSet.builderWithExpectedSize( + callSettings.getRetryableCodes().size() + 1) + .addAll(callSettings.getRetryableCodes()) + .add(StatusCode.Code.RESOURCE_EXHAUSTED) + .build(); + callSettings = callSettings.toBuilder().setRetryableCodes(codes).build(); + } + return super.createUnaryCallable(grpcCallSettings, callSettings, clientContext); } - return super.createUnaryCallable(grpcCallSettings, callSettings, clientContext); - } - }; - this.databaseAdminStub = - new GrpcDatabaseAdminStubWithCustomCallableFactory( - databaseAdminStubSettings, - ClientContext.create(databaseAdminStubSettings), - factory); - } else { - this.databaseAdminStub = GrpcDatabaseAdminStub.create(databaseAdminStubSettings); - } + }; + this.databaseAdminStub = + new GrpcDatabaseAdminStubWithCustomCallableFactory( + databaseAdminStubSettings, + ClientContext.create(databaseAdminStubSettings), + factory); + } else { + this.databaseAdminStub = GrpcDatabaseAdminStub.create(databaseAdminStubSettings); + } - // Check whether the SPANNER_EMULATOR_HOST env var has been set, and if so, if the emulator is - // actually running. - checkEmulatorConnection(options, channelProvider, credentialsProvider); - } catch (Exception e) { - throw newSpannerException(e); + // Check whether the SPANNER_EMULATOR_HOST env var has been set, and if so, if the emulator + // is actually running. + checkEmulatorConnection(options, channelProvider, credentialsProvider); + } catch (Exception e) { + throw newSpannerException(e); + } + } else { + this.databaseAdminStub = null; + this.instanceAdminStub = null; + this.spannerStub = null; + this.partitionedDmlStub = null; + this.databaseAdminStubSettings = null; + this.spannerWatchdog = null; + this.partitionedDmlRetrySettings = null; + this.executorProvider = null; } } @@ -578,11 +595,11 @@ public boolean shouldRetry(Throwable prevThrowable, T prevResponse) } } - private static T runWithRetryOnAdministrativeRequestsExceeded(Callable callable) { + private T runWithRetryOnAdministrativeRequestsExceeded(Callable callable) { try { return RetryHelper.runWithRetries( callable, - ADMIN_REQUESTS_LIMIT_EXCEEDED_RETRY_SETTINGS, + retryAdministrativeRequestsSettings, new AdminRequestsLimitExceededRetryAlgorithm<>(), NanoClock.getDefaultClock()); } catch (RetryHelperException e) { @@ -1630,22 +1647,24 @@ GrpcCallContext newCallContext( @Override public void shutdown() { this.rpcIsClosed = true; - this.spannerStub.close(); - this.partitionedDmlStub.close(); - this.instanceAdminStub.close(); - this.databaseAdminStub.close(); - this.spannerWatchdog.shutdown(); - this.executorProvider.shutdown(); + if (this.spannerStub != null) { + this.spannerStub.close(); + this.partitionedDmlStub.close(); + this.instanceAdminStub.close(); + this.databaseAdminStub.close(); + this.spannerWatchdog.shutdown(); + this.executorProvider.shutdown(); - try { - this.spannerStub.awaitTermination(10L, TimeUnit.SECONDS); - this.partitionedDmlStub.awaitTermination(10L, TimeUnit.SECONDS); - this.instanceAdminStub.awaitTermination(10L, TimeUnit.SECONDS); - this.databaseAdminStub.awaitTermination(10L, TimeUnit.SECONDS); - this.spannerWatchdog.awaitTermination(10L, TimeUnit.SECONDS); - this.executorProvider.awaitTermination(); - } catch (InterruptedException e) { - throw SpannerExceptionFactory.propagateInterrupt(e); + try { + this.spannerStub.awaitTermination(10L, TimeUnit.SECONDS); + this.partitionedDmlStub.awaitTermination(10L, TimeUnit.SECONDS); + this.instanceAdminStub.awaitTermination(10L, TimeUnit.SECONDS); + this.databaseAdminStub.awaitTermination(10L, TimeUnit.SECONDS); + this.spannerWatchdog.awaitTermination(10L, TimeUnit.SECONDS); + this.executorProvider.awaitTermination(); + } catch (InterruptedException e) { + throw SpannerExceptionFactory.propagateInterrupt(e); + } } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java index 3a18f24173f..9dcadc85ade 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientTest.java @@ -38,18 +38,22 @@ import com.google.cloud.spanner.MockSpannerServiceImpl.SimulatedExecutionTime; import com.google.longrunning.Operation; import com.google.protobuf.InvalidProtocolBufferException; +import com.google.rpc.ErrorInfo; import com.google.spanner.admin.database.v1.CreateBackupMetadata; import com.google.spanner.admin.database.v1.CreateBackupRequest; import com.google.spanner.admin.database.v1.CreateDatabaseMetadata; import com.google.spanner.admin.database.v1.CreateDatabaseRequest; +import com.google.spanner.admin.database.v1.GetDatabaseRequest; import com.google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata; import com.google.spanner.admin.database.v1.RestoreDatabaseMetadata; import com.google.spanner.admin.database.v1.RestoreDatabaseRequest; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; import io.grpc.ManagedChannelBuilder; +import io.grpc.Metadata; import io.grpc.Server; import io.grpc.Status; import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder; +import io.grpc.protobuf.lite.ProtoLiteUtils; import java.net.InetSocketAddress; import java.util.Arrays; import java.util.Collections; @@ -83,8 +87,8 @@ public class DatabaseAdminClientTest { private static Server server; private static InetSocketAddress address; - private Spanner spanner; - private DatabaseAdminClient client; + private static Spanner spanner; + private static DatabaseAdminClient client; private OperationFuture createDatabaseOperation; private OperationFuture createBackupOperation; private OperationFuture restoreDatabaseOperation; @@ -101,18 +105,6 @@ public static void startStaticServer() throws Exception { .addService(mockDatabaseAdmin) .build() .start(); - } - - @AfterClass - public static void stopServer() throws Exception { - server.shutdown(); - server.awaitTermination(); - } - - @Before - public void setUp() { - mockDatabaseAdmin.reset(); - mockOperations.reset(); SpannerOptions.Builder builder = SpannerOptions.newBuilder(); RetrySettings longRunningInitialRetrySettings = RetrySettings.newBuilder() @@ -193,6 +185,11 @@ public void setUp() { .setRetryDelayMultiplier(1.3) .setRpcTimeoutMultiplier(1.3) .build())); + builder.setRetryAdministrativeRequestsSettings( + SpannerOptions.Builder.DEFAULT_ADMIN_REQUESTS_LIMIT_EXCEEDED_RETRY_SETTINGS + .toBuilder() + .setInitialRetryDelay(Duration.ofNanos(1L)) + .build()); spanner = builder .setHost("http://localhost:" + server.getPort()) @@ -202,6 +199,19 @@ public void setUp() { .build() .getService(); client = spanner.getDatabaseAdminClient(); + } + + @AfterClass + public static void stopServer() throws Exception { + spanner.close(); + server.shutdown(); + server.awaitTermination(); + } + + @Before + public void setUp() { + mockDatabaseAdmin.reset(); + mockOperations.reset(); createTestDatabase(); createTestBackup(); restoreTestBackup(); @@ -212,7 +222,6 @@ public void tearDown() { mockDatabaseAdmin.reset(); mockDatabaseAdmin.removeAllExecutionTimes(); mockOperations.reset(); - spanner.close(); } @Test @@ -905,4 +914,25 @@ public void retryRestoreDatabaseSlowStartup() throws Exception { assertThat(retrieved.getCreateTime()).isEqualTo(database.getCreateTime()); assertThat(mockDatabaseAdmin.countRequestsOfType(RestoreDatabaseRequest.class)).isAtLeast(3); } + + @Test + public void testRetryOperationOnAdminMethodQuotaPerMinutePerProjectExceeded() { + ErrorInfo info = + ErrorInfo.newBuilder() + .putMetadata("quota_limit", "AdminMethodQuotaPerMinutePerProject") + .build(); + Metadata.Key key = + Metadata.Key.of( + info.getDescriptorForType().getFullName() + Metadata.BINARY_HEADER_SUFFIX, + ProtoLiteUtils.metadataMarshaller(info)); + Metadata trailers = new Metadata(); + trailers.put(key, info); + mockDatabaseAdmin.addException( + Status.RESOURCE_EXHAUSTED.withDescription("foo").asRuntimeException(trailers)); + mockDatabaseAdmin.clearRequests(); + + Database database = client.getDatabase(INSTANCE_ID, DB_ID); + assertEquals(DB_ID, database.getId().getDatabase()); + assertEquals(2, mockDatabaseAdmin.countRequestsOfType(GetDatabaseRequest.class)); + } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java index 891f2265620..42c7bb1b944 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java @@ -958,6 +958,7 @@ public void transactionManagerIsNonBlocking() throws Exception { } } + @SuppressWarnings("resource") @Test public void transactionManagerExecuteQueryAsync() throws Exception { DatabaseClient client = @@ -991,7 +992,6 @@ public void transactionManagerExecuteQueryAsync() throws Exception { txManager.commit(); break; } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); transaction = txManager.resetForRetry(); } } @@ -1519,11 +1519,7 @@ public void testBackendQueryOptions() { .setProjectId("[PROJECT]") .setChannelProvider(channelProvider) .setCredentials(NoCredentials.getInstance()) - .setSessionPoolOption( - SessionPoolOptions.newBuilder() - .setMinSessions(0) - .setWriteSessionsFraction(0.0f) - .build()) + .setSessionPoolOption(SessionPoolOptions.newBuilder().setMinSessions(0).build()) .build() .getService()) { DatabaseClient client = @@ -1557,11 +1553,7 @@ public void testBackendQueryOptionsWithAnalyzeQuery() { .setProjectId("[PROJECT]") .setChannelProvider(channelProvider) .setCredentials(NoCredentials.getInstance()) - .setSessionPoolOption( - SessionPoolOptions.newBuilder() - .setMinSessions(0) - .setWriteSessionsFraction(0.0f) - .build()) + .setSessionPoolOption(SessionPoolOptions.newBuilder().setMinSessions(0).build()) .build() .getService()) { DatabaseClient client = @@ -1597,11 +1589,7 @@ public void testBackendPartitionQueryOptions() { .setProjectId("[PROJECT]") .setChannelProvider(channelProvider) .setCredentials(NoCredentials.getInstance()) - .setSessionPoolOption( - SessionPoolOptions.newBuilder() - .setMinSessions(0) - .setWriteSessionsFraction(0.0f) - .build()) + .setSessionPoolOption(SessionPoolOptions.newBuilder().setMinSessions(0).build()) .build() .getService()) { BatchClient client = diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockDatabaseAdminServiceImpl.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockDatabaseAdminServiceImpl.java index 20a39f318f9..6b248f7902d 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockDatabaseAdminServiceImpl.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockDatabaseAdminServiceImpl.java @@ -447,6 +447,7 @@ private com.google.rpc.Status fromException(Exception e) { private SimulatedExecutionTime createDatabaseStartupExecutionTime = SimulatedExecutionTime.none(); private SimulatedExecutionTime createDatabaseResponseExecutionTime = SimulatedExecutionTime.none(); + private SimulatedExecutionTime getDatabaseExecutionTime = SimulatedExecutionTime.none(); private SimulatedExecutionTime restoreDatabaseStartupExecutionTime = SimulatedExecutionTime.none(); private SimulatedExecutionTime restoreDatabaseResponseExecutionTime = @@ -509,17 +510,22 @@ public void dropDatabase(DropDatabaseRequest request, StreamObserver resp @Override public void getDatabase(GetDatabaseRequest request, StreamObserver responseObserver) { requests.add(request); - MockDatabase db = databases.get(request.getName()); - if (db != null) { - responseObserver.onNext( - Database.newBuilder() - .setName(request.getName()) - .setCreateTime(db.createTime) - .setState(State.READY) - .build()); - responseObserver.onCompleted(); - } else { - responseObserver.onError(Status.NOT_FOUND.asRuntimeException()); + try { + getDatabaseExecutionTime.simulateExecutionTime(exceptions, false, freezeLock); + MockDatabase db = databases.get(request.getName()); + if (db != null) { + responseObserver.onNext( + Database.newBuilder() + .setName(request.getName()) + .setCreateTime(db.createTime) + .setState(State.READY) + .build()); + responseObserver.onCompleted(); + } else { + responseObserver.onError(Status.NOT_FOUND.asRuntimeException()); + } + } catch (Throwable t) { + responseObserver.onError(t); } } @@ -912,6 +918,10 @@ public List getRequests() { return new ArrayList<>(requests); } + public void clearRequests() { + requests.clear(); + } + public int countRequestsOfType(final Class type) { return Collections2.filter(getRequests(), input -> input.getClass().equals(type)).size(); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/RetryOnInvalidatedSessionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/RetryOnInvalidatedSessionTest.java index d8eec88d88c..a8fbbeb40b8 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/RetryOnInvalidatedSessionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/RetryOnInvalidatedSessionTest.java @@ -18,10 +18,7 @@ import static com.google.cloud.spanner.SpannerApiFutures.get; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; import com.google.api.core.ApiFuture; @@ -29,13 +26,11 @@ import com.google.api.gax.core.NoCredentialsProvider; import com.google.api.gax.grpc.testing.LocalChannelProvider; import com.google.cloud.NoCredentials; -import com.google.cloud.Timestamp; import com.google.cloud.spanner.AsyncResultSet.CallbackResponse; import com.google.cloud.spanner.AsyncTransactionManager.AsyncTransactionStep; import com.google.cloud.spanner.AsyncTransactionManager.CommitTimestampFuture; import com.google.cloud.spanner.AsyncTransactionManager.TransactionContextFuture; import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult; -import com.google.cloud.spanner.TransactionRunner.TransactionCallable; import com.google.cloud.spanner.v1.SpannerClient; import com.google.cloud.spanner.v1.SpannerClient.ListSessionsPagedResponse; import com.google.cloud.spanner.v1.SpannerSettings; @@ -55,12 +50,12 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; -import org.junit.After; +import java.util.function.Supplier; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -208,30 +203,31 @@ public static void stopServer() throws InterruptedException { } @Before - public void setUp() { + public void setUp() throws InterruptedException { mockSpanner.reset(); - SessionPoolOptions.Builder builder = SessionPoolOptions.newBuilder().setFailOnSessionLeak(); - if (failOnInvalidatedSession) { - builder.setFailIfSessionNotFound(); + if (spanner == null + || spanner.getOptions().getSessionPoolOptions().isFailIfPoolExhausted() + != failOnInvalidatedSession) { + if (spanner != null) { + spanner.close(); + } + SessionPoolOptions.Builder builder = SessionPoolOptions.newBuilder().setFailOnSessionLeak(); + if (failOnInvalidatedSession) { + builder.setFailIfSessionNotFound(); + } + // This prevents repeated retries for a large number of sessions in the pool. + builder.setMinSessions(1); + spanner = + SpannerOptions.newBuilder() + .setProjectId("[PROJECT]") + .setChannelProvider(channelProvider) + .setSessionPoolOption(builder.build()) + .setCredentials(NoCredentials.getInstance()) + .build() + .getService(); + client = spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); + invalidateSessionPool(client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); } - spanner = - SpannerOptions.newBuilder() - .setProjectId("[PROJECT]") - .setChannelProvider(channelProvider) - .setSessionPoolOption(builder.build()) - .setCredentials(NoCredentials.getInstance()) - .build() - .getService(); - client = spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); - } - - @After - public void tearDown() { - spanner.close(); - } - - private static void invalidateSessionPool() throws InterruptedException { - invalidateSessionPool(client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); } private static void invalidateSessionPool(DatabaseClient client, int minSessions) @@ -242,7 +238,7 @@ private static void invalidateSessionPool(DatabaseClient client, int minSessions if (watch.elapsed(TimeUnit.SECONDS) > 5L) { fail(String.format("Failed to create MinSessions=%d", minSessions)); } - Thread.sleep(5L); + Thread.sleep(1L); } ListSessionsPagedResponse response = @@ -252,333 +248,226 @@ private static void invalidateSessionPool(DatabaseClient client, int minSessions } } + private T assertThrowsSessionNotFoundIfShouldFail(Supplier supplier) { + if (failOnInvalidatedSession) { + assertThrows(SessionNotFoundException.class, () -> supplier.get()); + return null; + } else { + return supplier.get(); + } + } + @Test public void singleUseSelect() throws InterruptedException { - invalidateSessionPool(); - try { - // This call will receive an invalidated session that will be replaced on the first call to - // rs.next(). - int count = 0; - try (ReadContext context = client.singleUse()) { - try (ResultSet rs = context.executeQuery(SELECT1AND2)) { - while (rs.next()) { - count++; - } - } + // This call will receive an invalidated session that will be replaced on the first call to + // rs.next(). + try (ReadContext context = client.singleUse()) { + try (ResultSet rs = context.executeQuery(SELECT1AND2)) { + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @Test public void singleUseSelectAsync() throws Exception { - invalidateSessionPool(); ApiFuture> list; try (AsyncResultSet rs = client.singleUse().executeQueryAsync(SELECT1AND2)) { list = rs.toListAsync(TO_LONG, executor); - assertThat(list.get()).containsExactly(1L, 2L); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (ExecutionException e) { - assertThat(e.getCause()).isInstanceOf(SessionNotFoundException.class); - assertThat(failOnInvalidatedSession).isTrue(); + assertThrowsSessionNotFoundIfShouldFail(() -> get(list)); } } @Test public void singleUseRead() throws InterruptedException { - invalidateSessionPool(); - int count = 0; try (ReadContext context = client.singleUse()) { try (ResultSet rs = context.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @Test public void singleUseReadUsingIndex() throws InterruptedException { - invalidateSessionPool(); - int count = 0; try (ReadContext context = client.singleUse()) { try (ResultSet rs = context.readUsingIndex("FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @Test public void singleUseReadRow() throws InterruptedException { - invalidateSessionPool(); try (ReadContext context = client.singleUse()) { - Struct row = context.readRow("FOO", Key.of(), Collections.singletonList("BAR")); - assertThat(row.getLong(0)).isEqualTo(1L); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); + assertThrowsSessionNotFoundIfShouldFail( + () -> context.readRow("FOO", Key.of(), Collections.singletonList("BAR"))); } } @Test public void singleUseReadRowUsingIndex() throws InterruptedException { - invalidateSessionPool(); try (ReadContext context = client.singleUse()) { - Struct row = - context.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR")); - assertThat(row.getLong(0)).isEqualTo(1L); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + context.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR"))); } } @Test public void singleUseReadOnlyTransactionSelect() throws InterruptedException { - invalidateSessionPool(); - int count = 0; try (ReadContext context = client.singleUseReadOnlyTransaction()) { try (ResultSet rs = context.executeQuery(SELECT1AND2)) { - while (rs.next()) { - count++; - } + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @Test public void singleUseReadOnlyTransactionRead() throws InterruptedException { - invalidateSessionPool(); - int count = 0; try (ReadContext context = client.singleUseReadOnlyTransaction()) { try (ResultSet rs = context.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @Test public void singlUseReadOnlyTransactionReadUsingIndex() throws InterruptedException { - invalidateSessionPool(); - int count = 0; try (ReadContext context = client.singleUseReadOnlyTransaction()) { try (ResultSet rs = context.readUsingIndex("FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @Test public void singleUseReadOnlyTransactionReadRow() throws InterruptedException { - invalidateSessionPool(); try (ReadContext context = client.singleUseReadOnlyTransaction()) { - Struct row = context.readRow("FOO", Key.of(), Collections.singletonList("BAR")); - assertThat(row.getLong(0)).isEqualTo(1L); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); + assertThrowsSessionNotFoundIfShouldFail( + () -> context.readRow("FOO", Key.of(), Collections.singletonList("BAR"))); } } @Test public void singleUseReadOnlyTransactionReadRowUsingIndex() throws InterruptedException { - invalidateSessionPool(); try (ReadContext context = client.singleUseReadOnlyTransaction()) { - Struct row = - context.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR")); - assertThat(row.getLong(0)).isEqualTo(1L); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + context.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR"))); } } @Test public void readOnlyTransactionSelect() throws InterruptedException { - invalidateSessionPool(); - int count = 0; try (ReadContext context = client.readOnlyTransaction()) { try (ResultSet rs = context.executeQuery(SELECT1AND2)) { - while (rs.next()) { - count++; - } + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @Test public void readOnlyTransactionRead() throws InterruptedException { - invalidateSessionPool(); - int count = 0; try (ReadContext context = client.readOnlyTransaction()) { try (ResultSet rs = context.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @Test public void readOnlyTransactionReadUsingIndex() throws InterruptedException { - invalidateSessionPool(); - int count = 0; try (ReadContext context = client.readOnlyTransaction()) { try (ResultSet rs = context.readUsingIndex("FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @Test public void readOnlyTransactionReadRow() throws InterruptedException { - invalidateSessionPool(); try (ReadContext context = client.readOnlyTransaction()) { - Struct row = context.readRow("FOO", Key.of(), Collections.singletonList("BAR")); - assertThat(row.getLong(0)).isEqualTo(1L); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); + assertThrowsSessionNotFoundIfShouldFail( + () -> context.readRow("FOO", Key.of(), Collections.singletonList("BAR"))); } } @Test public void readOnlyTransactionReadRowUsingIndex() throws InterruptedException { - invalidateSessionPool(); try (ReadContext context = client.readOnlyTransaction()) { - Struct row = - context.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR")); - assertThat(row.getLong(0)).isEqualTo(1L); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + context.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR"))); } } - @Test(expected = SessionNotFoundException.class) + @Test public void readOnlyTransactionSelectNonRecoverable() throws InterruptedException { - int count = 0; try (ReadContext context = client.readOnlyTransaction()) { try (ResultSet rs = context.executeQuery(SELECT1AND2)) { - while (rs.next()) { - count++; - } + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } - assertThat(count).isEqualTo(2); // Invalidate the session pool while in a transaction. This is not recoverable. - invalidateSessionPool(); + invalidateSessionPool(client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); try (ResultSet rs = context.executeQuery(SELECT1AND2)) { - while (rs.next()) { - count++; - } + assertThrows(SessionNotFoundException.class, () -> rs.next()); } } } - @Test(expected = SessionNotFoundException.class) + @Test public void readOnlyTransactionReadNonRecoverable() throws InterruptedException { - int count = 0; try (ReadContext context = client.readOnlyTransaction()) { try (ResultSet rs = context.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } - assertThat(count).isEqualTo(2); - invalidateSessionPool(); + invalidateSessionPool(client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); try (ResultSet rs = context.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + assertThrows(SessionNotFoundException.class, () -> rs.next()); } } } - @Test(expected = SessionNotFoundException.class) + @Test public void readOnlyTransactionReadUsingIndexNonRecoverable() throws InterruptedException { - int count = 0; try (ReadContext context = client.readOnlyTransaction()) { try (ResultSet rs = context.readUsingIndex("FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } - assertThat(count).isEqualTo(2); - invalidateSessionPool(); + invalidateSessionPool(client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); try (ResultSet rs = context.readUsingIndex("FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + assertThrows(SessionNotFoundException.class, () -> rs.next()); } } } - @Test(expected = SessionNotFoundException.class) + @Test public void readOnlyTransactionReadRowNonRecoverable() throws InterruptedException { try (ReadContext context = client.readOnlyTransaction()) { - Struct row = context.readRow("FOO", Key.of(), Collections.singletonList("BAR")); - assertThat(row.getLong(0)).isEqualTo(1L); - invalidateSessionPool(); - context.readRow("FOO", Key.of(), Collections.singletonList("BAR")); + assertThrowsSessionNotFoundIfShouldFail( + () -> context.readRow("FOO", Key.of(), Collections.singletonList("BAR"))); + invalidateSessionPool(client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); + assertThrows( + SessionNotFoundException.class, + () -> context.readRow("FOO", Key.of(), Collections.singletonList("BAR"))); } } - @Test(expected = SessionNotFoundException.class) + @Test public void readOnlyTransactionReadRowUsingIndexNonRecoverable() throws InterruptedException { try (ReadContext context = client.readOnlyTransaction()) { - Struct row = - context.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR")); - assertThat(row.getLong(0)).isEqualTo(1L); - invalidateSessionPool(); - context.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR")); + assertThrowsSessionNotFoundIfShouldFail( + () -> + context.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR"))); + invalidateSessionPool(client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); + assertThrows( + SessionNotFoundException.class, + () -> + context.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR"))); } } @@ -588,581 +477,409 @@ public void readWriteTransactionReadOnlySessionInPool() throws InterruptedExcept if (failOnInvalidatedSession) { builder.setFailIfSessionNotFound(); } - Spanner spanner = + try (Spanner spanner = SpannerOptions.newBuilder() .setProjectId("[PROJECT]") .setChannelProvider(channelProvider) .setSessionPoolOption(builder.build()) .setCredentials(NoCredentials.getInstance()) .build() - .getService(); - DatabaseClient client = - spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); - invalidateSessionPool(client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); - try { + .getService()) { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); + invalidateSessionPool(client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); TransactionRunner runner = client.readWriteTransaction(); - int count = - runner.run( - transaction -> { - int count1 = 0; - try (ResultSet rs = transaction.executeQuery(SELECT1AND2)) { - while (rs.next()) { - count1++; - } - } - return count1; - }); - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + runner.run( + transaction -> { + try (ResultSet rs = transaction.executeQuery(SELECT1AND2)) { + while (rs.next()) {} + } + return null; + })); } } @Test public void readWriteTransactionSelect() throws InterruptedException { - invalidateSessionPool(); - try { - TransactionRunner runner = client.readWriteTransaction(); - int count = - runner.run( - transaction -> { - int count1 = 0; - try (ResultSet rs = transaction.executeQuery(SELECT1AND2)) { - while (rs.next()) { - count1++; + TransactionRunner runner = client.readWriteTransaction(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + runner.run( + transaction -> { + try (ResultSet rs = transaction.executeQuery(SELECT1AND2)) { + while (rs.next()) {} } - } - return count1; - }); - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + return null; + })); } @Test public void readWriteTransactionRead() throws InterruptedException { - invalidateSessionPool(); - try { - TransactionRunner runner = client.readWriteTransaction(); - int count = - runner.run( - transaction -> { - int count1 = 0; - try (ResultSet rs = - transaction.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count1++; + TransactionRunner runner = client.readWriteTransaction(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + runner.run( + transaction -> { + try (ResultSet rs = + transaction.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { + while (rs.next()) {} } - } - return count1; - }); - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + return null; + })); } @Test public void readWriteTransactionReadUsingIndex() throws InterruptedException { - invalidateSessionPool(); - try { - TransactionRunner runner = client.readWriteTransaction(); - int count = - runner.run( - transaction -> { - int count1 = 0; - try (ResultSet rs = - transaction.readUsingIndex( - "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count1++; + TransactionRunner runner = client.readWriteTransaction(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + runner.run( + transaction -> { + try (ResultSet rs = + transaction.readUsingIndex( + "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { + while (rs.next()) {} } - } - return count1; - }); - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + return null; + })); } @Test public void readWriteTransactionReadRow() throws InterruptedException { - invalidateSessionPool(); - try { - TransactionRunner runner = client.readWriteTransaction(); - Struct row = - runner.run( - transaction -> - transaction.readRow("FOO", Key.of(), Collections.singletonList("BAR"))); - assertThat(row.getLong(0)).isEqualTo(1L); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + TransactionRunner runner = client.readWriteTransaction(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + runner.run( + transaction -> + transaction.readRow("FOO", Key.of(), Collections.singletonList("BAR")))); } @Test public void readWriteTransactionReadRowUsingIndex() throws InterruptedException { - invalidateSessionPool(); - try { - TransactionRunner runner = client.readWriteTransaction(); - Struct row = - runner.run( - transaction -> - transaction.readRowUsingIndex( - "FOO", "IDX", Key.of(), Collections.singletonList("BAR"))); - assertThat(row.getLong(0)).isEqualTo(1L); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + TransactionRunner runner = client.readWriteTransaction(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + runner.run( + transaction -> + transaction.readRowUsingIndex( + "FOO", "IDX", Key.of(), Collections.singletonList("BAR")))); } @Test public void readWriteTransactionUpdate() throws InterruptedException { - invalidateSessionPool(); - try { - TransactionRunner runner = client.readWriteTransaction(); - long count = runner.run(transaction -> transaction.executeUpdate(UPDATE_STATEMENT)); - assertThat(count).isEqualTo(UPDATE_COUNT); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + TransactionRunner runner = client.readWriteTransaction(); + assertThrowsSessionNotFoundIfShouldFail( + () -> runner.run(transaction -> transaction.executeUpdate(UPDATE_STATEMENT))); } @Test public void readWriteTransactionBatchUpdate() throws InterruptedException { - invalidateSessionPool(); - try { - TransactionRunner runner = client.readWriteTransaction(); - long[] count = - runner.run( - transaction -> transaction.batchUpdate(Collections.singletonList(UPDATE_STATEMENT))); - assertThat(count.length).isEqualTo(1); - assertThat(count[0]).isEqualTo(UPDATE_COUNT); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + TransactionRunner runner = client.readWriteTransaction(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + runner.run( + transaction -> + transaction.batchUpdate(Collections.singletonList(UPDATE_STATEMENT)))); } @Test public void readWriteTransactionBuffer() throws InterruptedException { - invalidateSessionPool(); - try { - TransactionRunner runner = client.readWriteTransaction(); - runner.run( - transaction -> { - transaction.buffer(Mutation.newInsertBuilder("FOO").set("BAR").to(1L).build()); - return null; - }); - assertThat(runner.getCommitTimestamp()).isNotNull(); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + TransactionRunner runner = client.readWriteTransaction(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + runner.run( + transaction -> { + transaction.buffer(Mutation.newInsertBuilder("FOO").set("BAR").to(1L).build()); + return null; + })); } @Test public void readWriteTransactionSelectInvalidatedDuringTransaction() { - try { - TransactionRunner runner = client.readWriteTransaction(); - int attempts = - runner.run( - new TransactionCallable() { - private int attempt = 0; - - @Override - public Integer run(TransactionContext transaction) throws Exception { - attempt++; - int count = 0; + TransactionRunner runner = client.readWriteTransaction(); + final AtomicInteger attempt = new AtomicInteger(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + runner.run( + transaction -> { + attempt.incrementAndGet(); try (ResultSet rs = transaction.executeQuery(SELECT1AND2)) { - while (rs.next()) { - count++; - } + while (rs.next()) {} } - assertThat(count).isEqualTo(2); - if (attempt == 1) { - invalidateSessionPool(); + if (attempt.get() == 1) { + invalidateSessionPool( + client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); } try (ResultSet rs = transaction.executeQuery(SELECT1AND2)) { - while (rs.next()) { - count++; - } + while (rs.next()) {} } - return attempt; - } - }); - assertThat(attempts).isGreaterThan(1); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + assertThat(attempt.get()).isGreaterThan(1); + return null; + })); } @Test public void readWriteTransactionReadInvalidatedDuringTransaction() { - try { - TransactionRunner runner = client.readWriteTransaction(); - int attempts = - runner.run( - new TransactionCallable() { - private int attempt = 0; - - @Override - public Integer run(TransactionContext transaction) throws Exception { - attempt++; - int count = 0; + TransactionRunner runner = client.readWriteTransaction(); + final AtomicInteger attempt = new AtomicInteger(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + runner.run( + transaction -> { + attempt.incrementAndGet(); try (ResultSet rs = transaction.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + while (rs.next()) {} } - assertThat(count).isEqualTo(2); - if (attempt == 1) { - invalidateSessionPool(); + if (attempt.get() == 1) { + invalidateSessionPool( + client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); } try (ResultSet rs = transaction.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + while (rs.next()) {} } - return attempt; - } - }); - assertThat(attempts).isGreaterThan(1); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + assertThat(attempt.get()).isGreaterThan(1); + return null; + })); } @Test public void readWriteTransactionReadUsingIndexInvalidatedDuringTransaction() { - try { - TransactionRunner runner = client.readWriteTransaction(); - int attempts = - runner.run( - new TransactionCallable() { - private int attempt = 0; - - @Override - public Integer run(TransactionContext transaction) throws Exception { - attempt++; - int count = 0; + TransactionRunner runner = client.readWriteTransaction(); + final AtomicInteger attempt = new AtomicInteger(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + runner.run( + transaction -> { + attempt.incrementAndGet(); try (ResultSet rs = transaction.readUsingIndex( "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + while (rs.next()) {} } - assertThat(count).isEqualTo(2); - if (attempt == 1) { - invalidateSessionPool(); + if (attempt.get() == 1) { + invalidateSessionPool( + client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); } try (ResultSet rs = transaction.readUsingIndex( "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + while (rs.next()) {} } - return attempt; - } - }); - assertThat(attempts).isGreaterThan(1); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + assertThat(attempt.get()).isGreaterThan(1); + return null; + })); } @Test public void readWriteTransactionReadRowInvalidatedDuringTransaction() { - try { - TransactionRunner runner = client.readWriteTransaction(); - int attempts = - runner.run( - new TransactionCallable() { - private int attempt = 0; - - @Override - public Integer run(TransactionContext transaction) throws Exception { - attempt++; + TransactionRunner runner = client.readWriteTransaction(); + final AtomicInteger attempt = new AtomicInteger(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + runner.run( + transaction -> { + attempt.incrementAndGet(); Struct row = transaction.readRow("FOO", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0)).isEqualTo(1L); - if (attempt == 1) { - invalidateSessionPool(); + if (attempt.get() == 1) { + invalidateSessionPool( + client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); } transaction.readRow("FOO", Key.of(), Collections.singletonList("BAR")); - return attempt; - } - }); - assertThat(attempts).isGreaterThan(1); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + assertThat(attempt.get()).isGreaterThan(1); + return null; + })); } @Test public void readWriteTransactionReadRowUsingIndexInvalidatedDuringTransaction() { - try { - TransactionRunner runner = client.readWriteTransaction(); - int attempts = - runner.run( - new TransactionCallable() { - private int attempt = 0; - - @Override - public Integer run(TransactionContext transaction) throws Exception { - attempt++; + TransactionRunner runner = client.readWriteTransaction(); + final AtomicInteger attempt = new AtomicInteger(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + runner.run( + transaction -> { + attempt.incrementAndGet(); Struct row = transaction.readRowUsingIndex( "FOO", "IDX", Key.of(), Collections.singletonList("BAR")); assertThat(row.getLong(0)).isEqualTo(1L); - if (attempt == 1) { - invalidateSessionPool(); + if (attempt.get() == 1) { + invalidateSessionPool( + client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); } transaction.readRowUsingIndex( "FOO", "IDX", Key.of(), Collections.singletonList("BAR")); - return attempt; - } - }); - assertThat(attempts).isGreaterThan(1); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + assertThat(attempt.get()).isGreaterThan(1); + return null; + })); } - /** - * Test with one read-only session in the pool that is invalidated. The session pool will try to - * prepare this session for read/write, which will fail with a {@link SessionNotFoundException}. - * That again will trigger the creation of a new session. This will always succeed. - */ @SuppressWarnings("resource") @Test public void transactionManagerReadOnlySessionInPool() throws InterruptedException { - SessionPoolOptions.Builder builder = SessionPoolOptions.newBuilder(); - if (failOnInvalidatedSession) { - builder.setFailIfSessionNotFound(); - } - Spanner spanner = - SpannerOptions.newBuilder() - .setProjectId("[PROJECT]") - .setChannelProvider(channelProvider) - .setSessionPoolOption(builder.build()) - .setCredentials(NoCredentials.getInstance()) - .build() - .getService(); - DatabaseClient client = - spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); - invalidateSessionPool(client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); - int count = 0; try (TransactionManager manager = client.transactionManager()) { TransactionContext transaction = manager.begin(); while (true) { try { try (ResultSet rs = transaction.executeQuery(SELECT1AND2)) { - while (rs.next()) { - count++; - } + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } manager.commit(); break; } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); - transaction = manager.resetForRetry(); + transaction = assertThrowsSessionNotFoundIfShouldFail(() -> manager.resetForRetry()); + if (transaction == null) { + break; + } } } - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @SuppressWarnings("resource") @Test public void transactionManagerSelect() throws InterruptedException { - invalidateSessionPool(); try (TransactionManager manager = client.transactionManager()) { - int count = 0; TransactionContext transaction = manager.begin(); while (true) { try { try (ResultSet rs = transaction.executeQuery(SELECT1AND2)) { - while (rs.next()) { - count++; - } + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } manager.commit(); break; } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); - transaction = manager.resetForRetry(); + transaction = assertThrowsSessionNotFoundIfShouldFail(() -> manager.resetForRetry()); + if (transaction == null) { + break; + } } } - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @SuppressWarnings("resource") @Test public void transactionManagerRead() throws InterruptedException { - invalidateSessionPool(); try (TransactionManager manager = client.transactionManager()) { - int count = 0; TransactionContext transaction = manager.begin(); while (true) { try { try (ResultSet rs = transaction.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } manager.commit(); break; } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); - transaction = manager.resetForRetry(); + transaction = assertThrowsSessionNotFoundIfShouldFail(() -> manager.resetForRetry()); + if (transaction == null) { + break; + } } } - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @SuppressWarnings("resource") @Test public void transactionManagerReadUsingIndex() throws InterruptedException { - invalidateSessionPool(); try (TransactionManager manager = client.transactionManager()) { - int count = 0; TransactionContext transaction = manager.begin(); while (true) { try { try (ResultSet rs = transaction.readUsingIndex( "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; - } + assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()); } manager.commit(); break; } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); - transaction = manager.resetForRetry(); + transaction = assertThrowsSessionNotFoundIfShouldFail(() -> manager.resetForRetry()); + if (transaction == null) { + break; + } } } - assertThat(count).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } - @SuppressWarnings("resource") @Test public void transactionManagerReadRow() throws InterruptedException { - invalidateSessionPool(); try (TransactionManager manager = client.transactionManager()) { - Struct row; TransactionContext transaction = manager.begin(); while (true) { try { - row = transaction.readRow("FOO", Key.of(), Collections.singletonList("BAR")); + TransactionContext context = transaction; + assertThrowsSessionNotFoundIfShouldFail( + () -> context.readRow("FOO", Key.of(), Collections.singletonList("BAR"))); manager.commit(); break; } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); - transaction = manager.resetForRetry(); + transaction = assertThrowsSessionNotFoundIfShouldFail(() -> manager.resetForRetry()); + if (transaction == null) { + break; + } } } - assertThat(row.getLong(0)).isEqualTo(1L); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } - @SuppressWarnings("resource") @Test public void transactionManagerReadRowUsingIndex() throws InterruptedException { - invalidateSessionPool(); try (TransactionManager manager = client.transactionManager()) { - Struct row; TransactionContext transaction = manager.begin(); while (true) { try { - row = - transaction.readRowUsingIndex( - "FOO", "IDX", Key.of(), Collections.singletonList("BAR")); + TransactionContext context = transaction; + assertThrowsSessionNotFoundIfShouldFail( + () -> + context.readRowUsingIndex( + "FOO", "IDX", Key.of(), Collections.singletonList("BAR"))); manager.commit(); break; } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); - transaction = manager.resetForRetry(); + transaction = assertThrowsSessionNotFoundIfShouldFail(() -> manager.resetForRetry()); + if (transaction == null) { + break; + } } } - assertThat(row.getLong(0)).isEqualTo(1L); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } - @SuppressWarnings("resource") @Test public void transactionManagerUpdate() throws InterruptedException { - invalidateSessionPool(); try (TransactionManager manager = client.transactionManager(Options.commitStats())) { - long count; TransactionContext transaction = manager.begin(); while (true) { try { - count = transaction.executeUpdate(UPDATE_STATEMENT); + TransactionContext context = transaction; + assertThrowsSessionNotFoundIfShouldFail(() -> context.executeUpdate(UPDATE_STATEMENT)); manager.commit(); break; } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); - transaction = manager.resetForRetry(); + transaction = assertThrowsSessionNotFoundIfShouldFail(() -> manager.resetForRetry()); + if (transaction == null) { + break; + } } } - assertEquals(UPDATE_COUNT, count); - assertNotNull(manager.getCommitResponse().getCommitStats()); - assertFalse(failOnInvalidatedSession); - } catch (SessionNotFoundException e) { - assertTrue(failOnInvalidatedSession); } } - @SuppressWarnings("resource") @Test public void transactionManagerAborted_thenSessionNotFoundOnBeginTransaction() throws InterruptedException { int attempt = 0; try (TransactionManager manager = client.transactionManager()) { - long count; TransactionContext transaction = manager.begin(); while (true) { try { @@ -1171,55 +888,50 @@ public void transactionManagerAborted_thenSessionNotFoundOnBeginTransaction() mockSpanner.abortNextStatement(); } if (attempt == 2) { - invalidateSessionPool(); + invalidateSessionPool( + client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); } - count = transaction.executeUpdate(UPDATE_STATEMENT); + TransactionContext context = transaction; + assertThrowsSessionNotFoundIfShouldFail(() -> context.executeUpdate(UPDATE_STATEMENT)); manager.commit(); + // The actual number of attempts depends on when the transaction manager will actually get + // a valid session, as we invalidate the entire session pool. + assertThat(attempt).isAtLeast(3); break; } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); - transaction = manager.resetForRetry(); + transaction = assertThrowsSessionNotFoundIfShouldFail(() -> manager.resetForRetry()); + if (transaction == null) { + break; + } } } - assertThat(count).isEqualTo(UPDATE_COUNT); - assertThat(failOnInvalidatedSession).isFalse(); - // The actual number of attempts depends on when the transaction manager will actually get a - // valid session, as we invalidate the entire session pool. - assertThat(attempt).isAtLeast(3); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } - @SuppressWarnings("resource") @Test public void transactionManagerBatchUpdate() throws InterruptedException { - invalidateSessionPool(); try (TransactionManager manager = client.transactionManager()) { - long[] count; TransactionContext transaction = manager.begin(); while (true) { try { - count = transaction.batchUpdate(Collections.singletonList(UPDATE_STATEMENT)); + TransactionContext context = transaction; + assertThrowsSessionNotFoundIfShouldFail( + () -> context.batchUpdate(Collections.singletonList(UPDATE_STATEMENT))); manager.commit(); break; } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); - transaction = manager.resetForRetry(); + transaction = assertThrowsSessionNotFoundIfShouldFail(() -> manager.resetForRetry()); + if (transaction == null) { + break; + } } } - assertThat(count.length).isEqualTo(1); - assertThat(count[0]).isEqualTo(UPDATE_COUNT); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @SuppressWarnings("resource") @Test public void transactionManagerBuffer() throws InterruptedException { - invalidateSessionPool(); try (TransactionManager manager = client.transactionManager()) { TransactionContext transaction = manager.begin(); while (true) { @@ -1228,8 +940,10 @@ public void transactionManagerBuffer() throws InterruptedException { manager.commit(); break; } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); - transaction = manager.resetForRetry(); + transaction = assertThrowsSessionNotFoundIfShouldFail(() -> manager.resetForRetry()); + if (transaction == null) { + break; + } } } assertThat(manager.getCommitTimestamp()).isNotNull(); @@ -1242,78 +956,93 @@ public void transactionManagerBuffer() throws InterruptedException { @SuppressWarnings("resource") @Test public void transactionManagerSelectInvalidatedDuringTransaction() throws InterruptedException { - try (TransactionManager manager = client.transactionManager()) { - int attempts = 0; - TransactionContext transaction = manager.begin(); - while (true) { - attempts++; - int count = 0; - try { - try (ResultSet rs = transaction.executeQuery(SELECT1AND2)) { - while (rs.next()) { - count++; + SessionPoolOptions.Builder builder = SessionPoolOptions.newBuilder(); + if (failOnInvalidatedSession) { + builder.setFailIfSessionNotFound(); + } + try (Spanner spanner = + SpannerOptions.newBuilder() + .setProjectId("[PROJECT]") + .setChannelProvider(channelProvider) + .setSessionPoolOption(builder.build()) + .setCredentials(NoCredentials.getInstance()) + .build() + .getService()) { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); + try (TransactionManager manager = client.transactionManager()) { + int attempts = 0; + TransactionContext transaction = manager.begin(); + while (true) { + attempts++; + try { + try (ResultSet rs = transaction.executeQuery(SELECT1AND2)) { + while (rs.next()) {} } - } - assertThat(count).isEqualTo(2); - if (attempts == 1) { - invalidateSessionPool(); - } - try (ResultSet rs = transaction.executeQuery(SELECT1AND2)) { - while (rs.next()) { - count++; + if (attempts == 1) { + invalidateSessionPool( + client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); + } + try (ResultSet rs = transaction.executeQuery(SELECT1AND2)) { + if (assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()) == null) { + break; + } } + manager.commit(); + assertThat(attempts).isGreaterThan(1); + break; + } catch (AbortedException e) { + transaction = assertThrowsSessionNotFoundIfShouldFail(() -> manager.resetForRetry()); } - manager.commit(); - break; - } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); - transaction = manager.resetForRetry(); } } - assertThat(attempts).isGreaterThan(1); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @SuppressWarnings("resource") @Test public void transactionManagerReadInvalidatedDuringTransaction() throws InterruptedException { - try (TransactionManager manager = client.transactionManager()) { - int attempts = 0; - TransactionContext transaction = manager.begin(); - while (true) { - attempts++; - int count = 0; - try { - try (ResultSet rs = - transaction.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; + SessionPoolOptions.Builder builder = SessionPoolOptions.newBuilder(); + if (failOnInvalidatedSession) { + builder.setFailIfSessionNotFound(); + } + try (Spanner spanner = + SpannerOptions.newBuilder() + .setProjectId("[PROJECT]") + .setChannelProvider(channelProvider) + .setSessionPoolOption(builder.build()) + .setCredentials(NoCredentials.getInstance()) + .build() + .getService()) { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); + try (TransactionManager manager = client.transactionManager()) { + int attempts = 0; + TransactionContext transaction = manager.begin(); + while (true) { + attempts++; + try { + try (ResultSet rs = + transaction.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { + while (rs.next()) {} } - } - assertThat(count).isEqualTo(2); - if (attempts == 1) { - invalidateSessionPool(); - } - try (ResultSet rs = - transaction.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; + if (attempts == 1) { + invalidateSessionPool( + client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); + } + try (ResultSet rs = + transaction.read("FOO", KeySet.all(), Collections.singletonList("BAR"))) { + if (assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()) == null) { + break; + } } + manager.commit(); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); } - manager.commit(); - break; - } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); - transaction = manager.resetForRetry(); } } - assertThat(attempts).isGreaterThan(1); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @@ -1321,71 +1050,94 @@ public void transactionManagerReadInvalidatedDuringTransaction() throws Interrup @Test public void transactionManagerReadUsingIndexInvalidatedDuringTransaction() throws InterruptedException { - try (TransactionManager manager = client.transactionManager()) { - int attempts = 0; - TransactionContext transaction = manager.begin(); - while (true) { - attempts++; - int count = 0; - try { - try (ResultSet rs = - transaction.readUsingIndex( - "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; + SessionPoolOptions.Builder builder = SessionPoolOptions.newBuilder(); + if (failOnInvalidatedSession) { + builder.setFailIfSessionNotFound(); + } + try (Spanner spanner = + SpannerOptions.newBuilder() + .setProjectId("[PROJECT]") + .setChannelProvider(channelProvider) + .setSessionPoolOption(builder.build()) + .setCredentials(NoCredentials.getInstance()) + .build() + .getService()) { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); + try (TransactionManager manager = client.transactionManager()) { + int attempts = 0; + TransactionContext transaction = manager.begin(); + while (true) { + attempts++; + try { + try (ResultSet rs = + transaction.readUsingIndex( + "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { + while (rs.next()) {} } - } - assertThat(count).isEqualTo(2); - if (attempts == 1) { - invalidateSessionPool(); - } - try (ResultSet rs = - transaction.readUsingIndex( - "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { - while (rs.next()) { - count++; + if (attempts == 1) { + invalidateSessionPool( + client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); + } + try (ResultSet rs = + transaction.readUsingIndex( + "FOO", "IDX", KeySet.all(), Collections.singletonList("BAR"))) { + if (assertThrowsSessionNotFoundIfShouldFail(() -> rs.next()) == null) { + break; + } } + manager.commit(); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); } - manager.commit(); - break; - } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); - transaction = manager.resetForRetry(); } } - assertThat(attempts).isGreaterThan(1); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @SuppressWarnings("resource") @Test public void transactionManagerReadRowInvalidatedDuringTransaction() throws InterruptedException { - try (TransactionManager manager = client.transactionManager()) { - int attempts = 0; - TransactionContext transaction = manager.begin(); - while (true) { - attempts++; - try { - Struct row = transaction.readRow("FOO", Key.of(), Collections.singletonList("BAR")); - assertThat(row.getLong(0)).isEqualTo(1L); - if (attempts == 1) { - invalidateSessionPool(); + SessionPoolOptions.Builder builder = SessionPoolOptions.newBuilder(); + if (failOnInvalidatedSession) { + builder.setFailIfSessionNotFound(); + } + try (Spanner spanner = + SpannerOptions.newBuilder() + .setProjectId("[PROJECT]") + .setChannelProvider(channelProvider) + .setSessionPoolOption(builder.build()) + .setCredentials(NoCredentials.getInstance()) + .build() + .getService()) { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); + try (TransactionManager manager = client.transactionManager()) { + int attempts = 0; + TransactionContext transaction = manager.begin(); + while (true) { + attempts++; + try { + Struct row = transaction.readRow("FOO", Key.of(), Collections.singletonList("BAR")); + assertThat(row.getLong(0)).isEqualTo(1L); + if (attempts == 1) { + invalidateSessionPool( + client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); + } + TransactionContext context = transaction; + if (assertThrowsSessionNotFoundIfShouldFail( + () -> context.readRow("FOO", Key.of(), Collections.singletonList("BAR"))) + == null) { + break; + } + manager.commit(); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); } - transaction.readRow("FOO", Key.of(), Collections.singletonList("BAR")); - manager.commit(); - break; - } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); - transaction = manager.resetForRetry(); } } - assertThat(attempts).isGreaterThan(1); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @@ -1393,69 +1145,70 @@ public void transactionManagerReadRowInvalidatedDuringTransaction() throws Inter @Test public void transactionManagerReadRowUsingIndexInvalidatedDuringTransaction() throws InterruptedException { - try (TransactionManager manager = client.transactionManager()) { - int attempts = 0; - TransactionContext transaction = manager.begin(); - while (true) { - attempts++; - try { - Struct row = - transaction.readRowUsingIndex( - "FOO", "IDX", Key.of(), Collections.singletonList("BAR")); - assertThat(row.getLong(0)).isEqualTo(1L); - if (attempts == 1) { - invalidateSessionPool(); + SessionPoolOptions.Builder builder = SessionPoolOptions.newBuilder(); + if (failOnInvalidatedSession) { + builder.setFailIfSessionNotFound(); + } + try (Spanner spanner = + SpannerOptions.newBuilder() + .setProjectId("[PROJECT]") + .setChannelProvider(channelProvider) + .setSessionPoolOption(builder.build()) + .setCredentials(NoCredentials.getInstance()) + .build() + .getService()) { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); + try (TransactionManager manager = client.transactionManager()) { + int attempts = 0; + TransactionContext transaction = manager.begin(); + while (true) { + attempts++; + try { + Struct row = + transaction.readRowUsingIndex( + "FOO", "IDX", Key.of(), Collections.singletonList("BAR")); + assertThat(row.getLong(0)).isEqualTo(1L); + if (attempts == 1) { + invalidateSessionPool( + client, spanner.getOptions().getSessionPoolOptions().getMinSessions()); + } + TransactionContext context = transaction; + if (assertThrowsSessionNotFoundIfShouldFail( + () -> + context.readRowUsingIndex( + "FOO", "IDX", Key.of(), Collections.singletonList("BAR"))) + == null) { + break; + } + manager.commit(); + break; + } catch (AbortedException e) { + transaction = manager.resetForRetry(); } - transaction.readRowUsingIndex("FOO", "IDX", Key.of(), Collections.singletonList("BAR")); - manager.commit(); - break; - } catch (AbortedException e) { - Thread.sleep(e.getRetryDelayInMillis()); - transaction = manager.resetForRetry(); } } - assertThat(attempts).isGreaterThan(1); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } @Test public void partitionedDml() throws InterruptedException { - invalidateSessionPool(); - try { - assertThat(client.executePartitionedUpdate(UPDATE_STATEMENT)).isEqualTo(UPDATE_COUNT); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + assertThrowsSessionNotFoundIfShouldFail( + () -> client.executePartitionedUpdate(UPDATE_STATEMENT)); } @Test public void write() throws InterruptedException { - invalidateSessionPool(); - try { - Timestamp timestamp = - client.write(Collections.singletonList(Mutation.delete("FOO", KeySet.all()))); - assertThat(timestamp).isNotNull(); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + assertThrowsSessionNotFoundIfShouldFail( + () -> client.write(Collections.singletonList(Mutation.delete("FOO", KeySet.all())))); } @Test public void writeAtLeastOnce() throws InterruptedException { - invalidateSessionPool(); - try { - Timestamp timestamp = - client.writeAtLeastOnce(Collections.singletonList(Mutation.delete("FOO", KeySet.all()))); - assertThat(timestamp).isNotNull(); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + assertThrowsSessionNotFoundIfShouldFail( + () -> + client.writeAtLeastOnce( + Collections.singletonList(Mutation.delete("FOO", KeySet.all())))); } @Test @@ -1479,39 +1232,36 @@ public void asyncRunnerReadUsingIndex() throws InterruptedException { private void asyncRunner_withReadFunction( final Function readFunction) throws InterruptedException { - invalidateSessionPool(); final ExecutorService queryExecutor = Executors.newSingleThreadExecutor(); try { AsyncRunner runner = client.runAsync(); final AtomicLong counter = new AtomicLong(); - ApiFuture count = - runner.runAsync( - txn -> { - AsyncResultSet rs = readFunction.apply(txn); - ApiFuture fut = - rs.setCallback( - queryExecutor, - resultSet -> { - while (true) { - switch (resultSet.tryNext()) { - case OK: - counter.incrementAndGet(); - break; - case DONE: - return CallbackResponse.DONE; - case NOT_READY: - return CallbackResponse.CONTINUE; - } - } - }); - return ApiFutures.transform( - fut, input -> counter.get(), MoreExecutors.directExecutor()); - }, - executor); - assertThat(get(count)).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + get( + runner.runAsync( + txn -> { + AsyncResultSet rs = readFunction.apply(txn); + ApiFuture fut = + rs.setCallback( + queryExecutor, + resultSet -> { + while (true) { + switch (resultSet.tryNext()) { + case OK: + counter.incrementAndGet(); + break; + case DONE: + return CallbackResponse.DONE; + case NOT_READY: + return CallbackResponse.CONTINUE; + } + } + }); + return ApiFutures.transform( + fut, input -> counter.get(), MoreExecutors.directExecutor()); + }, + executor))); } finally { queryExecutor.shutdown(); } @@ -1519,86 +1269,58 @@ private void asyncRunner_withReadFunction( @Test public void asyncRunnerReadRow() throws InterruptedException { - invalidateSessionPool(); - try { - AsyncRunner runner = client.runAsync(); - ApiFuture row = - runner.runAsync( - txn -> txn.readRowAsync("FOO", Key.of(), Collections.singletonList("BAR")), executor); - assertThat(get(row).getLong(0)).isEqualTo(1L); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + AsyncRunner runner = client.runAsync(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + get( + runner.runAsync( + txn -> txn.readRowAsync("FOO", Key.of(), Collections.singletonList("BAR")), + executor))); } @Test public void asyncRunnerReadRowUsingIndex() throws InterruptedException { - invalidateSessionPool(); - try { - AsyncRunner runner = client.runAsync(); - ApiFuture row = - runner.runAsync( - txn -> - txn.readRowUsingIndexAsync( - "FOO", "IDX", Key.of(), Collections.singletonList("BAR")), - executor); - assertThat(get(row).getLong(0)).isEqualTo(1L); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + AsyncRunner runner = client.runAsync(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + get( + runner.runAsync( + txn -> + txn.readRowUsingIndexAsync( + "FOO", "IDX", Key.of(), Collections.singletonList("BAR")), + executor))); } @Test public void asyncRunnerUpdate() throws InterruptedException { - invalidateSessionPool(); - try { - AsyncRunner runner = client.runAsync(); - ApiFuture count = - runner.runAsync(txn -> txn.executeUpdateAsync(UPDATE_STATEMENT), executor); - assertThat(get(count)).isEqualTo(UPDATE_COUNT); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + AsyncRunner runner = client.runAsync(); + assertThrowsSessionNotFoundIfShouldFail( + () -> get(runner.runAsync(txn -> txn.executeUpdateAsync(UPDATE_STATEMENT), executor))); } @Test public void asyncRunnerBatchUpdate() throws InterruptedException { - invalidateSessionPool(); - try { - AsyncRunner runner = client.runAsync(); - ApiFuture count = - runner.runAsync( - txn -> txn.batchUpdateAsync(Arrays.asList(UPDATE_STATEMENT, UPDATE_STATEMENT)), - executor); - assertThat(get(count)).hasLength(2); - assertThat(get(count)).asList().containsExactly(UPDATE_COUNT, UPDATE_COUNT); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + AsyncRunner runner = client.runAsync(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + get( + runner.runAsync( + txn -> txn.batchUpdateAsync(Arrays.asList(UPDATE_STATEMENT, UPDATE_STATEMENT)), + executor))); } @Test public void asyncRunnerBuffer() throws InterruptedException { - invalidateSessionPool(); - try { - AsyncRunner runner = client.runAsync(); - ApiFuture res = - runner.runAsync( - txn -> { - txn.buffer(Mutation.newInsertBuilder("FOO").set("BAR").to(1L).build()); - return ApiFutures.immediateFuture(null); - }, - executor); - assertThat(get(res)).isNull(); - assertThat(get(runner.getCommitTimestamp())).isNotNull(); - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); - } + AsyncRunner runner = client.runAsync(); + assertThrowsSessionNotFoundIfShouldFail( + () -> + get( + runner.runAsync( + txn -> { + txn.buffer(Mutation.newInsertBuilder("FOO").set("BAR").to(1L).build()); + return ApiFutures.immediateFuture(null); + }, + executor))); } @Test @@ -1622,7 +1344,6 @@ public void asyncTransactionManagerAsyncReadUsingIndex() throws InterruptedExcep private void asyncTransactionManager_readAsync( final Function fn) throws InterruptedException { - invalidateSessionPool(); final ExecutorService queryExecutor = Executors.newSingleThreadExecutor(); try (AsyncTransactionManager manager = client.transactionManagerAsync()) { TransactionContextFuture context = manager.beginAsync(); @@ -1654,16 +1375,12 @@ private void asyncTransactionManager_readAsync( }, executor); CommitTimestampFuture ts = count.commitAsync(); - assertThat(get(ts)).isNotNull(); - assertThat(get(count)).isEqualTo(2); - assertThat(failOnInvalidatedSession).isFalse(); + assertThrowsSessionNotFoundIfShouldFail(() -> get(ts)); break; } catch (AbortedException e) { context = manager.resetForRetryAsync(); } } - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } finally { queryExecutor.shutdown(); } @@ -1689,7 +1406,6 @@ public void asyncTransactionManagerReadUsingIndex() throws InterruptedException private void asyncTransactionManager_readSync(final Function fn) throws InterruptedException { - invalidateSessionPool(); final ExecutorService queryExecutor = Executors.newSingleThreadExecutor(); try (AsyncTransactionManager manager = client.transactionManagerAsync()) { TransactionContextFuture context = manager.beginAsync(); @@ -1708,16 +1424,12 @@ private void asyncTransactionManager_readSync(final Function get(ts)); break; } catch (AbortedException e) { context = manager.resetForRetryAsync(); } } - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } finally { queryExecutor.shutdown(); } @@ -1756,7 +1468,6 @@ public void asyncTransactionManagerReadRowUsingIndexAsync() throws InterruptedEx private void asyncTransactionManager_readRowFunction( final Function> fn) throws InterruptedException { - invalidateSessionPool(); final ExecutorService queryExecutor = Executors.newSingleThreadExecutor(); try (AsyncTransactionManager manager = client.transactionManagerAsync()) { TransactionContextFuture context = manager.beginAsync(); @@ -1765,16 +1476,12 @@ private void asyncTransactionManager_readRowFunction( AsyncTransactionStep row = context.then((transaction, ignored) -> fn.apply(transaction), executor); CommitTimestampFuture ts = row.commitAsync(); - assertThat(get(ts)).isNotNull(); - assertThat(get(row)).isEqualTo(Struct.newBuilder().set("BAR").to(1L).build()); - assertThat(failOnInvalidatedSession).isFalse(); + assertThrowsSessionNotFoundIfShouldFail(() -> get(ts)); break; } catch (AbortedException e) { context = manager.resetForRetryAsync(); } } - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } finally { queryExecutor.shutdown(); } @@ -1810,7 +1517,6 @@ public void asyncTransactionManagerBatchUpdate() throws InterruptedException { private void asyncTransactionManager_updateFunction( final Function> fn, T expected) throws InterruptedException { - invalidateSessionPool(); try (AsyncTransactionManager manager = client.transactionManagerAsync()) { TransactionContextFuture transaction = manager.beginAsync(); while (true) { @@ -1818,16 +1524,12 @@ private void asyncTransactionManager_updateFunction( AsyncTransactionStep res = transaction.then((txn, input) -> fn.apply(txn), executor); CommitTimestampFuture ts = res.commitAsync(); - assertThat(get(res)).isEqualTo(expected); - assertThat(get(ts)).isNotNull(); + assertThrowsSessionNotFoundIfShouldFail(() -> get(ts)); break; } catch (AbortedException e) { transaction = manager.resetForRetryAsync(); } } - assertThat(failOnInvalidatedSession).isFalse(); - } catch (SessionNotFoundException e) { - assertThat(failOnInvalidatedSession).isTrue(); } } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerGaxRetryTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerGaxRetryTest.java index 5dfde3503ac..ad45f9039a3 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerGaxRetryTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerGaxRetryTest.java @@ -130,8 +130,7 @@ public void setUp() throws Exception { .setChannelProvider(channelProvider) .setCredentials(NoCredentials.getInstance()); // Make sure the session pool is empty by default. - builder.setSessionPoolOption( - SessionPoolOptions.newBuilder().setMinSessions(0).setWriteSessionsFraction(0.0f).build()); + builder.setSessionPoolOption(SessionPoolOptions.newBuilder().setMinSessions(0).build()); // Create one client with default timeout values and one with short timeout values specifically // for the test cases that expect a DEADLINE_EXCEEDED. spanner = builder.build().getService(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractMockServerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractMockServerTest.java index 154384e2e5b..6cf838845b5 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractMockServerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractMockServerTest.java @@ -53,7 +53,6 @@ import java.util.List; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; -import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -113,10 +112,10 @@ public abstract class AbstractMockServerTest { private static Server server; private static InetSocketAddress address; - private boolean futureParentHandlers; - private boolean exceptionRunnableParentHandlers; - private boolean nettyServerParentHandlers; - private boolean clientStreamParentHandlers; + private static boolean futureParentHandlers; + private static boolean exceptionRunnableParentHandlers; + private static boolean nettyServerParentHandlers; + private static boolean clientStreamParentHandlers; @BeforeClass public static void startStaticServer() throws IOException { @@ -152,18 +151,6 @@ public void getOperation( mockSpanner.putStatementResult(StatementResult.update(INSERT_STATEMENT, UPDATE_COUNT)); mockSpanner.putStatementResult( StatementResult.query(SELECT_RANDOM_STATEMENT, RANDOM_RESULT_SET)); - } - - @AfterClass - public static void stopServer() { - server.shutdown(); - } - - @Before - public void setupResults() { - mockSpanner.reset(); - mockDatabaseAdmin.reset(); - mockInstanceAdmin.reset(); futureParentHandlers = Logger.getLogger(AbstractFuture.class.getName()).getUseParentHandlers(); exceptionRunnableParentHandlers = @@ -181,8 +168,8 @@ public void setupResults() { Logger.getLogger("io.grpc.internal.AbstractClientStream").setUseParentHandlers(false); } - @After - public void closeSpannerPool() { + @AfterClass + public static void stopServer() { try { SpannerPool.INSTANCE.checkAndCloseSpanners( CheckAndCloseSpannersMode.ERROR, @@ -196,6 +183,14 @@ public void closeSpannerPool() { Logger.getLogger("io.grpc.internal.AbstractClientStream") .setUseParentHandlers(clientStreamParentHandlers); } + server.shutdown(); + } + + @Before + public void setupResults() { + mockSpanner.clearRequests(); + mockDatabaseAdmin.getRequests().clear(); + mockInstanceAdmin.getRequests().clear(); } protected java.sql.Connection createJdbcConnection() throws SQLException { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractSqlScriptVerifier.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractSqlScriptVerifier.java index 2eb3087089b..f247b2d6306 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractSqlScriptVerifier.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractSqlScriptVerifier.java @@ -28,6 +28,7 @@ import com.google.cloud.Timestamp; import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.SpannerException; +import com.google.cloud.spanner.SpannerExceptionFactory; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -38,6 +39,7 @@ import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Stream; /** * Base class for SQL Script verifiers for both the generic Connection API and JDBC connections @@ -180,8 +182,6 @@ public static List readStatementsFromFile(String filename, Class reso private final GenericConnectionProvider connectionProvider; - private final Map variables = new HashMap<>(); - private final boolean logStatements; /** @@ -212,9 +212,12 @@ public AbstractSqlScriptVerifier(GenericConnectionProvider provider) { * semicolon (;) * @param resourceClass The class that should be used to locate the resource specified by the file * name + * @param allowParallel indicates whether the batches in the given script may be executed in + * parallel */ - public void verifyStatementsInFile(String filename, Class resourceClass) throws Exception { - verifyStatementsInFile(connectionProvider.getConnection(), filename, resourceClass); + public void verifyStatementsInFile(String filename, Class resourceClass, boolean allowParallel) + throws Exception { + verifyStatementsInFile(null, filename, resourceClass, allowParallel); } /** @@ -223,42 +226,80 @@ public void verifyStatementsInFile(String filename, Class resourceClass) thro * Statements without an @EXPECT statement will be executed and its result will be ignored, unless * the statement throws an exception, which will fail the test case. * - * @param connection The {@link com.google.cloud.spanner.jdbc.Connection} to execute the + * @param providedConnection The {@link com.google.cloud.spanner.jdbc.Connection} to execute the * statements against * @param filename The file name containing the statements. Statements must be separated by a * semicolon (;) * @param resourceClass The class that defines the package where to find the input file + * @param allowParallel indicates whether the batches in the given script may be executed in + * parallel */ public void verifyStatementsInFile( - GenericConnection connection, String filename, Class resourceClass) throws Exception { - try { - List statements = readStatementsFromFile(filename, resourceClass); - for (String statement : statements) { - String sql = statement.trim(); - if (logStatements) { - System.out.println( - "\n------------------------------------------------------\n" - + new Date() - + " ---- verifying statement:"); - System.out.println(sql); - } - if (sql.equalsIgnoreCase("NEW_CONNECTION")) { - connection.close(); - connection = connectionProvider.getConnection(); - variables.clear(); - } else { - verifyStatement(connection, sql); + GenericConnection providedConnection, + String filename, + Class resourceClass, + boolean allowParallel) + throws Exception { + List statements = readStatementsFromFile(filename, resourceClass); + List> batches = toBatches(statements); + + Stream> stream; + if (!allowParallel || logStatements) { + stream = batches.stream(); + } else { + stream = batches.parallelStream(); + } + stream.forEach( + batch -> { + try { + Map variables = new HashMap<>(); + GenericConnection connection; + if (providedConnection == null) { + connection = connectionProvider.getConnection(); + } else { + connection = providedConnection; + } + for (String sql : batch) { + if (logStatements) { + System.out.println( + "\n------------------------------------------------------\n" + + new Date() + + " ---- verifying statement:"); + System.out.println(sql); + } + verifyStatement(variables, connection, sql); + } + connection.close(); + } catch (Exception e) { + throw SpannerExceptionFactory.asSpannerException(e); + } + }); + } + + private List> toBatches(List statements) { + List> batches = new ArrayList<>(); + List currentBatch = new ArrayList<>(); + for (String statement : statements) { + String sql = statement.trim(); + if (sql.equalsIgnoreCase("NEW_CONNECTION")) { + if (!currentBatch.isEmpty()) { + batches.add(currentBatch); } - } - } finally { - if (connection != null) { - connection.close(); + currentBatch = new ArrayList<>(); + } else { + currentBatch.add(sql); } } + if (!currentBatch.isEmpty()) { + batches.add(currentBatch); + } + return batches; } - private void verifyStatement(GenericConnection connection, String statement) throws Exception { - statement = replaceVariables(statement); + private void verifyStatement( + Map variables, GenericConnection connection, String statement) + throws Exception { + statement = replaceVariables(variables, statement); String statementWithoutComments = StatementParser.removeCommentsAndTrim(statement); Matcher verifyMatcher = VERIFY_PATTERN.matcher(statementWithoutComments); Matcher putMatcher = PUT_PATTERN.matcher(statementWithoutComments); @@ -350,7 +391,7 @@ private void verifyStatement(GenericConnection connection, String statement) thr } } - private String replaceVariables(String sql) { + private String replaceVariables(Map variables, String sql) { for (String key : variables.keySet()) { sql = sql.replaceAll("%%" + key + "%%", variables.get(key).toString()); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ClientSideStatementsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ClientSideStatementsTest.java index b36da9c7ac6..eab14248149 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ClientSideStatementsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ClientSideStatementsTest.java @@ -49,7 +49,7 @@ public class ClientSideStatementsTest { @Test public void testExecuteClientSideStatementsScript() throws Exception { SqlScriptVerifier verifier = new SqlScriptVerifier(new TestConnectionProvider()); - verifier.verifyStatementsInFile("ClientSideStatementsTest.sql", getClass()); + verifier.verifyStatementsInFile("ClientSideStatementsTest.sql", getClass(), true); } private static final String SCRIPT_FILE = diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionAsyncApiTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionAsyncApiTest.java index ca16259f68b..ff409e88c63 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionAsyncApiTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionAsyncApiTest.java @@ -18,6 +18,9 @@ import static com.google.cloud.spanner.SpannerApiFutures.get; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; import com.google.api.core.ApiFuture; @@ -26,18 +29,21 @@ import com.google.cloud.spanner.AsyncResultSet.CallbackResponse; import com.google.cloud.spanner.AsyncResultSet.ReadyCallback; import com.google.cloud.spanner.ErrorCode; +import com.google.cloud.spanner.ForceCloseSpannerFunction; import com.google.cloud.spanner.MockSpannerServiceImpl.SimulatedExecutionTime; import com.google.cloud.spanner.Mutation; import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.SpannerApiFutures; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.connection.SpannerPool.CheckAndCloseSpannersMode; import com.google.cloud.spanner.connection.StatementResult.ResultType; import com.google.common.base.Function; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.protobuf.AbstractMessage; +import com.google.spanner.v1.CommitRequest; import com.google.spanner.v1.ExecuteBatchDmlRequest; import com.google.spanner.v1.ExecuteSqlRequest; import java.util.List; @@ -54,7 +60,7 @@ @RunWith(JUnit4.class) public class ConnectionAsyncApiTest extends AbstractMockServerTest { - private static final ExecutorService executor = Executors.newSingleThreadExecutor(); + private static ExecutorService executor = Executors.newSingleThreadExecutor(); private static final Function AUTOCOMMIT = input -> { input.setAutocommit(true); @@ -75,6 +81,8 @@ public static void stopExecutor() { @After public void reset() { mockSpanner.removeAllExecutionTimes(); + executor.shutdownNow(); + executor = Executors.newSingleThreadExecutor(); } @Test @@ -258,20 +266,32 @@ public CallbackResponse cursorReady(AsyncResultSet resultSet) { } }); } - connection.commitAsync(); + ApiFuture commit = connection.commitAsync(); assertThat(get(update1)).isEqualTo(UPDATE_COUNT); assertThat(get(update2)).isEqualTo(UPDATE_COUNT); assertThat(get(batch)).asList().containsExactly(1L, 1L); assertThat(get(rowCount)).isEqualTo(RANDOM_RESULT_SET_ROW_COUNT); + assertNull(get(commit)); + // Get the last commit request. + CommitRequest commitRequest = + mockSpanner.getRequestsOfType(CommitRequest.class).stream() + .reduce((first, second) -> second) + .get(); // Verify the order of the statements on the server. List requests = Lists.newArrayList( Collections2.filter( mockSpanner.getRequests(), input -> - input instanceof ExecuteSqlRequest - || input instanceof ExecuteBatchDmlRequest)); + (input instanceof ExecuteSqlRequest + && ((ExecuteSqlRequest) input) + .getSession() + .equals(commitRequest.getSession())) + || (input instanceof ExecuteBatchDmlRequest + && ((ExecuteBatchDmlRequest) input) + .getSession() + .equals(commitRequest.getSession())))); assertThat(requests).hasSize(4); assertThat(requests.get(0)).isInstanceOf(ExecuteSqlRequest.class); assertThat(((ExecuteSqlRequest) requests.get(0)).getSeqno()).isEqualTo(1L); @@ -326,12 +346,13 @@ public void testExecuteDdlAsync() { @Test public void testExecuteInvalidStatementAsync() { try (Connection connection = createConnection()) { - try { - connection.executeAsync(Statement.of("UPSERT INTO FOO (ID, VAL) VALUES (1, 'foo')")); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - } + SpannerException e = + assertThrows( + SpannerException.class, + () -> + connection.executeAsync( + Statement.of("UPSERT INTO FOO (ID, VAL) VALUES (1, 'foo')"))); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); } } @@ -657,6 +678,10 @@ private void testExecuteBatchUpdate(Function connectionConfigu } } } + // Close the Spanner pool to prevent requests from this test from interfering with other tests. + SpannerPool.INSTANCE.checkAndCloseSpanners( + CheckAndCloseSpannersMode.ERROR, + new ForceCloseSpannerFunction(100L, TimeUnit.MILLISECONDS)); } private void testWriteAsync(Function connectionConfigurator) { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplGeneratedSqlScriptTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplGeneratedSqlScriptTest.java index 90dc3ad9bbc..bfa023c1ddc 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplGeneratedSqlScriptTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplGeneratedSqlScriptTest.java @@ -63,7 +63,7 @@ public GenericConnection getConnection() { @Test public void testGeneratedScript() throws Exception { SqlScriptVerifier verifier = new SqlScriptVerifier(new TestConnectionProvider()); - verifier.verifyStatementsInFile("ConnectionImplGeneratedSqlScriptTest.sql", getClass()); + verifier.verifyStatementsInFile("ConnectionImplGeneratedSqlScriptTest.sql", getClass(), true); } /** diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetReadOnlyStalenessSqlScriptTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetReadOnlyStalenessSqlScriptTest.java index a317630ebd0..25aad948fee 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetReadOnlyStalenessSqlScriptTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetReadOnlyStalenessSqlScriptTest.java @@ -42,6 +42,6 @@ public GenericConnection getConnection() { @Test public void testSetReadOnlyStalenessScript() throws Exception { SqlScriptVerifier verifier = new SqlScriptVerifier(new TestConnectionProvider()); - verifier.verifyStatementsInFile("SetReadOnlyStalenessTest.sql", getClass()); + verifier.verifyStatementsInFile("SetReadOnlyStalenessTest.sql", getClass(), true); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetStatementTimeoutSqlScriptTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetStatementTimeoutSqlScriptTest.java index ea70384d96f..c47fde41c17 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetStatementTimeoutSqlScriptTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetStatementTimeoutSqlScriptTest.java @@ -42,6 +42,6 @@ public GenericConnection getConnection() { @Test public void testSetStatementTimeoutScript() throws Exception { SqlScriptVerifier verifier = new SqlScriptVerifier(new TestConnectionProvider()); - verifier.verifyStatementsInFile("SetStatementTimeoutTest.sql", getClass()); + verifier.verifyStatementsInFile("SetStatementTimeoutTest.sql", getClass(), true); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementTimeoutTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementTimeoutTest.java index 87fde11f9bb..08f47c0c5d4 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementTimeoutTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementTimeoutTest.java @@ -18,11 +18,13 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; +import com.google.api.core.SettableApiFuture; import com.google.api.gax.longrunning.OperationTimedPollAlgorithm; import com.google.api.gax.retrying.RetrySettings; import com.google.cloud.spanner.ErrorCode; @@ -33,12 +35,14 @@ import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.connection.AbstractConnectionImplTest.ConnectionConsumer; import com.google.cloud.spanner.connection.ITAbstractSpannerTest.ITConnection; -import com.google.common.util.concurrent.Uninterruptibles; +import com.google.common.base.Stopwatch; +import com.google.common.collect.Collections2; import com.google.longrunning.Operation; import com.google.protobuf.AbstractMessage; import com.google.protobuf.Any; import com.google.protobuf.Empty; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; +import com.google.spanner.admin.database.v1.UpdateDatabaseDdlRequest; import com.google.spanner.v1.CommitRequest; import com.google.spanner.v1.ExecuteSqlRequest; import io.grpc.Status; @@ -115,12 +119,10 @@ public void testTimeoutExceptionReadOnlyAutocommit() { connection.setAutocommit(true); connection.setReadOnly(true); connection.setStatementTimeout(TIMEOUT_FOR_SLOW_STATEMENTS, TimeUnit.MILLISECONDS); - try { - connection.executeQuery(SELECT_RANDOM_STATEMENT); - fail("missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, ex.getErrorCode()); - } + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(SELECT_RANDOM_STATEMENT)); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } @@ -135,18 +137,16 @@ public void testTimeoutExceptionReadOnlyAutocommitMultipleStatements() { connection.setStatementTimeout(TIMEOUT_FOR_SLOW_STATEMENTS, TimeUnit.MILLISECONDS); // assert that multiple statements after each other also time out for (int i = 0; i < 2; i++) { - try { - connection.executeQuery(SELECT_RANDOM_STATEMENT); - fail("missing expected exception"); - } catch (SpannerException e) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); - } + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(SELECT_RANDOM_STATEMENT)); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } // try to do a new query that is fast. mockSpanner.removeAllExecutionTimes(); connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { - assertThat(rs, is(notNullValue())); + assertNotNull(rs); } } } @@ -160,12 +160,10 @@ public void testTimeoutExceptionReadOnlyTransactional() { connection.setReadOnly(true); connection.setAutocommit(false); connection.setStatementTimeout(TIMEOUT_FOR_SLOW_STATEMENTS, TimeUnit.MILLISECONDS); - try { - connection.executeQuery(SELECT_RANDOM_STATEMENT); - fail("missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, ex.getErrorCode()); - } + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(SELECT_RANDOM_STATEMENT)); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } @@ -180,12 +178,10 @@ public void testTimeoutExceptionReadOnlyTransactionMultipleStatements() { connection.setStatementTimeout(TIMEOUT_FOR_SLOW_STATEMENTS, TimeUnit.MILLISECONDS); // assert that multiple statements after each other also time out for (int i = 0; i < 2; i++) { - try { - connection.executeQuery(SELECT_RANDOM_STATEMENT); - fail("missing expected exception"); - } catch (SpannerException e) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); - } + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(SELECT_RANDOM_STATEMENT)); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } // do a rollback without any chance of a timeout connection.clearStatementTimeout(); @@ -194,7 +190,7 @@ public void testTimeoutExceptionReadOnlyTransactionMultipleStatements() { mockSpanner.removeAllExecutionTimes(); connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { - assertThat(rs, is(notNullValue())); + assertNotNull(rs); } } } @@ -207,12 +203,10 @@ public void testTimeoutExceptionReadWriteAutocommit() { try (Connection connection = createConnection()) { connection.setAutocommit(true); connection.setStatementTimeout(TIMEOUT_FOR_SLOW_STATEMENTS, TimeUnit.MILLISECONDS); - try { - connection.executeQuery(SELECT_RANDOM_STATEMENT); - fail("missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, ex.getErrorCode()); - } + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(SELECT_RANDOM_STATEMENT)); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } @@ -226,18 +220,16 @@ public void testTimeoutExceptionReadWriteAutocommitMultipleStatements() { connection.setStatementTimeout(TIMEOUT_FOR_SLOW_STATEMENTS, TimeUnit.MILLISECONDS); // assert that multiple statements after each other also time out for (int i = 0; i < 2; i++) { - try { - connection.executeQuery(SELECT_RANDOM_STATEMENT); - fail("missing expected exception"); - } catch (SpannerException e) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); - } + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(SELECT_RANDOM_STATEMENT)); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } // try to do a new query that is fast. mockSpanner.removeAllExecutionTimes(); connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { - assertThat(rs, is(notNullValue())); + assertNotNull(rs); } } } @@ -250,12 +242,9 @@ public void testTimeoutExceptionReadWriteAutocommitSlowUpdate() { try (Connection connection = createConnection()) { connection.setAutocommit(true); connection.setStatementTimeout(TIMEOUT_FOR_SLOW_STATEMENTS, TimeUnit.MILLISECONDS); - try { - connection.execute(INSERT_STATEMENT); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, ex.getErrorCode()); - } + SpannerException e = + assertThrows(SpannerException.class, () -> connection.execute(INSERT_STATEMENT)); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } @@ -270,17 +259,15 @@ public void testTimeoutExceptionReadWriteAutocommitSlowUpdateMultipleStatements( // assert that multiple statements after each other also time out for (int i = 0; i < 2; i++) { - try { - connection.execute(Statement.of(SLOW_UPDATE)); - fail("missing expected exception"); - } catch (SpannerException e) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); - } + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.execute(Statement.of(SLOW_UPDATE))); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } // try to do a new update that is fast. mockSpanner.removeAllExecutionTimes(); connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); - assertThat(connection.execute(INSERT_STATEMENT).getUpdateCount(), is(equalTo(UPDATE_COUNT))); + assertEquals(UPDATE_COUNT, connection.execute(INSERT_STATEMENT).getUpdateCount().longValue()); } } @@ -301,12 +288,9 @@ public void testTimeoutExceptionReadWriteAutocommitSlowCommit() { // gRPC call will be slow. connection.setStatementTimeout(TIMEOUT_FOR_SLOW_STATEMENTS, TimeUnit.MILLISECONDS); connection.setAutocommit(true); - try { - connection.execute(INSERT_STATEMENT); - fail("missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, ex.getErrorCode()); - } + SpannerException e = + assertThrows(SpannerException.class, () -> connection.execute(INSERT_STATEMENT)); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } @@ -320,18 +304,15 @@ public void testTimeoutExceptionReadWriteAutocommitSlowCommitMultipleStatements( connection.setStatementTimeout(TIMEOUT_FOR_SLOW_STATEMENTS, TimeUnit.MILLISECONDS); // assert that multiple statements after each other also time out for (int i = 0; i < 2; i++) { - try { - connection.execute(INSERT_STATEMENT); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode(), is(equalTo(ErrorCode.DEADLINE_EXCEEDED))); - } + SpannerException e = + assertThrows(SpannerException.class, () -> connection.execute(INSERT_STATEMENT)); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } // try to do a query in autocommit mode. This will use a single-use read-only transaction that // does not need to commit, i.e. it should succeed. connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { - assertThat(rs, is(notNullValue())); + assertNotNull(rs); } } } @@ -350,12 +331,9 @@ public void testTimeoutExceptionReadWriteAutocommitPartitioned() { mockSpanner.setExecuteStreamingSqlExecutionTime( SimulatedExecutionTime.ofMinimumAndRandomTime(EXECUTION_TIME_SLOW_STATEMENT, 0)); connection.setStatementTimeout(TIMEOUT_FOR_SLOW_STATEMENTS, TimeUnit.MILLISECONDS); - try { - connection.execute(INSERT_STATEMENT); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, ex.getErrorCode()); - } + SpannerException e = + assertThrows(SpannerException.class, () -> connection.execute(INSERT_STATEMENT)); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } @@ -367,12 +345,10 @@ public void testTimeoutExceptionReadWriteTransactional() { try (Connection connection = createConnection()) { connection.setAutocommit(false); connection.setStatementTimeout(TIMEOUT_FOR_SLOW_STATEMENTS, TimeUnit.MILLISECONDS); - try { - connection.executeQuery(SELECT_RANDOM_STATEMENT); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, ex.getErrorCode()); - } + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(SELECT_RANDOM_STATEMENT)); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } @@ -387,15 +363,13 @@ public void testTimeoutExceptionReadWriteTransactionMultipleStatements() { // Assert that multiple statements after each other will timeout the first time, and then // throw a SpannerException with code FAILED_PRECONDITION. for (int i = 0; i < 2; i++) { - try { - connection.executeQuery(SELECT_RANDOM_STATEMENT); - fail("Missing expected exception"); - } catch (SpannerException e) { - if (i == 0) { - assertThat(e.getErrorCode(), is(equalTo(ErrorCode.DEADLINE_EXCEEDED))); - } else { - assertThat(e.getErrorCode(), is(equalTo(ErrorCode.FAILED_PRECONDITION))); - } + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(SELECT_RANDOM_STATEMENT)); + if (i == 0) { + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); + } else { + assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode()); } } // do a rollback without any chance of a timeout @@ -405,7 +379,7 @@ public void testTimeoutExceptionReadWriteTransactionMultipleStatements() { mockSpanner.removeAllExecutionTimes(); connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { - assertThat(rs, is(notNullValue())); + assertNotNull(rs); } } } @@ -420,16 +394,12 @@ public void testTimeoutExceptionReadWriteTransactionalSlowCommit() { connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { - assertThat(rs, is(notNullValue())); + assertNotNull(rs); } connection.setStatementTimeout(TIMEOUT_FOR_SLOW_STATEMENTS, TimeUnit.MILLISECONDS); - try { - connection.commit(); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, ex.getErrorCode()); - } + SpannerException e = assertThrows(SpannerException.class, () -> connection.commit()); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } @@ -443,7 +413,7 @@ public void testTimeoutExceptionReadWriteTransactionalSlowRollback() { connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { - assertThat(rs, is(notNullValue())); + assertNotNull(rs); } connection.setStatementTimeout(TIMEOUT_FOR_SLOW_STATEMENTS, TimeUnit.MILLISECONDS); // Rollback timeouts are not propagated as exceptions, as all errors during a Rollback RPC are @@ -513,25 +483,32 @@ private void testInterruptedException(final ConnectionConsumer consumer) mockSpanner.setExecuteStreamingSqlExecutionTime( SimulatedExecutionTime.ofMinimumAndRandomTime(EXECUTION_TIME_SLOW_STATEMENT, 0)); - final CountDownLatch latch = new CountDownLatch(1); + CountDownLatch latch = new CountDownLatch(1); + SettableApiFuture thread = SettableApiFuture.create(); ExecutorService executor = Executors.newSingleThreadExecutor(); - Future future = - executor.submit( - () -> { - try (Connection connection = createConnection()) { - consumer.accept(connection); - connection.setStatementTimeout(10000L, TimeUnit.MILLISECONDS); - - latch.countDown(); - try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) {} - return false; - } catch (SpannerException e) { - return e.getErrorCode() == ErrorCode.CANCELLED; - } - }); - latch.await(10L, TimeUnit.SECONDS); - executor.shutdownNow(); - assertThat(future.get(), is(true)); + try { + Future future = + executor.submit( + () -> { + try (Connection connection = createConnection()) { + consumer.accept(connection); + connection.setStatementTimeout(10000L, TimeUnit.MILLISECONDS); + + thread.set(Thread.currentThread()); + latch.countDown(); + try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) {} + return false; + } catch (SpannerException e) { + return e.getErrorCode() == ErrorCode.CANCELLED; + } + }); + latch.await(10L, TimeUnit.SECONDS); + waitForRequestsToContain(ExecuteSqlRequest.class); + thread.get().interrupt(); + assertTrue(future.get()); + } finally { + executor.shutdownNow(); + } } @Test @@ -543,12 +520,10 @@ public void testInvalidQueryReadOnlyAutocommit() { connection.setAutocommit(true); connection.setReadOnly(true); connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); - try { - connection.executeQuery(Statement.of(INVALID_SELECT)); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.INVALID_ARGUMENT, ex.getErrorCode()); - } + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(Statement.of(INVALID_SELECT))); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); } } @@ -561,12 +536,10 @@ public void testInvalidQueryReadOnlyTransactional() { connection.setReadOnly(true); connection.setAutocommit(false); connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); - try { - connection.executeQuery(Statement.of(INVALID_SELECT)); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.INVALID_ARGUMENT, ex.getErrorCode()); - } + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(Statement.of(INVALID_SELECT))); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); } } @@ -578,12 +551,10 @@ public void testInvalidQueryReadWriteAutocommit() { try (Connection connection = createConnection()) { connection.setAutocommit(true); connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); - try { - connection.executeQuery(Statement.of(INVALID_SELECT)); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.INVALID_ARGUMENT, ex.getErrorCode()); - } + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(Statement.of(INVALID_SELECT))); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); } } @@ -595,12 +566,10 @@ public void testInvalidQueryReadWriteTransactional() { try (Connection connection = createConnection()) { connection.setAutocommit(false); connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); - try { - connection.executeQuery(Statement.of(INVALID_SELECT)); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.INVALID_ARGUMENT, ex.getErrorCode()); - } + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(Statement.of(INVALID_SELECT))); + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); } } @@ -614,28 +583,48 @@ static void waitForRequestsToContain(Class request) { } } + private void waitForDdlRequestOnServer() { + try { + Stopwatch watch = Stopwatch.createStarted(); + while (Collections2.filter( + mockDatabaseAdmin.getRequests(), + input -> input.getClass().equals(UpdateDatabaseDdlRequest.class)) + .size() + == 0) { + Thread.sleep(1L); + if (watch.elapsed(TimeUnit.MILLISECONDS) > EXECUTION_TIME_SLOW_STATEMENT) { + throw new TimeoutException("Timeout while waiting for DDL request"); + } + } + } catch (InterruptedException e) { + throw SpannerExceptionFactory.propagateInterrupt(e); + } catch (TimeoutException e) { + throw SpannerExceptionFactory.propagateTimeout(e); + } + } + @Test public void testCancelReadOnlyAutocommit() { mockSpanner.setExecuteStreamingSqlExecutionTime( SimulatedExecutionTime.ofMinimumAndRandomTime(EXECUTION_TIME_SLOW_STATEMENT, 0)); - ExecutorService executor = Executors.newSingleThreadExecutor(); try (Connection connection = createConnection()) { connection.setAutocommit(true); connection.setReadOnly(true); - executor.execute( - () -> { - waitForRequestsToContain(ExecuteSqlRequest.class); - connection.cancel(); - }); + ExecutorService executor = Executors.newSingleThreadExecutor(); try { - connection.executeQuery(SELECT_RANDOM_STATEMENT); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.CANCELLED, ex.getErrorCode()); + executor.execute( + () -> { + waitForRequestsToContain(ExecuteSqlRequest.class); + connection.cancel(); + }); + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(SELECT_RANDOM_STATEMENT)); + assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); + } finally { + executor.shutdownNow(); } - } finally { - executor.shutdown(); } } @@ -644,29 +633,30 @@ public void testCancelReadOnlyAutocommitMultipleStatements() { mockSpanner.setExecuteStreamingSqlExecutionTime( SimulatedExecutionTime.ofMinimumAndRandomTime(EXECUTION_TIME_SLOW_STATEMENT, 0)); - ExecutorService executor = Executors.newSingleThreadExecutor(); try (Connection connection = createConnection()) { connection.setAutocommit(true); connection.setReadOnly(true); - executor.execute( - () -> { - waitForRequestsToContain(ExecuteSqlRequest.class); - connection.cancel(); - }); + ExecutorService executor = Executors.newSingleThreadExecutor(); + try { + executor.execute( + () -> { + waitForRequestsToContain(ExecuteSqlRequest.class); + connection.cancel(); + }); - try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { - fail("Missing expected exception"); - } catch (SpannerException e) { + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(SELECT_RANDOM_STATEMENT)); assertThat(e.getErrorCode(), is(equalTo(ErrorCode.CANCELLED))); - } - mockSpanner.removeAllExecutionTimes(); - connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); - try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { - assertThat(rs, is(notNullValue())); + mockSpanner.removeAllExecutionTimes(); + connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); + try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { + assertNotNull(rs); + } + } finally { + executor.shutdownNow(); } - } finally { - executor.shutdown(); } } @@ -675,23 +665,23 @@ public void testCancelReadOnlyTransactional() { mockSpanner.setExecuteStreamingSqlExecutionTime( SimulatedExecutionTime.ofMinimumAndRandomTime(EXECUTION_TIME_SLOW_STATEMENT, 0)); - ExecutorService executor = Executors.newSingleThreadExecutor(); try (Connection connection = createConnection()) { connection.setReadOnly(true); connection.setAutocommit(false); - executor.execute( - () -> { - waitForRequestsToContain(ExecuteSqlRequest.class); - connection.cancel(); - }); + ExecutorService executor = Executors.newSingleThreadExecutor(); try { - connection.executeQuery(SELECT_RANDOM_STATEMENT); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.CANCELLED, ex.getErrorCode()); + executor.execute( + () -> { + waitForRequestsToContain(ExecuteSqlRequest.class); + connection.cancel(); + }); + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(SELECT_RANDOM_STATEMENT)); + assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); + } finally { + executor.shutdownNow(); } - } finally { - executor.shutdown(); } } @@ -700,35 +690,35 @@ public void testCancelReadOnlyTransactionalMultipleStatements() { mockSpanner.setExecuteStreamingSqlExecutionTime( SimulatedExecutionTime.ofMinimumAndRandomTime(EXECUTION_TIME_SLOW_STATEMENT, 0)); - ExecutorService executor = Executors.newSingleThreadExecutor(); try (Connection connection = createConnection()) { connection.setReadOnly(true); connection.setAutocommit(false); - executor.execute( - () -> { - waitForRequestsToContain(ExecuteSqlRequest.class); - connection.cancel(); - }); + ExecutorService executor = Executors.newSingleThreadExecutor(); try { - connection.executeQuery(Statement.of(SLOW_SELECT)); - fail("Missing expected exception"); - } catch (SpannerException e) { + executor.execute( + () -> { + waitForRequestsToContain(ExecuteSqlRequest.class); + connection.cancel(); + }); + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(Statement.of(SLOW_SELECT))); assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); - } - // try to do a new query that is fast. - mockSpanner.removeAllExecutionTimes(); - connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); - try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { - assertThat(rs, is(notNullValue())); - } - // rollback and do another fast query - connection.rollback(); - try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { - assertThat(rs, is(notNullValue())); + // try to do a new query that is fast. + mockSpanner.removeAllExecutionTimes(); + connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); + try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { + assertNotNull(rs); + } + // rollback and do another fast query + connection.rollback(); + try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { + assertNotNull(rs); + } + } finally { + executor.shutdownNow(); } - } finally { - executor.shutdown(); } } @@ -737,22 +727,22 @@ public void testCancelReadWriteAutocommit() { mockSpanner.setExecuteStreamingSqlExecutionTime( SimulatedExecutionTime.ofMinimumAndRandomTime(EXECUTION_TIME_SLOW_STATEMENT, 0)); - ExecutorService executor = Executors.newSingleThreadExecutor(); try (Connection connection = createConnection()) { connection.setAutocommit(true); - executor.execute( - () -> { - waitForRequestsToContain(ExecuteSqlRequest.class); - connection.cancel(); - }); + ExecutorService executor = Executors.newSingleThreadExecutor(); try { - connection.executeQuery(SELECT_RANDOM_STATEMENT); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.CANCELLED, ex.getErrorCode()); + executor.execute( + () -> { + waitForRequestsToContain(ExecuteSqlRequest.class); + connection.cancel(); + }); + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(SELECT_RANDOM_STATEMENT)); + assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); + } finally { + executor.shutdownNow(); } - } finally { - executor.shutdown(); } } @@ -761,29 +751,29 @@ public void testCancelReadWriteAutocommitMultipleStatements() { mockSpanner.setExecuteStreamingSqlExecutionTime( SimulatedExecutionTime.ofMinimumAndRandomTime(EXECUTION_TIME_SLOW_STATEMENT, 0)); - ExecutorService executor = Executors.newSingleThreadExecutor(); try (Connection connection = createConnection()) { connection.setAutocommit(true); - executor.execute( - () -> { - waitForRequestsToContain(ExecuteSqlRequest.class); - connection.cancel(); - }); + ExecutorService executor = Executors.newSingleThreadExecutor(); try { - connection.executeQuery(SELECT_RANDOM_STATEMENT); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.CANCELLED, ex.getErrorCode()); - } + executor.execute( + () -> { + waitForRequestsToContain(ExecuteSqlRequest.class); + connection.cancel(); + }); + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(SELECT_RANDOM_STATEMENT)); + assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); - // try to do a new query that is fast. - mockSpanner.removeAllExecutionTimes(); - connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); - try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { - assertThat(rs, is(notNullValue())); + // try to do a new query that is fast. + mockSpanner.removeAllExecutionTimes(); + connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); + try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { + assertNotNull(rs); + } + } finally { + executor.shutdownNow(); } - } finally { - executor.shutdown(); } } @@ -792,22 +782,21 @@ public void testCancelReadWriteAutocommitSlowUpdate() { mockSpanner.setExecuteSqlExecutionTime( SimulatedExecutionTime.ofMinimumAndRandomTime(EXECUTION_TIME_SLOW_STATEMENT, 0)); - ExecutorService executor = Executors.newSingleThreadExecutor(); try (Connection connection = createConnection()) { connection.setAutocommit(true); - executor.execute( - () -> { - waitForRequestsToContain(ExecuteSqlRequest.class); - connection.cancel(); - }); + ExecutorService executor = Executors.newSingleThreadExecutor(); try { - connection.execute(INSERT_STATEMENT); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.CANCELLED, ex.getErrorCode()); + executor.execute( + () -> { + waitForRequestsToContain(ExecuteSqlRequest.class); + connection.cancel(); + }); + SpannerException e = + assertThrows(SpannerException.class, () -> connection.execute(INSERT_STATEMENT)); + assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); + } finally { + executor.shutdownNow(); } - } finally { - executor.shutdown(); } } @@ -816,20 +805,21 @@ public void testCancelReadWriteAutocommitSlowCommit() { mockSpanner.setCommitExecutionTime( SimulatedExecutionTime.ofMinimumAndRandomTime(EXECUTION_TIME_SLOW_STATEMENT, 0)); - ExecutorService executor = Executors.newSingleThreadExecutor(); try (Connection connection = createConnection()) { connection.setAutocommit(true); - executor.execute( - () -> { - waitForRequestsToContain(CommitRequest.class); - connection.cancel(); - }); - connection.execute(INSERT_STATEMENT); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.CANCELLED, ex.getErrorCode()); - } finally { - executor.shutdown(); + ExecutorService executor = Executors.newSingleThreadExecutor(); + try { + executor.execute( + () -> { + waitForRequestsToContain(CommitRequest.class); + connection.cancel(); + }); + SpannerException e = + assertThrows(SpannerException.class, () -> connection.execute(INSERT_STATEMENT)); + assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); + } finally { + executor.shutdownNow(); + } } } @@ -838,20 +828,22 @@ public void testCancelReadWriteTransactional() { mockSpanner.setExecuteStreamingSqlExecutionTime( SimulatedExecutionTime.ofMinimumAndRandomTime(EXECUTION_TIME_SLOW_STATEMENT, 0)); - ExecutorService executor = Executors.newSingleThreadExecutor(); try (Connection connection = createConnection()) { connection.setAutocommit(false); - executor.execute( - () -> { - waitForRequestsToContain(ExecuteSqlRequest.class); - connection.cancel(); - }); - connection.executeQuery(SELECT_RANDOM_STATEMENT); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.CANCELLED, ex.getErrorCode()); - } finally { - executor.shutdown(); + ExecutorService executor = Executors.newSingleThreadExecutor(); + try { + executor.execute( + () -> { + waitForRequestsToContain(ExecuteSqlRequest.class); + connection.cancel(); + }); + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(SELECT_RANDOM_STATEMENT)); + assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); + } finally { + executor.shutdownNow(); + } } } @@ -860,31 +852,31 @@ public void testCancelReadWriteTransactionalMultipleStatements() { mockSpanner.setExecuteStreamingSqlExecutionTime( SimulatedExecutionTime.ofMinimumAndRandomTime(EXECUTION_TIME_SLOW_STATEMENT, 0)); - ExecutorService executor = Executors.newSingleThreadExecutor(); try (Connection connection = createConnection()) { connection.setAutocommit(false); - executor.execute( - () -> { - waitForRequestsToContain(ExecuteSqlRequest.class); - connection.cancel(); - }); + ExecutorService executor = Executors.newSingleThreadExecutor(); try { - connection.executeQuery(SELECT_RANDOM_STATEMENT); - fail("Missing expected exception"); - } catch (SpannerException e) { + executor.execute( + () -> { + waitForRequestsToContain(ExecuteSqlRequest.class); + connection.cancel(); + }); + SpannerException e = + assertThrows( + SpannerException.class, () -> connection.executeQuery(SELECT_RANDOM_STATEMENT)); assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); + // Rollback the transaction as it is no longer usable. + connection.rollback(); + + // Try to do a new query that is fast. + mockSpanner.removeAllExecutionTimes(); + connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); + try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { + assertNotNull(rs); + } + } finally { + executor.shutdownNow(); } - // Rollback the transaction as it is no longer usable. - connection.rollback(); - - // Try to do a new query that is fast. - mockSpanner.removeAllExecutionTimes(); - connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); - try (ResultSet rs = connection.executeQuery(SELECT_RANDOM_STATEMENT)) { - assertThat(rs, is(notNullValue())); - } - } finally { - executor.shutdown(); } } @@ -925,22 +917,22 @@ static void addMockDdlOperations(int count, boolean done) { public void testCancelDdlBatch() { addSlowMockDdlOperation(); - ExecutorService executor = Executors.newSingleThreadExecutor(); try (Connection connection = createConnection()) { connection.setAutocommit(false); connection.startBatchDdl(); connection.execute(Statement.of(SLOW_DDL)); - executor.execute( - () -> { - Uninterruptibles.sleepUninterruptibly(100L, TimeUnit.MILLISECONDS); - connection.cancel(); - }); - connection.runBatch(); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.CANCELLED, ex.getErrorCode()); - } finally { - executor.shutdown(); + ExecutorService executor = Executors.newSingleThreadExecutor(); + try { + executor.execute( + () -> { + waitForDdlRequestOnServer(); + connection.cancel(); + }); + SpannerException e = assertThrows(SpannerException.class, () -> connection.runBatch()); + assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); + } finally { + executor.shutdownNow(); + } } } @@ -948,20 +940,21 @@ public void testCancelDdlBatch() { public void testCancelDdlAutocommit() { addSlowMockDdlOperation(); - ExecutorService executor = Executors.newSingleThreadExecutor(); try (Connection connection = createConnection()) { connection.setAutocommit(true); - executor.execute( - () -> { - Uninterruptibles.sleepUninterruptibly(100L, TimeUnit.MILLISECONDS); - connection.cancel(); - }); - connection.execute(Statement.of(SLOW_DDL)); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.CANCELLED, ex.getErrorCode()); - } finally { - executor.shutdown(); + ExecutorService executor = Executors.newSingleThreadExecutor(); + try { + executor.execute( + () -> { + waitForDdlRequestOnServer(); + connection.cancel(); + }); + SpannerException e = + assertThrows(SpannerException.class, () -> connection.execute(Statement.of(SLOW_DDL))); + assertEquals(ErrorCode.CANCELLED, e.getErrorCode()); + } finally { + executor.shutdownNow(); + } } } @@ -972,10 +965,9 @@ public void testTimeoutExceptionDdlAutocommit() { try (Connection connection = createConnection()) { connection.setAutocommit(true); connection.setStatementTimeout(TIMEOUT_FOR_SLOW_STATEMENTS, TimeUnit.MILLISECONDS); - connection.execute(Statement.of(SLOW_DDL)); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, ex.getErrorCode()); + SpannerException e = + assertThrows(SpannerException.class, () -> connection.execute(Statement.of(SLOW_DDL))); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } @@ -989,18 +981,15 @@ public void testTimeoutExceptionDdlAutocommitMultipleStatements() { // assert that multiple statements after each other also time out for (int i = 0; i < 2; i++) { - try { - connection.execute(Statement.of(SLOW_DDL)); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); - } + SpannerException e = + assertThrows(SpannerException.class, () -> connection.execute(Statement.of(SLOW_DDL))); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } // try to do a new DDL statement that is fast. mockDatabaseAdmin.reset(); addFastMockDdlOperation(); connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); - assertThat(connection.execute(Statement.of(FAST_DDL)), is(notNullValue())); + assertNotNull(connection.execute(Statement.of(FAST_DDL))); } } @@ -1016,10 +1005,8 @@ public void testTimeoutExceptionDdlBatch() { // the following statement will NOT timeout as the statement is only buffered locally connection.execute(Statement.of(SLOW_DDL)); // the runBatch() statement sends the statement to the server and should timeout - connection.runBatch(); - fail("Missing expected exception"); - } catch (SpannerException ex) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, ex.getErrorCode()); + SpannerException e = assertThrows(SpannerException.class, () -> connection.runBatch()); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } } @@ -1033,22 +1020,17 @@ public void testTimeoutExceptionDdlBatchMultipleStatements() { // assert that multiple statements after each other also time out for (int i = 0; i < 2; i++) { - connection.startBatchDdl(); connection.execute(Statement.of(SLOW_DDL)); - try { - connection.runBatch(); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); - } + SpannerException e = assertThrows(SpannerException.class, () -> connection.runBatch()); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); } // try to do a new DDL statement that is fast. mockDatabaseAdmin.reset(); addFastMockDdlOperation(); connection.setStatementTimeout(TIMEOUT_FOR_FAST_STATEMENTS, TimeUnit.MILLISECONDS); connection.startBatchDdl(); - assertThat(connection.execute(Statement.of(FAST_DDL)), is(notNullValue())); + assertNotNull(connection.execute(Statement.of(FAST_DDL))); connection.runBatch(); } } @@ -1061,13 +1043,9 @@ public void testTimeoutDifferentTimeUnits() { try (Connection connection = createConnection()) { connection.setAutocommit(true); for (TimeUnit unit : ReadOnlyStalenessUtil.SUPPORTED_UNITS) { + // Only set the timeout, don't execute a statement with the timeout to prevent unnecessarily + // slowing down the build time. connection.setStatementTimeout(1L, unit); - try { - connection.execute(SELECT_RANDOM_STATEMENT); - fail("Missing expected exception"); - } catch (SpannerException e) { - assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); - } } } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITDdlTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITDdlTest.java index 8448c601b12..74c072cd760 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITDdlTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITDdlTest.java @@ -32,6 +32,6 @@ public class ITDdlTest extends ITAbstractSpannerTest { @Test public void testSqlScript() throws Exception { SqlScriptVerifier verifier = new SqlScriptVerifier(new ITConnectionProvider()); - verifier.verifyStatementsInFile("ITDdlTest.sql", SqlScriptVerifier.class); + verifier.verifyStatementsInFile("ITDdlTest.sql", SqlScriptVerifier.class, false); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITReadOnlySpannerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITReadOnlySpannerTest.java index 55a4926f641..fd5df07954e 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITReadOnlySpannerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITReadOnlySpannerTest.java @@ -66,7 +66,7 @@ public void createTestTables() throws Exception { // create tables SqlScriptVerifier verifier = new SqlScriptVerifier(new ITConnectionProvider()); verifier.verifyStatementsInFile( - "ITReadOnlySpannerTest_CreateTables.sql", SqlScriptVerifier.class); + "ITReadOnlySpannerTest_CreateTables.sql", SqlScriptVerifier.class, false); // fill tables with data connection.setAutocommit(false); @@ -101,7 +101,7 @@ public void testSqlScript() throws Exception { // Wait 100ms to ensure that staleness tests in the script succeed. Thread.sleep(100L); SqlScriptVerifier verifier = new SqlScriptVerifier(new ITConnectionProvider()); - verifier.verifyStatementsInFile("ITReadOnlySpannerTest.sql", SqlScriptVerifier.class); + verifier.verifyStatementsInFile("ITReadOnlySpannerTest.sql", SqlScriptVerifier.class, false); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITReadWriteAutocommitSpannerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITReadWriteAutocommitSpannerTest.java index ab1da50992d..d394013fbea 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITReadWriteAutocommitSpannerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITReadWriteAutocommitSpannerTest.java @@ -59,7 +59,7 @@ public boolean doCreateDefaultTestTable() { public void test01_SqlScript() throws Exception { SqlScriptVerifier verifier = new SqlScriptVerifier(new ITConnectionProvider()); verifier.verifyStatementsInFile( - "ITReadWriteAutocommitSpannerTest.sql", SqlScriptVerifier.class); + "ITReadWriteAutocommitSpannerTest.sql", SqlScriptVerifier.class, false); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITSqlMusicScriptTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITSqlMusicScriptTest.java index e8a479c6d63..e7afe957705 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITSqlMusicScriptTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITSqlMusicScriptTest.java @@ -54,7 +54,7 @@ public class ITSqlMusicScriptTest extends ITAbstractSpannerTest { public void test01_RunScript() throws Exception { SqlScriptVerifier verifier = new SqlScriptVerifier(); try (GenericConnection connection = SpannerGenericConnection.of(createConnection())) { - verifier.verifyStatementsInFile(connection, SCRIPT_FILE, SqlScriptVerifier.class); + verifier.verifyStatementsInFile(connection, SCRIPT_FILE, SqlScriptVerifier.class, false); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITSqlScriptTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITSqlScriptTest.java index 5a1e9bb6282..026495605ed 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITSqlScriptTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITSqlScriptTest.java @@ -66,7 +66,10 @@ public class ITSqlScriptTest extends ITAbstractSpannerTest { public void test01_CreateTables() throws Exception { try (ITConnection connection = createConnection()) { verifier.verifyStatementsInFile( - SpannerGenericConnection.of(connection), CREATE_TABLES_FILE, SqlScriptVerifier.class); + SpannerGenericConnection.of(connection), + CREATE_TABLES_FILE, + SqlScriptVerifier.class, + false); } } @@ -76,7 +79,8 @@ public void test02_InsertTestData() throws Exception { verifier.verifyStatementsInFile( SpannerGenericConnection.of(connection), INSERT_AND_VERIFY_TEST_DATA, - SqlScriptVerifier.class); + SqlScriptVerifier.class, + false); } catch (SpannerException e) { if (isUsingEmulator() && e.getErrorCode() == ErrorCode.ALREADY_EXISTS) { // Errors in a transaction are 'sticky' on the emulator, so any query in the same @@ -92,7 +96,8 @@ public void test03_TestGetReadTimestamp() throws Exception { verifier.verifyStatementsInFile( SpannerGenericConnection.of(connection), TEST_GET_READ_TIMESTAMP, - SqlScriptVerifier.class); + SqlScriptVerifier.class, + false); } } @@ -102,7 +107,8 @@ public void test04_TestGetCommitTimestamp() throws Exception { verifier.verifyStatementsInFile( SpannerGenericConnection.of(connection), TEST_GET_COMMIT_TIMESTAMP, - SqlScriptVerifier.class); + SqlScriptVerifier.class, + false); } catch (SpannerException e) { if (isUsingEmulator() && e.getErrorCode() == ErrorCode.INVALID_ARGUMENT) { // Errors in a transaction are 'sticky' on the emulator, so any query in the same @@ -117,7 +123,8 @@ public void test05_TestTemporaryTransactions() throws Exception { verifier.verifyStatementsInFile( SpannerGenericConnection.of(connection), TEST_TEMPORARY_TRANSACTIONS, - SqlScriptVerifier.class); + SqlScriptVerifier.class, + false); } } @@ -125,7 +132,10 @@ public void test05_TestTemporaryTransactions() throws Exception { public void test06_TestTransactionMode() throws Exception { try (ITConnection connection = createConnection()) { verifier.verifyStatementsInFile( - SpannerGenericConnection.of(connection), TEST_TRANSACTION_MODE, SqlScriptVerifier.class); + SpannerGenericConnection.of(connection), + TEST_TRANSACTION_MODE, + SqlScriptVerifier.class, + false); } } @@ -135,7 +145,8 @@ public void test07_TestTransactionModeReadOnly() throws Exception { verifier.verifyStatementsInFile( SpannerGenericConnection.of(connection), TEST_TRANSACTION_MODE_READ_ONLY, - SqlScriptVerifier.class); + SqlScriptVerifier.class, + false); } } @@ -145,7 +156,8 @@ public void test08_TestReadOnlyStaleness() throws Exception { verifier.verifyStatementsInFile( SpannerGenericConnection.of(connection), TEST_READ_ONLY_STALENESS, - SqlScriptVerifier.class); + SqlScriptVerifier.class, + false); } } @@ -155,7 +167,8 @@ public void test09_TestAutocommitDmlMode() throws Exception { verifier.verifyStatementsInFile( SpannerGenericConnection.of(connection), TEST_AUTOCOMMIT_DML_MODE, - SqlScriptVerifier.class); + SqlScriptVerifier.class, + false); } } @@ -165,7 +178,8 @@ public void test10_TestAutocommitReadOnly() throws Exception { verifier.verifyStatementsInFile( SpannerGenericConnection.of(connection), TEST_AUTOCOMMIT_READ_ONLY, - SqlScriptVerifier.class); + SqlScriptVerifier.class, + false); } } @@ -173,7 +187,10 @@ public void test10_TestAutocommitReadOnly() throws Exception { public void test11_TestStatementTimeout() throws Exception { try (ITConnection connection = createConnection()) { verifier.verifyStatementsInFile( - SpannerGenericConnection.of(connection), TEST_STATEMENT_TIMEOUT, SqlScriptVerifier.class); + SpannerGenericConnection.of(connection), + TEST_STATEMENT_TIMEOUT, + SqlScriptVerifier.class, + false); } } @@ -181,7 +198,10 @@ public void test11_TestStatementTimeout() throws Exception { public void test12_TestSetStatements() throws Exception { try (ITConnection connection = createConnection()) { verifier.verifyStatementsInFile( - SpannerGenericConnection.of(connection), TEST_SET_STATEMENTS, SqlScriptVerifier.class); + SpannerGenericConnection.of(connection), + TEST_SET_STATEMENTS, + SqlScriptVerifier.class, + false); } } @@ -191,7 +211,8 @@ public void test13_TestInvalidStatements() throws Exception { verifier.verifyStatementsInFile( SpannerGenericConnection.of(connection), TEST_INVALID_STATEMENTS, - SqlScriptVerifier.class); + SqlScriptVerifier.class, + false); } } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITTransactionModeTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITTransactionModeTest.java index 3874f595bad..33b059c8bf9 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITTransactionModeTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITTransactionModeTest.java @@ -53,7 +53,7 @@ public boolean doCreateDefaultTestTable() { @Test public void testSqlScript() throws Exception { SqlScriptVerifier verifier = new SqlScriptVerifier(new ITConnectionProvider()); - verifier.verifyStatementsInFile("ITTransactionModeTest.sql", SqlScriptVerifier.class); + verifier.verifyStatementsInFile("ITTransactionModeTest.sql", SqlScriptVerifier.class, false); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java index 39e16fcca40..a004dd3465a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java @@ -20,7 +20,8 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import static org.junit.Assume.assumeTrue; import com.google.api.gax.core.GaxProperties; @@ -84,7 +85,7 @@ import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; import org.junit.After; -import org.junit.Before; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @@ -141,24 +142,22 @@ public class GapicSpannerRpcTest { new java.util.Date( System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(1L, TimeUnit.DAYS)))); - private MockSpannerServiceImpl mockSpanner; - private MockInstanceAdminImpl mockInstanceAdmin; - private MockDatabaseAdminImpl mockDatabaseAdmin; - private Server server; - private InetSocketAddress address; - private final Map optionsMap = new HashMap<>(); - private Metadata seenHeaders; - private String defaultUserAgent; + private static MockSpannerServiceImpl mockSpanner; + private static MockInstanceAdminImpl mockInstanceAdmin; + private static MockDatabaseAdminImpl mockDatabaseAdmin; + private static Server server; + private static InetSocketAddress address; + private static final Map optionsMap = new HashMap<>(); + private static Metadata lastSeenHeaders; + private static String defaultUserAgent; + private static Spanner spanner; @BeforeClass - public static void checkNotEmulator() { + public static void startServer() throws IOException { assumeTrue( "Skip tests when emulator is enabled as this test interferes with the check whether the emulator is running", System.getenv("SPANNER_EMULATOR_HOST") == null); - } - @Before - public void startServer() throws IOException { defaultUserAgent = "spanner-java/" + GaxProperties.getLibraryVersion(GapicSpannerRpc.class); mockSpanner = new MockSpannerServiceImpl(); mockSpanner.setAbortProbability(0.0D); // We don't want any unpredictable aborted transactions. @@ -182,7 +181,7 @@ public ServerCall.Listener interceptCall( ServerCall call, Metadata headers, ServerCallHandler next) { - seenHeaders = headers; + lastSeenHeaders = headers; String auth = headers.get(Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER)); assertThat(auth).isEqualTo("Bearer " + VARIABLE_OAUTH_TOKEN); @@ -192,12 +191,21 @@ public ServerCall.Listener interceptCall( .build() .start(); optionsMap.put(Option.CHANNEL_HINT, 1L); + spanner = createSpannerOptions().getService(); + } + + @AfterClass + public static void stopServer() throws InterruptedException { + if (spanner != null) { + spanner.close(); + server.shutdown(); + server.awaitTermination(); + } } @After - public void stopServer() throws InterruptedException { - server.shutdown(); - server.awaitTermination(); + public void reset() { + mockSpanner.reset(); } private static final int NUMBER_OF_TEST_RUNS = 2; @@ -207,8 +215,8 @@ public void stopServer() throws InterruptedException { @Test public void testCloseAllThreadsWhenClosingSpanner() throws InterruptedException { + int initialNumberOfThreads = getNumberOfThreadsWithName(SPANNER_THREAD_NAME, false, 0); for (int i = 0; i < NUMBER_OF_TEST_RUNS; i++) { - assertThat(getNumberOfThreadsWithName(SPANNER_THREAD_NAME, true), is(equalTo(0))); // Create Spanner instance. SpannerOptions options = createSpannerOptions(); Spanner spanner = options.getService(); @@ -227,8 +235,8 @@ public void testCloseAllThreadsWhenClosingSpanner() throws InterruptedException // sessions should initialize multiple transport channels. resultSets.add(rs); // Check whether the number of expected threads has been reached. - if (getNumberOfThreadsWithName(SPANNER_THREAD_NAME, false) - == options.getNumChannels() * NUM_THREADS_PER_CHANNEL) { + if (getNumberOfThreadsWithName(SPANNER_THREAD_NAME, false, initialNumberOfThreads) + == options.getNumChannels() * NUM_THREADS_PER_CHANNEL + initialNumberOfThreads) { break; } } @@ -253,11 +261,14 @@ public void testCloseAllThreadsWhenClosingSpanner() throws InterruptedException spanner.close(); // Wait for up to two seconds to allow the threads to actually shutdown. Stopwatch watch = Stopwatch.createStarted(); - while (getNumberOfThreadsWithName(SPANNER_THREAD_NAME, false) > 0 + while (getNumberOfThreadsWithName(SPANNER_THREAD_NAME, false, initialNumberOfThreads) + > initialNumberOfThreads && watch.elapsed(TimeUnit.SECONDS) < 2) { Thread.sleep(10L); } - assertThat(getNumberOfThreadsWithName(SPANNER_THREAD_NAME, true), is(equalTo(0))); + assertThat( + getNumberOfThreadsWithName(SPANNER_THREAD_NAME, true, initialNumberOfThreads), + is(equalTo(initialNumberOfThreads))); } } @@ -268,7 +279,7 @@ public void testCloseAllThreadsWhenClosingSpanner() throws InterruptedException @Test public void testMultipleOpenSpanners() throws InterruptedException { List spanners = new ArrayList<>(); - assertThat(getNumberOfThreadsWithName(SPANNER_THREAD_NAME, true), is(equalTo(0))); + int initialNumberOfThreads = getNumberOfThreadsWithName(SPANNER_THREAD_NAME, false, 0); for (int openSpanners = 1; openSpanners <= 3; openSpanners++) { // Create Spanner instance. SpannerOptions options = createSpannerOptions(); @@ -282,8 +293,9 @@ public void testMultipleOpenSpanners() throws InterruptedException { // to ensure we also hit multiple channels. for (int sessionCount = 0; sessionCount < options.getSessionPoolOptions().getMaxSessions() - && getNumberOfThreadsWithName(SPANNER_THREAD_NAME, false) - < options.getNumChannels() * NUM_THREADS_PER_CHANNEL * openSpanners; + && getNumberOfThreadsWithName(SPANNER_THREAD_NAME, false, initialNumberOfThreads) + < options.getNumChannels() * NUM_THREADS_PER_CHANNEL * openSpanners + + initialNumberOfThreads; sessionCount++) { ResultSet rs = client.singleUse().executeQuery(SELECT1AND2); // Execute ResultSet#next() to send the query to Spanner. @@ -302,11 +314,14 @@ && getNumberOfThreadsWithName(SPANNER_THREAD_NAME, false) } // Wait a little to allow the threads to actually shutdown. Stopwatch watch = Stopwatch.createStarted(); - while (getNumberOfThreadsWithName(SPANNER_THREAD_NAME, false) > 0 + while (getNumberOfThreadsWithName(SPANNER_THREAD_NAME, false, initialNumberOfThreads) + > initialNumberOfThreads && watch.elapsed(TimeUnit.SECONDS) < 2) { Thread.sleep(10L); } - assertThat(getNumberOfThreadsWithName(SPANNER_THREAD_NAME, true), is(equalTo(0))); + assertThat( + getNumberOfThreadsWithName(SPANNER_THREAD_NAME, true, initialNumberOfThreads), + is(equalTo(initialNumberOfThreads))); } @Test @@ -317,7 +332,7 @@ public void testCallCredentialsProviderPreferenceAboveCredentials() { .setCredentials(STATIC_CREDENTIALS) .setCallCredentialsProvider(() -> MoreCallCredentials.from(VARIABLE_CREDENTIALS)) .build(); - GapicSpannerRpc rpc = new GapicSpannerRpc(options); + GapicSpannerRpc rpc = new GapicSpannerRpc(options, false); // GoogleAuthLibraryCallCredentials doesn't implement equals, so we can only check for the // existence. assertThat( @@ -340,7 +355,7 @@ public void testCallCredentialsProviderReturnsNull() { .setCredentials(STATIC_CREDENTIALS) .setCallCredentialsProvider(() -> null) .build(); - GapicSpannerRpc rpc = new GapicSpannerRpc(options); + GapicSpannerRpc rpc = new GapicSpannerRpc(options, false); assertThat( rpc.newCallContext( optionsMap, @@ -360,7 +375,7 @@ public void testNoCallCredentials() { .setProjectId("some-project") .setCredentials(STATIC_CREDENTIALS) .build(); - GapicSpannerRpc rpc = new GapicSpannerRpc(options); + GapicSpannerRpc rpc = new GapicSpannerRpc(options, false); assertThat( rpc.newCallContext( optionsMap, @@ -403,41 +418,38 @@ public ApiCallContext configure( }; mockSpanner.setExecuteSqlExecutionTime(SimulatedExecutionTime.ofMinimumAndRandomTime(10, 0)); - SpannerOptions options = createSpannerOptions(); - try (Spanner spanner = options.getService()) { - final DatabaseClient client = - spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); - Context context = - Context.current().withValue(SpannerOptions.CALL_CONTEXT_CONFIGURATOR_KEY, configurator); - context.run( - () -> { - try { - // First try with a 1ns timeout. This should always cause a DEADLINE_EXCEEDED - // exception. - timeoutHolder.timeout = Duration.ofNanos(1L); + final DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); + Context context = + Context.current().withValue(SpannerOptions.CALL_CONTEXT_CONFIGURATOR_KEY, configurator); + context.run( + () -> { + // First try with a 1ns timeout. This should always cause a DEADLINE_EXCEEDED + // exception. + timeoutHolder.timeout = Duration.ofNanos(1L); + SpannerException e = + assertThrows( + SpannerException.class, + () -> + client + .readWriteTransaction() + .run(transaction -> transaction.executeUpdate(UPDATE_FOO_STATEMENT))); + assertEquals(ErrorCode.DEADLINE_EXCEEDED, e.getErrorCode()); + + // Then try with a longer timeout. This should now succeed. + timeoutHolder.timeout = Duration.ofMinutes(1L); + long updateCount = client .readWriteTransaction() .run(transaction -> transaction.executeUpdate(UPDATE_FOO_STATEMENT)); - fail("missing expected timeout exception"); - } catch (SpannerException e) { - assertThat(e.getErrorCode()).isEqualTo(ErrorCode.DEADLINE_EXCEEDED); - } - - // Then try with a longer timeout. This should now succeed. - timeoutHolder.timeout = Duration.ofMinutes(1L); - Long updateCount = - client - .readWriteTransaction() - .run(transaction -> transaction.executeUpdate(UPDATE_FOO_STATEMENT)); - assertThat(updateCount).isEqualTo(1L); - }); - } + assertEquals(1L, updateCount); + }); } @Test public void testNewCallContextWithNullRequestAndNullMethod() { SpannerOptions options = SpannerOptions.newBuilder().setProjectId("some-project").build(); - GapicSpannerRpc rpc = new GapicSpannerRpc(options); + GapicSpannerRpc rpc = new GapicSpannerRpc(options, false); assertThat(rpc.newCallContext(optionsMap, "/some/resource", null, null)).isNotNull(); rpc.shutdown(); } @@ -477,18 +489,15 @@ public void testAdminRequestsLimitExceededRetryAlgorithm() { @Test public void testDefaultUserAgent() { - final SpannerOptions options = createSpannerOptions(); - try (final Spanner spanner = options.getService()) { - final DatabaseClient databaseClient = - spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); - - try (final ResultSet rs = databaseClient.singleUse().executeQuery(SELECT1AND2)) { - rs.next(); - } + final DatabaseClient databaseClient = + spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]")); - assertThat(seenHeaders.get(Key.of("user-agent", Metadata.ASCII_STRING_MARSHALLER))) - .contains(defaultUserAgent); + try (final ResultSet rs = databaseClient.singleUse().executeQuery(SELECT1AND2)) { + rs.next(); } + + assertThat(lastSeenHeaders.get(Key.of("user-agent", Metadata.ASCII_STRING_MARSHALLER))) + .contains(defaultUserAgent); } @Test @@ -510,13 +519,13 @@ public void testCustomUserAgent() { rs.next(); } - assertThat(seenHeaders.get(Key.of("user-agent", Metadata.ASCII_STRING_MARSHALLER))) + assertThat(lastSeenHeaders.get(Key.of("user-agent", Metadata.ASCII_STRING_MARSHALLER))) .contains("test-agent " + defaultUserAgent); } } } - private SpannerOptions createSpannerOptions() { + private static SpannerOptions createSpannerOptions() { String endpoint = address.getHostString() + ":" + server.getPort(); return SpannerOptions.newBuilder() .setProjectId("[PROJECT]") @@ -535,7 +544,7 @@ private SpannerOptions createSpannerOptions() { .build(); } - private int getNumberOfThreadsWithName(String serviceName, boolean dumpStack) { + private int getNumberOfThreadsWithName(String serviceName, boolean dumpStack, int expected) { Pattern pattern = Pattern.compile(String.format(THREAD_PATTERN, serviceName)); ThreadGroup group = Thread.currentThread().getThreadGroup(); while (group.getParent() != null) { @@ -544,14 +553,18 @@ private int getNumberOfThreadsWithName(String serviceName, boolean dumpStack) { Thread[] threads = new Thread[100 * NUMBER_OF_TEST_RUNS]; int numberOfThreads = group.enumerate(threads); int res = 0; + List found = new ArrayList<>(); for (int i = 0; i < numberOfThreads; i++) { if (pattern.matcher(threads[i].getName()).matches()) { if (dumpStack) { - dumpThread(threads[i]); + found.add(threads[i]); } res++; } } + if (dumpStack && res > expected) { + found.stream().forEach(t -> dumpThread(t)); + } return res; } diff --git a/samples/README.md b/samples/README.md index 6df90704ed7..b65ad460b56 100644 --- a/samples/README.md +++ b/samples/README.md @@ -17,7 +17,7 @@ Install [Maven](http://maven.apache.org/). Build your project from the root directory (`java-spanner`): - mvn clean package -DskipTests -DskipUTs -Penable-samples + mvn clean package -DskipTests -Penable-samples Every subsequent command here should be run from a subdirectory (`cd samples/snippets`). From f22e17491d66388e363d328e8ee8a721002b6528 Mon Sep 17 00:00:00 2001 From: Thiago Nunes Date: Wed, 12 May 2021 11:04:24 +1000 Subject: [PATCH 20/27] build: configure branch 3.3.3-sp as a release branch (#1155) --- .github/release-please.yml | 28 ++-- .github/sync-repo-settings.yaml | 236 +++++++++++++------------------- 2 files changed, 107 insertions(+), 157 deletions(-) diff --git a/.github/release-please.yml b/.github/release-please.yml index d7589c23dac..37d9fad3ffe 100644 --- a/.github/release-please.yml +++ b/.github/release-please.yml @@ -1,16 +1,18 @@ releaseType: java-yoshi bumpMinorPreMajor: true branches: -- branch: 3.1.x - releaseType: java-yoshi - bumpMinorPreMajor: true -- branch: 3.3.x - releaseType: java-yoshi - bumpMinorPreMajor: true -- branch: 4.0.x - releaseType: java-yoshi - bumpMinorPreMajor: true -- branch: 5.2.x - releaseType: java-yoshi - bumpMinorPreMajor: true - + - branch: 3.1.x + releaseType: java-yoshi + bumpMinorPreMajor: true + - branch: 3.3.x + releaseType: java-yoshi + bumpMinorPreMajor: true + - branch: 4.0.x + releaseType: java-yoshi + bumpMinorPreMajor: true + - branch: 5.2.x + releaseType: java-yoshi + bumpMinorPreMajor: true + - releaseType: java-lts + bumpMinorPreMajor: true + branch: 3.3.3-sp diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index dff2e8609ba..c9f626e58cb 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -1,149 +1,97 @@ - -# Whether or not rebase-merging is enabled on this repository. -# Defaults to `true` rebaseMergeAllowed: false - -# Whether or not squash-merging is enabled on this repository. -# Defaults to `true` squashMergeAllowed: true - -# Whether or not PRs are merged with a merge commit on this repository. -# Defaults to `false` mergeCommitAllowed: false - -# Rules for master branch protection branchProtectionRules: -# Identifies the protection rule pattern. Name of the branch to be protected. -# Defaults to `master` -- pattern: master - # Can admins overwrite branch protection. - # Defaults to `true` - isAdminEnforced: true - # Number of approving reviews required to update matching branches. - # Defaults to `1` - requiredApprovingReviewCount: 1 - # Are reviews from code owners required to update matching branches. - # Defaults to `false` - requiresCodeOwnerReviews: true - # Require up to date branches - requiresStrictStatusChecks: false - # List of required status check contexts that must pass for commits to be accepted to matching branches. - requiredStatusCheckContexts: - - "dependencies (8)" - - "dependencies (11)" - - "linkage-monitor" - - "lint" - - "clirr" - - "units (8)" - - "units (11)" - - "Kokoro - Test: Integration" - - "cla/google" - -# Identifies the protection rule pattern. Name of the branch to be protected. -# Defaults to `master` -- pattern: 3.1.x - # Can admins overwrite branch protection. - # Defaults to `true` - isAdminEnforced: true - # Number of approving reviews required to update matching branches. - # Defaults to `1` - requiredApprovingReviewCount: 1 - # Are reviews from code owners required to update matching branches. - # Defaults to `false` - requiresCodeOwnerReviews: true - # Require up to date branches - requiresStrictStatusChecks: false - # List of required status check contexts that must pass for commits to be accepted to matching branches. - requiredStatusCheckContexts: - - "dependencies (8)" - - "dependencies (11)" - - "lint" - - "units (7)" - - "units (8)" - - "units (11)" - - "Kokoro - Test: Integration" - - "cla/google" - -# Identifies the protection rule pattern. Name of the branch to be protected. -# Defaults to `master` -- pattern: 3.3.x - # Can admins overwrite branch protection. - # Defaults to `true` - isAdminEnforced: true - # Number of approving reviews required to update matching branches. - # Defaults to `1` - requiredApprovingReviewCount: 1 - # Are reviews from code owners required to update matching branches. - # Defaults to `false` - requiresCodeOwnerReviews: true - # Require up to date branches - requiresStrictStatusChecks: false - # List of required status check contexts that must pass for commits to be accepted to matching branches. - requiredStatusCheckContexts: - - "dependencies (8)" - - "dependencies (11)" - - "lint" - - "units (7)" - - "units (8)" - - "units (11)" - - "Kokoro - Test: Integration" - - "cla/google" - -# Identifies the protection rule pattern. Name of the branch to be protected. -# Defaults to `master` -- pattern: 4.0.x - # Can admins overwrite branch protection. - # Defaults to `true` - isAdminEnforced: true - # Number of approving reviews required to update matching branches. - # Defaults to `1` - requiredApprovingReviewCount: 1 - # Are reviews from code owners required to update matching branches. - # Defaults to `false` - requiresCodeOwnerReviews: true - # Require up to date branches - requiresStrictStatusChecks: false - # List of required status check contexts that must pass for commits to be accepted to matching branches. - requiredStatusCheckContexts: - - "dependencies (8)" - - "dependencies (11)" - - "lint" - - "units (7)" - - "units (8)" - - "units (11)" - - "Kokoro - Test: Integration" - - "cla/google" - -# Identifies the protection rule pattern. Name of the branch to be protected. -# Defaults to `master` -- pattern: 5.2.x - # Can admins overwrite branch protection. - # Defaults to `true` - isAdminEnforced: true - # Number of approving reviews required to update matching branches. - # Defaults to `1` - requiredApprovingReviewCount: 1 - # Are reviews from code owners required to update matching branches. - # Defaults to `false` - requiresCodeOwnerReviews: true - # Require up to date branches - requiresStrictStatusChecks: false - # List of required status check contexts that must pass for commits to be accepted to matching branches. - requiredStatusCheckContexts: - - "dependencies (8)" - - "dependencies (11)" - - "lint" - - "units (7)" - - "units (8)" - - "units (11)" - - "Kokoro - Test: Integration" - - "cla/google" - -# List of explicit permissions to add (additive only) + - pattern: master + isAdminEnforced: true + requiredApprovingReviewCount: 1 + requiresCodeOwnerReviews: true + requiresStrictStatusChecks: false + requiredStatusCheckContexts: + - dependencies (8) + - dependencies (11) + - linkage-monitor + - lint + - clirr + - units (8) + - units (11) + - 'Kokoro - Test: Integration' + - cla/google + - pattern: 3.1.x + isAdminEnforced: true + requiredApprovingReviewCount: 1 + requiresCodeOwnerReviews: true + requiresStrictStatusChecks: false + requiredStatusCheckContexts: + - dependencies (8) + - dependencies (11) + - lint + - units (7) + - units (8) + - units (11) + - 'Kokoro - Test: Integration' + - cla/google + - pattern: 3.3.x + isAdminEnforced: true + requiredApprovingReviewCount: 1 + requiresCodeOwnerReviews: true + requiresStrictStatusChecks: false + requiredStatusCheckContexts: + - dependencies (8) + - dependencies (11) + - lint + - units (7) + - units (8) + - units (11) + - 'Kokoro - Test: Integration' + - cla/google + - pattern: 4.0.x + isAdminEnforced: true + requiredApprovingReviewCount: 1 + requiresCodeOwnerReviews: true + requiresStrictStatusChecks: false + requiredStatusCheckContexts: + - dependencies (8) + - dependencies (11) + - lint + - units (7) + - units (8) + - units (11) + - 'Kokoro - Test: Integration' + - cla/google + - pattern: 5.2.x + isAdminEnforced: true + requiredApprovingReviewCount: 1 + requiresCodeOwnerReviews: true + requiresStrictStatusChecks: false + requiredStatusCheckContexts: + - dependencies (8) + - dependencies (11) + - lint + - units (7) + - units (8) + - units (11) + - 'Kokoro - Test: Integration' + - cla/google + - pattern: 3.3.3-sp + isAdminEnforced: true + requiredApprovingReviewCount: 1 + requiresCodeOwnerReviews: true + requiresStrictStatusChecks: false + requiredStatusCheckContexts: + - dependencies (8) + - dependencies (11) + - linkage-monitor + - lint + - clirr + - units (8) + - units (11) + - 'Kokoro - Test: Integration' + - cla/google permissionRules: -- team: yoshi-admins - permission: admin -- team: yoshi-java-admins - permission: admin -- team: yoshi-java - permission: push + - team: yoshi-admins + permission: admin + - team: yoshi-java-admins + permission: admin + - team: yoshi-java + permission: push From a3631358336b60fd58b323c945fa5bc161c2de3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Wed, 12 May 2021 09:34:29 +0200 Subject: [PATCH 21/27] build: remove custom skip tests variable (#1157) From ad6649df03a1a193dd524a84fe9dc1a72ed14e09 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Wed, 12 May 2021 09:34:46 +0200 Subject: [PATCH 22/27] deps: update dependency org.openjdk.jmh:jmh-generator-annprocess to v1.30 (#1138) --- google-cloud-spanner/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index ad37f479a99..79d06acc7c7 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -309,7 +309,7 @@ org.openjdk.jmh jmh-generator-annprocess - 1.29 + 1.30 test From 63eed2e66fb063358e8b123ba5f919663b70bbe4 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Wed, 12 May 2021 09:35:08 +0200 Subject: [PATCH 23/27] deps: update dependency com.google.cloud:google-cloud-monitoring to v2.2.2 (#1158) --- samples/install-without-bom/pom.xml | 2 +- samples/snapshot/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index 6e4f935b462..1e216f204c9 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -23,7 +23,7 @@ UTF-8 0.28.3 1.3.3 - 2.2.1 + 2.2.2 diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index c724f7148dd..f3b8a3a953c 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -23,7 +23,7 @@ UTF-8 0.28.3 1.3.3 - 2.2.1 + 2.2.2 From 43a0fb97352d928e16ec5138ed2ea494ebaae343 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Thu, 13 May 2021 05:27:22 +0200 Subject: [PATCH 24/27] deps: update dependency org.openjdk.jmh:jmh-core to v1.31 (#1160) --- google-cloud-spanner/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index 79d06acc7c7..b6dfc31115a 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -303,7 +303,7 @@ org.openjdk.jmh jmh-core - 1.30 + 1.31 test From 89dd784694d5ec7925e02d801595922b4339bb5e Mon Sep 17 00:00:00 2001 From: Thiago Nunes Date: Thu, 13 May 2021 14:16:51 +1000 Subject: [PATCH 25/27] chore: removes clirr/linkage-monitor from 3.3.3-sp (#1164) Removes clirr and linkage-monitor as required CI steps from the LTS version, since they do not support old versions (not HEAD) of the library. --- .github/sync-repo-settings.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index c9f626e58cb..76f7af948fc 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -81,9 +81,7 @@ branchProtectionRules: requiredStatusCheckContexts: - dependencies (8) - dependencies (11) - - linkage-monitor - lint - - clirr - units (8) - units (11) - 'Kokoro - Test: Integration' From 4d17da25977dde0cc1032192045d9ee26d3fae09 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Thu, 13 May 2021 09:07:45 +0200 Subject: [PATCH 26/27] deps: update dependency org.openjdk.jmh:jmh-generator-annprocess to v1.31 (#1161) --- google-cloud-spanner/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index b6dfc31115a..b0c5fd9fdc9 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -309,7 +309,7 @@ org.openjdk.jmh jmh-generator-annprocess - 1.30 + 1.31 test From 8476fe55139f76b32fca36926459983e9f25a786 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 13 May 2021 17:04:05 +0000 Subject: [PATCH 27/27] chore: release 6.4.1 (#1130) :robot: I have created a release \*beep\* \*boop\* --- ### [6.4.1](https://www.github.com/googleapis/java-spanner/compare/v6.4.0...v6.4.1) (2021-05-13) ### Documentation * close Spanner instance when it is no longer needed ([#1116](https://www.github.com/googleapis/java-spanner/issues/1116)) ([85bd0cf](https://www.github.com/googleapis/java-spanner/commit/85bd0cf11eab7b2ec47a082a4c2c0c4d9cea01d4)) ### Dependencies * update dependency com.google.cloud:google-cloud-monitoring to v2.2.2 ([#1158](https://www.github.com/googleapis/java-spanner/issues/1158)) ([63eed2e](https://www.github.com/googleapis/java-spanner/commit/63eed2e66fb063358e8b123ba5f919663b70bbe4)) * update dependency com.google.cloud:google-cloud-shared-dependencies to v1.1.0 ([#1152](https://www.github.com/googleapis/java-spanner/issues/1152)) ([2e7f18a](https://www.github.com/googleapis/java-spanner/commit/2e7f18a52ef2ed5de6a87169eeefd570844a4c55)) * update dependency org.openjdk.jmh:jmh-core to v1.30 ([#1137](https://www.github.com/googleapis/java-spanner/issues/1137)) ([699a426](https://www.github.com/googleapis/java-spanner/commit/699a4260e3b1a4cf53fc690910aeeadac293e469)) * update dependency org.openjdk.jmh:jmh-core to v1.31 ([#1160](https://www.github.com/googleapis/java-spanner/issues/1160)) ([43a0fb9](https://www.github.com/googleapis/java-spanner/commit/43a0fb97352d928e16ec5138ed2ea494ebaae343)) * update dependency org.openjdk.jmh:jmh-generator-annprocess to v1.30 ([#1138](https://www.github.com/googleapis/java-spanner/issues/1138)) ([ad6649d](https://www.github.com/googleapis/java-spanner/commit/ad6649df03a1a193dd524a84fe9dc1a72ed14e09)) * update dependency org.openjdk.jmh:jmh-generator-annprocess to v1.31 ([#1161](https://www.github.com/googleapis/java-spanner/issues/1161)) ([4d17da2](https://www.github.com/googleapis/java-spanner/commit/4d17da25977dde0cc1032192045d9ee26d3fae09)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --- CHANGELOG.md | 17 +++++++++++++++++ google-cloud-spanner-bom/pom.xml | 18 +++++++++--------- google-cloud-spanner/pom.xml | 4 ++-- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- grpc-google-cloud-spanner-v1/pom.xml | 4 ++-- pom.xml | 16 ++++++++-------- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- proto-google-cloud-spanner-v1/pom.xml | 4 ++-- samples/snapshot/pom.xml | 2 +- versions.txt | 14 +++++++------- 12 files changed, 56 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45edf5c84dd..7d5d7a5b50e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +### [6.4.1](https://www.github.com/googleapis/java-spanner/compare/v6.4.0...v6.4.1) (2021-05-13) + + +### Documentation + +* close Spanner instance when it is no longer needed ([#1116](https://www.github.com/googleapis/java-spanner/issues/1116)) ([85bd0cf](https://www.github.com/googleapis/java-spanner/commit/85bd0cf11eab7b2ec47a082a4c2c0c4d9cea01d4)) + + +### Dependencies + +* update dependency com.google.cloud:google-cloud-monitoring to v2.2.2 ([#1158](https://www.github.com/googleapis/java-spanner/issues/1158)) ([63eed2e](https://www.github.com/googleapis/java-spanner/commit/63eed2e66fb063358e8b123ba5f919663b70bbe4)) +* update dependency com.google.cloud:google-cloud-shared-dependencies to v1.1.0 ([#1152](https://www.github.com/googleapis/java-spanner/issues/1152)) ([2e7f18a](https://www.github.com/googleapis/java-spanner/commit/2e7f18a52ef2ed5de6a87169eeefd570844a4c55)) +* update dependency org.openjdk.jmh:jmh-core to v1.30 ([#1137](https://www.github.com/googleapis/java-spanner/issues/1137)) ([699a426](https://www.github.com/googleapis/java-spanner/commit/699a4260e3b1a4cf53fc690910aeeadac293e469)) +* update dependency org.openjdk.jmh:jmh-core to v1.31 ([#1160](https://www.github.com/googleapis/java-spanner/issues/1160)) ([43a0fb9](https://www.github.com/googleapis/java-spanner/commit/43a0fb97352d928e16ec5138ed2ea494ebaae343)) +* update dependency org.openjdk.jmh:jmh-generator-annprocess to v1.30 ([#1138](https://www.github.com/googleapis/java-spanner/issues/1138)) ([ad6649d](https://www.github.com/googleapis/java-spanner/commit/ad6649df03a1a193dd524a84fe9dc1a72ed14e09)) +* update dependency org.openjdk.jmh:jmh-generator-annprocess to v1.31 ([#1161](https://www.github.com/googleapis/java-spanner/issues/1161)) ([4d17da2](https://www.github.com/googleapis/java-spanner/commit/4d17da25977dde0cc1032192045d9ee26d3fae09)) + ## [6.4.0](https://www.github.com/googleapis/java-spanner/compare/v6.3.3...v6.4.0) (2021-04-29) diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml index 38df5cc9e60..a77d74ba67a 100644 --- a/google-cloud-spanner-bom/pom.xml +++ b/google-cloud-spanner-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner-bom - 6.4.1-SNAPSHOT + 6.4.1 pom com.google.cloud @@ -64,43 +64,43 @@ com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.4.1-SNAPSHOT + 6.4.1 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.4.1-SNAPSHOT + 6.4.1 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.4.1-SNAPSHOT + 6.4.1 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.4.1-SNAPSHOT + 6.4.1 com.google.cloud google-cloud-spanner - 6.4.1-SNAPSHOT + 6.4.1 com.google.cloud google-cloud-spanner test-jar - 6.4.1-SNAPSHOT + 6.4.1 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.4.1-SNAPSHOT + 6.4.1 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.4.1-SNAPSHOT + 6.4.1 diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index b0c5fd9fdc9..edc4a71dbb2 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner - 6.4.1-SNAPSHOT + 6.4.1 jar Google Cloud Spanner https://github.com/googleapis/java-spanner @@ -11,7 +11,7 @@ com.google.cloud google-cloud-spanner-parent - 6.4.1-SNAPSHOT + 6.4.1 google-cloud-spanner diff --git a/grpc-google-cloud-spanner-admin-database-v1/pom.xml b/grpc-google-cloud-spanner-admin-database-v1/pom.xml index 38bef9b5fb9..680cf43dfb9 100644 --- a/grpc-google-cloud-spanner-admin-database-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.4.1-SNAPSHOT + 6.4.1 grpc-google-cloud-spanner-admin-database-v1 GRPC library for grpc-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.4.1-SNAPSHOT + 6.4.1 diff --git a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml index 89afdb4ce23..80d9f95f2c2 100644 --- a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.4.1-SNAPSHOT + 6.4.1 grpc-google-cloud-spanner-admin-instance-v1 GRPC library for grpc-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.4.1-SNAPSHOT + 6.4.1 diff --git a/grpc-google-cloud-spanner-v1/pom.xml b/grpc-google-cloud-spanner-v1/pom.xml index b043645e76c..6f9a3e6a357 100644 --- a/grpc-google-cloud-spanner-v1/pom.xml +++ b/grpc-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.4.1-SNAPSHOT + 6.4.1 grpc-google-cloud-spanner-v1 GRPC library for grpc-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.4.1-SNAPSHOT + 6.4.1 diff --git a/pom.xml b/pom.xml index 8186d8e29ab..f5ebb525cf7 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-spanner-parent pom - 6.4.1-SNAPSHOT + 6.4.1 Google Cloud Spanner Parent https://github.com/googleapis/java-spanner @@ -71,37 +71,37 @@ com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.4.1-SNAPSHOT + 6.4.1 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.4.1-SNAPSHOT + 6.4.1 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.4.1-SNAPSHOT + 6.4.1 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.4.1-SNAPSHOT + 6.4.1 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.4.1-SNAPSHOT + 6.4.1 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.4.1-SNAPSHOT + 6.4.1 com.google.cloud google-cloud-spanner - 6.4.1-SNAPSHOT + 6.4.1 diff --git a/proto-google-cloud-spanner-admin-database-v1/pom.xml b/proto-google-cloud-spanner-admin-database-v1/pom.xml index f2a8f6fad2b..7a31167fd0b 100644 --- a/proto-google-cloud-spanner-admin-database-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.4.1-SNAPSHOT + 6.4.1 proto-google-cloud-spanner-admin-database-v1 PROTO library for proto-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.4.1-SNAPSHOT + 6.4.1 diff --git a/proto-google-cloud-spanner-admin-instance-v1/pom.xml b/proto-google-cloud-spanner-admin-instance-v1/pom.xml index 8f6a3f994fb..f3ed3a35564 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.4.1-SNAPSHOT + 6.4.1 proto-google-cloud-spanner-admin-instance-v1 PROTO library for proto-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.4.1-SNAPSHOT + 6.4.1 diff --git a/proto-google-cloud-spanner-v1/pom.xml b/proto-google-cloud-spanner-v1/pom.xml index 8a0a2fc784b..a6451e2abbe 100644 --- a/proto-google-cloud-spanner-v1/pom.xml +++ b/proto-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.4.1-SNAPSHOT + 6.4.1 proto-google-cloud-spanner-v1 PROTO library for proto-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.4.1-SNAPSHOT + 6.4.1 diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index f3b8a3a953c..15527da16d6 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -31,7 +31,7 @@ com.google.cloud google-cloud-spanner - 6.4.1-SNAPSHOT + 6.4.1 diff --git a/versions.txt b/versions.txt index 3ba665a3015..94fef63bde3 100644 --- a/versions.txt +++ b/versions.txt @@ -1,10 +1,10 @@ # Format: # module:released-version:current-version -proto-google-cloud-spanner-admin-instance-v1:6.4.0:6.4.1-SNAPSHOT -proto-google-cloud-spanner-v1:6.4.0:6.4.1-SNAPSHOT -proto-google-cloud-spanner-admin-database-v1:6.4.0:6.4.1-SNAPSHOT -grpc-google-cloud-spanner-v1:6.4.0:6.4.1-SNAPSHOT -grpc-google-cloud-spanner-admin-instance-v1:6.4.0:6.4.1-SNAPSHOT -grpc-google-cloud-spanner-admin-database-v1:6.4.0:6.4.1-SNAPSHOT -google-cloud-spanner:6.4.0:6.4.1-SNAPSHOT \ No newline at end of file +proto-google-cloud-spanner-admin-instance-v1:6.4.1:6.4.1 +proto-google-cloud-spanner-v1:6.4.1:6.4.1 +proto-google-cloud-spanner-admin-database-v1:6.4.1:6.4.1 +grpc-google-cloud-spanner-v1:6.4.1:6.4.1 +grpc-google-cloud-spanner-admin-instance-v1:6.4.1:6.4.1 +grpc-google-cloud-spanner-admin-database-v1:6.4.1:6.4.1 +google-cloud-spanner:6.4.1:6.4.1 \ No newline at end of file