Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ using ::google::cloud::testing_util::IsOkAndHolds;
using ::google::cloud::testing_util::StatusIs;
using ::testing::AnyOf;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::HasSubstr;
using ::testing::ResultOf;
using ::testing::UnorderedElementsAreArray;
Expand Down Expand Up @@ -495,6 +496,69 @@ TEST_F(DataTypeIntegrationTest, WriteReadArrayTimestamp) {
EXPECT_THAT(result, IsOkAndHolds(UnorderedElementsAreArray(data)));
}

TEST_F(DataTypeIntegrationTest, SelectIntervalScalar) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integration tests for a new Spanner type should include an addition to the DataTypes table in testing/database_integration_test.cc, and "WriteRead{,Array}" test cases in this file to exercise the new column.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reasons I am not privy to, the Interval data type cannot be used as a column in a table.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integration tests for a new Spanner type should include additions to MutationsTests.SpannerTypes in mutations_test.cc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand it, mutations can only be performed on table columns.

if (UsingEmulator()) GTEST_SKIP();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Spanner integrations tests have been written to expect particular behavior from the emulator, even it is an error, rather than just skipping the test altogether. See all the other UsingEmulator() calls in this file, for example. This allows us to learn when the emulator changes behavior and react accordingly, rather than just forgetting about the whole issue forever more.

[It also helped the emulator team, who (at least previously) ran our tests to check their implementation. Rather than just seeing successes no matter what they did, expecting the old (error) behavior allowed them to verify that things had indeed changed, and also to compare their new behavior to that of the service.]

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

created #15162

auto expected_interval = MakeInterval("1-2 3 4:5:6.789123456");
ASSERT_STATUS_OK(expected_interval);

auto select = SqlStatement(R"sql(
SELECT INTERVAL '1-2 3 4:5:6.789123456' YEAR TO SECOND;)sql",
{});

auto result = client_->ExecuteQuery(std::move(select));
for (auto& row : StreamOf<std::tuple<Interval>>(result)) {
ASSERT_STATUS_OK(row);
EXPECT_THAT(std::get<0>(row.value()), Eq(*expected_interval));
}
}

TEST_F(DataTypeIntegrationTest, SelectIntervalArray) {
if (UsingEmulator()) GTEST_SKIP();
auto expected_interval = MakeInterval("1-2 3 4:5:6.789123456");
ASSERT_STATUS_OK(expected_interval);

auto select = SqlStatement(R"sql(
SELECT ARRAY<INTERVAL>[INTERVAL '1-2 3 4:5:6.789123456' YEAR TO SECOND];)sql",
{});

auto result = client_->ExecuteQuery(std::move(select));
for (auto& row : StreamOf<std::tuple<std::vector<Interval>>>(result)) {
ASSERT_STATUS_OK(row);
EXPECT_THAT(std::get<0>(row.value()).front(), Eq(*expected_interval));
}
}

TEST_F(DataTypeIntegrationTest, SelectIntervalFromTimestampDiff) {
if (UsingEmulator()) GTEST_SKIP();
Interval expected_interval{
std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::hours(1))};
std::time_t now_seconds =
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
std::time_t one_hour_later_seconds = now_seconds + 3600;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do chrono arithmetic in the chrono domain.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

created #15163


std::vector<std::vector<Timestamp>> const data = {std::vector<Timestamp>{
MakeTimestamp(MakeTime(now_seconds, 0)).value(),
MakeTimestamp(MakeTime(one_hour_later_seconds, 0)).value()}};
auto result = WriteReadData(*client_, data, "ArrayTimestampValue");
EXPECT_THAT(result, IsOkAndHolds(UnorderedElementsAreArray(data)));

auto statement = SqlStatement(R"sql(
SELECT
CAST(ARRAY_LAST(ArrayTimestampValue) - ARRAY_FIRST(ArrayTimestampValue)
AS INTERVAL) as v1
FROM DataTypes;
)sql",
{});

auto query_result = client_->ExecuteQuery(std::move(statement));
using RowType = std::tuple<Interval>;
for (auto& row : StreamOf<RowType>(query_result)) {
ASSERT_STATUS_OK(row);
EXPECT_THAT(std::get<0>(row.value()), Eq(expected_interval));
}
}

TEST_F(DataTypeIntegrationTest, WriteReadArrayDate) {
std::vector<std::vector<absl::CivilDay>> const data = {
std::vector<absl::CivilDay>{},
Expand Down
Loading