Skip to content

Commit 61d9e43

Browse files
committed
test: add integration test
1 parent 051dc62 commit 61d9e43

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

google/cloud/spanner/integration_tests/client_integration_test.cc

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
#include "google/cloud/spanner/client.h"
1717
#include "google/cloud/spanner/database.h"
1818
#include "google/cloud/spanner/mutations.h"
19+
#include "google/cloud/spanner/options.h"
1920
#include "google/cloud/spanner/testing/database_integration_test.h"
2021
#include "google/cloud/credentials.h"
2122
#include "google/cloud/internal/random.h"
23+
#include "google/cloud/log.h"
2224
#include "google/cloud/testing_util/status_matchers.h"
2325
#include <gmock/gmock.h>
2426
#include <map>
@@ -36,6 +38,7 @@ using ::google::cloud::testing_util::IsOk;
3638
using ::google::cloud::testing_util::StatusIs;
3739
using ::testing::AllOf;
3840
using ::testing::AnyOf;
41+
using ::testing::Contains;
3942
using ::testing::Eq;
4043
using ::testing::Ge;
4144
using ::testing::HasSubstr;
@@ -768,6 +771,49 @@ void CheckExecuteQueryWithSingleUseOptions(
768771
EXPECT_THAT(actual_rows, UnorderedElementsAreArray(expected_rows));
769772
}
770773

774+
/// @test Verify the `ReadLockMode` option is sent in the RPC by creating a
775+
/// situation where a transaction A perfomrs a commit while a transaction B
776+
/// performed one after tx A started.
777+
TEST_F(ClientIntegrationTest, ReadLockModeOptionIsSent) {
778+
if (UsingEmulator()) {
779+
GTEST_SKIP() << "Optimistic locks not supported by emulator";
780+
}
781+
auto const singer_id = 101;
782+
783+
auto mutation_helper = [singer_id] (std::string new_name) {
784+
return Mutations{MakeInsertOrUpdateMutation("Singers", {"SingerId", "FirstName"}, singer_id, new_name)};
785+
};
786+
787+
// initial insert
788+
auto insert = client_->Commit(mutation_helper("InitialName"));
789+
ASSERT_STATUS_OK(insert);
790+
791+
// transaction A will do a DML after another transaction has executed DML
792+
// If optimistic, we expect transaction A to be aborted
793+
auto test_helper = [&mutation_helper, singer_id] (Transaction::ReadLockMode read_lock_mode) -> StatusOr<CommitResult> {
794+
// here we create tx A and confirm it can perform a read.
795+
auto tx_a = MakeReadWriteTransaction(Transaction::ReadWriteOptions(read_lock_mode));
796+
auto tx_a_read_result = client_->Read(tx_a, "Singers", KeySet().AddKey(MakeKey(singer_id)), {"SingerId"});
797+
for (auto row : StreamOf<std::tuple<std::int64_t>>(tx_a_read_result)) {
798+
EXPECT_STATUS_OK(row);
799+
}
800+
801+
// now a separate tx b will perform a write operation before tx A is finished.
802+
auto tx_b = client_->Commit(mutation_helper("FirstModifiedName"));
803+
EXPECT_STATUS_OK(tx_b);
804+
805+
// depending on the read lock mode, the result of the next write operation
806+
// in tx A will vary.
807+
return client_->Commit(tx_a, mutation_helper("SecondModifiedName"));
808+
};
809+
810+
auto optimistic_result = test_helper(Transaction::ReadLockMode::kOptimistic);
811+
auto pessimistic_result = test_helper(Transaction::ReadLockMode::kPessimistic);
812+
813+
EXPECT_STATUS_OK(pessimistic_result);
814+
EXPECT_THAT(optimistic_result, StatusIs(StatusCode::kAborted));
815+
}
816+
771817
/// @test Test ExecuteQuery() with bounded staleness set by a timestamp.
772818
TEST_F(ClientIntegrationTest, ExecuteQueryBoundedStalenessTimestamp) {
773819
CheckExecuteQueryWithSingleUseOptions(

0 commit comments

Comments
 (0)