Skip to content

Commit f66a62f

Browse files
authored
feat(spanner): add integration tests for proto columns (#13756)
1 parent 44c6ad9 commit f66a62f

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

google/cloud/spanner/integration_tests/data_types_integration_test.cc

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717
#include "google/cloud/spanner/database.h"
1818
#include "google/cloud/spanner/mutations.h"
1919
#include "google/cloud/spanner/testing/database_integration_test.h"
20+
#include "google/cloud/spanner/testing/singer.pb.h"
2021
#include "google/cloud/spanner/timestamp.h"
2122
#include "google/cloud/testing_util/status_matchers.h"
2223
#include "absl/time/time.h"
2324
#include <gmock/gmock.h>
25+
#include <cstdint>
26+
#include <string>
2427
#include <vector>
2528

2629
namespace google {
@@ -43,6 +46,16 @@ absl::Time MakeTime(std::time_t sec, int nanos) {
4346
return absl::FromTimeT(sec) + absl::Nanoseconds(nanos);
4447
}
4548

49+
testing::SingerInfo MakeSinger(std::int64_t singer_id, std::string birth_date,
50+
std::string nationality, testing::Genre genre) {
51+
testing::SingerInfo singer;
52+
singer.set_singer_id(singer_id);
53+
singer.set_birth_date(std::move(birth_date));
54+
singer.set_nationality(std::move(nationality));
55+
singer.set_genre(genre);
56+
return singer;
57+
}
58+
4659
// A helper function used in the test fixtures below. This function writes the
4760
// given data to the DataTypes table, then it reads all the data back and
4861
// returns it to the caller.
@@ -292,6 +305,30 @@ TEST_F(PgDataTypeIntegrationTest, WriteReadNumeric) {
292305
EXPECT_THAT(result, IsOkAndHolds(UnorderedElementsAreArray(data)));
293306
}
294307

308+
TEST_F(DataTypeIntegrationTest, WriteReadProtoEnum) {
309+
if (UsingEmulator()) GTEST_SKIP() << "emulator does not support PROTO";
310+
311+
std::vector<ProtoEnum<testing::Genre>> const data = {
312+
testing::Genre::POP,
313+
testing::Genre::JAZZ,
314+
testing::Genre::FOLK,
315+
testing::Genre::ROCK,
316+
};
317+
auto result = WriteReadData(*client_, data, "SingerGenre");
318+
EXPECT_THAT(result, IsOkAndHolds(UnorderedElementsAreArray(data)));
319+
}
320+
321+
TEST_F(DataTypeIntegrationTest, WriteReadProtoMessage) {
322+
if (UsingEmulator()) GTEST_SKIP() << "emulator does not support PROTO";
323+
324+
std::vector<ProtoMessage<testing::SingerInfo>> const data = {
325+
MakeSinger(1, "1817-05-25", "French", testing::Genre::FOLK),
326+
MakeSinger(2123139547, "1942-06-18", "British", testing::Genre::POP),
327+
};
328+
auto result = WriteReadData(*client_, data, "SingerInfo");
329+
EXPECT_THAT(result, IsOkAndHolds(UnorderedElementsAreArray(data)));
330+
}
331+
295332
TEST_F(DataTypeIntegrationTest, WriteReadArrayBool) {
296333
std::vector<std::vector<bool>> const data = {
297334
std::vector<bool>{},
@@ -434,6 +471,36 @@ TEST_F(PgDataTypeIntegrationTest, WriteReadArrayNumeric) {
434471
EXPECT_THAT(result, IsOkAndHolds(UnorderedElementsAreArray(data)));
435472
}
436473

474+
TEST_F(DataTypeIntegrationTest, WriteReadArrayProtoEnum) {
475+
if (UsingEmulator()) GTEST_SKIP() << "emulator does not support PROTO";
476+
477+
std::vector<std::vector<ProtoEnum<testing::Genre>>> const data = {
478+
std::vector<ProtoEnum<testing::Genre>>{},
479+
std::vector<ProtoEnum<testing::Genre>>{
480+
testing::Genre::POP,
481+
testing::Genre::JAZZ,
482+
testing::Genre::FOLK,
483+
testing::Genre::ROCK,
484+
},
485+
};
486+
auto result = WriteReadData(*client_, data, "ArraySingerGenre");
487+
EXPECT_THAT(result, IsOkAndHolds(UnorderedElementsAreArray(data)));
488+
}
489+
490+
TEST_F(DataTypeIntegrationTest, WriteReadArrayProtoMessage) {
491+
if (UsingEmulator()) GTEST_SKIP() << "emulator does not support PROTO";
492+
493+
std::vector<std::vector<ProtoMessage<testing::SingerInfo>>> const data = {
494+
std::vector<ProtoMessage<testing::SingerInfo>>{},
495+
std::vector<ProtoMessage<testing::SingerInfo>>{
496+
MakeSinger(1, "1817-05-25", "French", testing::Genre::FOLK),
497+
MakeSinger(2123139547, "1942-06-18", "British", testing::Genre::POP),
498+
},
499+
};
500+
auto result = WriteReadData(*client_, data, "ArraySingerInfo");
501+
EXPECT_THAT(result, IsOkAndHolds(UnorderedElementsAreArray(data)));
502+
}
503+
437504
TEST_F(DataTypeIntegrationTest, JsonIndexAndPrimaryKey) {
438505
spanner_admin::DatabaseAdminClient admin_client(
439506
spanner_admin::MakeDatabaseAdminConnection());
@@ -573,6 +640,25 @@ TEST_F(PgDataTypeIntegrationTest, NumericPrimaryKey) {
573640
HasSubstr("part of the primary key"))));
574641
}
575642

643+
TEST_F(DataTypeIntegrationTest, InsertAndQueryWithProtoEnumKey) {
644+
if (UsingEmulator()) GTEST_SKIP() << "emulator does not support PROTO";
645+
646+
auto& client = *client_;
647+
auto const key = testing::Genre::POP;
648+
649+
auto commit_result = client.Commit(
650+
Mutations{InsertOrUpdateMutationBuilder("ProtoEnumKey", {"Key"})
651+
.EmplaceRow(key)
652+
.Build()});
653+
ASSERT_STATUS_OK(commit_result);
654+
655+
auto rows = client.Read("ProtoEnumKey", KeySet::All(), {"Key"});
656+
using RowType = std::tuple<ProtoEnum<testing::Genre>>;
657+
auto row = GetSingularRow(StreamOf<RowType>(rows));
658+
ASSERT_STATUS_OK(row);
659+
EXPECT_EQ(std::get<0>(*std::move(row)), key);
660+
}
661+
576662
TEST_F(DataTypeIntegrationTest, DmlReturning) {
577663
if (UsingEmulator()) GTEST_SKIP() << "emulator does not support THEN RETURN";
578664

google/cloud/spanner/testing/database_integration_test.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "google/cloud/spanner/testing/cleanup_stale_databases.h"
1818
#include "google/cloud/spanner/testing/pick_random_instance.h"
1919
#include "google/cloud/spanner/testing/random_database_name.h"
20+
#include "google/cloud/spanner/testing/singer.pb.h"
2021
#include "google/cloud/internal/getenv.h"
2122
#include "google/cloud/testing_util/status_matchers.h"
2223
#include <chrono>
@@ -96,12 +97,52 @@ void DatabaseIntegrationTest::SetUpTestSuite() {
9697
ArrayNumericValue ARRAY<NUMERIC>
9798
) PRIMARY KEY (Id)
9899
)sql");
100+
if (!emulator_) { // proto columns
101+
google::protobuf::FileDescriptorSet fds;
102+
google::cloud::spanner::testing::SingerInfo::default_instance()
103+
.GetMetadata()
104+
.descriptor->file()
105+
->CopyTo(fds.add_file());
106+
fds.SerializeToString(request.mutable_proto_descriptors());
107+
request.add_extra_statements(R"sql(
108+
CREATE PROTO BUNDLE (
109+
google.cloud.spanner.testing.SingerInfo,
110+
google.cloud.spanner.testing.Genre,
111+
)
112+
)sql");
113+
request.add_extra_statements(R"sql(
114+
ALTER TABLE DataTypes
115+
ADD COLUMN SingerInfo google.cloud.spanner.testing.SingerInfo
116+
)sql");
117+
request.add_extra_statements(R"sql(
118+
ALTER TABLE DataTypes
119+
ADD COLUMN SingerGenre google.cloud.spanner.testing.Genre
120+
)sql");
121+
request.add_extra_statements(R"sql(
122+
ALTER TABLE DataTypes
123+
ADD COLUMN ArraySingerInfo
124+
ARRAY<google.cloud.spanner.testing.SingerInfo>
125+
)sql");
126+
request.add_extra_statements(R"sql(
127+
ALTER TABLE DataTypes
128+
ADD COLUMN ArraySingerGenre
129+
ARRAY<google.cloud.spanner.testing.Genre>
130+
)sql");
131+
}
99132
// Verify that NUMERIC can be used as a table key.
100133
request.add_extra_statements(R"sql(
101134
CREATE TABLE NumericKey (
102135
Key NUMERIC NOT NULL
103136
) PRIMARY KEY (Key)
104137
)sql");
138+
if (!emulator_) { // proto columns
139+
// Verify that ProtoEnum<T> can be used as a table key.
140+
request.add_extra_statements(R"sql(
141+
CREATE TABLE ProtoEnumKey (
142+
Key google.cloud.spanner.testing.Genre NOT NULL
143+
) PRIMARY KEY (Key)
144+
)sql");
145+
}
105146
auto database_future = admin_client.CreateDatabase(request);
106147

107148
int i = 0;

0 commit comments

Comments
 (0)