From c2cd620a4b5ac6ef02f3a0e72d12494ab2a8757a Mon Sep 17 00:00:00 2001 From: dbolduc Date: Wed, 15 Mar 2023 19:35:52 -0400 Subject: [PATCH 1/3] feat(mocks): access options used by client call in tests --- google/cloud/google_cloud_cpp_common.cmake | 6 ++- .../google_cloud_cpp_common_unit_tests.bzl | 1 + google/cloud/google_cloud_cpp_mocks.bzl | 1 + google/cloud/mocks/current_options.h | 51 +++++++++++++++++++ google/cloud/mocks/current_options_test.cc | 47 +++++++++++++++++ google/cloud/mocks/mock_stream_range_test.cc | 2 + 6 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 google/cloud/mocks/current_options.h create mode 100644 google/cloud/mocks/current_options_test.cc diff --git a/google/cloud/google_cloud_cpp_common.cmake b/google/cloud/google_cloud_cpp_common.cmake index 7707653a45687..329332ca8fc6f 100644 --- a/google/cloud/google_cloud_cpp_common.cmake +++ b/google/cloud/google_cloud_cpp_common.cmake @@ -262,8 +262,9 @@ install( # for these, a regular library would not work on macOS (where the library needs # at least one .o file). add_library(google_cloud_cpp_mocks INTERFACE) -set(google_cloud_cpp_mocks_hdrs # cmake-format: sort - mocks/mock_stream_range.h) +set(google_cloud_cpp_mocks_hdrs + # cmake-format: sort + mocks/current_options.h mocks/mock_stream_range.h) export_list_to_bazel("google_cloud_cpp_mocks.bzl" "google_cloud_cpp_mocks_hdrs" YEAR "2022") target_link_libraries( @@ -367,6 +368,7 @@ if (BUILD_TESTING) internal/utility_test.cc kms_key_name_test.cc log_test.cc + mocks/current_options_test.cc mocks/mock_stream_range_test.cc options_test.cc polling_policy_test.cc diff --git a/google/cloud/google_cloud_cpp_common_unit_tests.bzl b/google/cloud/google_cloud_cpp_common_unit_tests.bzl index c4cbc18c936bc..2606cde49db3e 100644 --- a/google/cloud/google_cloud_cpp_common_unit_tests.bzl +++ b/google/cloud/google_cloud_cpp_common_unit_tests.bzl @@ -64,6 +64,7 @@ google_cloud_cpp_common_unit_tests = [ "internal/utility_test.cc", "kms_key_name_test.cc", "log_test.cc", + "mocks/current_options_test.cc", "mocks/mock_stream_range_test.cc", "options_test.cc", "polling_policy_test.cc", diff --git a/google/cloud/google_cloud_cpp_mocks.bzl b/google/cloud/google_cloud_cpp_mocks.bzl index 878e80e8c0d58..43e6367d85e18 100644 --- a/google/cloud/google_cloud_cpp_mocks.bzl +++ b/google/cloud/google_cloud_cpp_mocks.bzl @@ -17,5 +17,6 @@ """Automatically generated unit tests list - DO NOT EDIT.""" google_cloud_cpp_mocks_hdrs = [ + "mocks/current_options.h", "mocks/mock_stream_range.h", ] diff --git a/google/cloud/mocks/current_options.h b/google/cloud/mocks/current_options.h new file mode 100644 index 0000000000000..e7a3d07ce910b --- /dev/null +++ b/google/cloud/mocks/current_options.h @@ -0,0 +1,51 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_MOCKS_CURRENT_OPTIONS_H +#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_MOCKS_CURRENT_OPTIONS_H + +#include "google/cloud/options.h" + +namespace google { +namespace cloud { +namespace mocks { +GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN + +/** + * Retrieve options used in a client call. + * + * This would be used to verify configuration options from within a + * MockConnection. It provides a way for applications to test the difference + * between `client.Foo(request, options)` and `client.Foo(request)`. + * + * @code + * TEST(Foo, CallOptions) { + * auto mock = std::make_shared(); + * EXPECT_CALL(*mock, Foo).WillOnce([] { + * auto const& options = google::cloud::mocks::CurrentOptions(); + * EXPECT_THAT(options, ...); + * }); + * auto client = Client(mock); + * DoThing(client); + * } + * @endcode + */ +Options CurrentOptions() { return internal::CurrentOptions(); } + +GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END +} // namespace mocks +} // namespace cloud +} // namespace google + +#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_MOCKS_CURRENT_OPTIONS_H diff --git a/google/cloud/mocks/current_options_test.cc b/google/cloud/mocks/current_options_test.cc new file mode 100644 index 0000000000000..118ca82b0be65 --- /dev/null +++ b/google/cloud/mocks/current_options_test.cc @@ -0,0 +1,47 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "google/cloud/mocks/current_options.h" +#include "google/cloud/testing_util/status_matchers.h" +#include + +namespace google { +namespace cloud { +namespace mocks { +GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN +namespace { + +TEST(CurrentOptionsTest, Basic) { + struct IntOption { + using Type = int; + }; + + EXPECT_FALSE(CurrentOptions().has()); + { + internal::OptionsSpan span(Options{}.set(1)); + EXPECT_EQ(CurrentOptions().get(), 1); + { + internal::OptionsSpan span(Options{}.set(2)); + EXPECT_EQ(CurrentOptions().get(), 2); + } + EXPECT_EQ(CurrentOptions().get(), 1); + } + EXPECT_FALSE(CurrentOptions().has()); +} + +} // namespace +GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END +} // namespace mocks +} // namespace cloud +} // namespace google diff --git a/google/cloud/mocks/mock_stream_range_test.cc b/google/cloud/mocks/mock_stream_range_test.cc index 938309646561a..fe95d938921d3 100644 --- a/google/cloud/mocks/mock_stream_range_test.cc +++ b/google/cloud/mocks/mock_stream_range_test.cc @@ -20,6 +20,7 @@ namespace google { namespace cloud { namespace mocks { GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN +namespace { using ::google::cloud::testing_util::StatusIs; using ::testing::ElementsAre; @@ -69,6 +70,7 @@ TEST(MakeStreamRangeTest, ValuesThenStatus) { EXPECT_THAT(result.final_status, StatusIs(StatusCode::kAborted)); } +} // namespace GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace mocks } // namespace cloud From c4a9f36fe6879f5ea32bea837cd3f3fd0b0517f5 Mon Sep 17 00:00:00 2001 From: dbolduc Date: Wed, 15 Mar 2023 23:23:53 -0400 Subject: [PATCH 2/3] address review comments; fix ODR --- google/cloud/mocks/current_options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google/cloud/mocks/current_options.h b/google/cloud/mocks/current_options.h index e7a3d07ce910b..761eed5559f79 100644 --- a/google/cloud/mocks/current_options.h +++ b/google/cloud/mocks/current_options.h @@ -41,7 +41,7 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN * } * @endcode */ -Options CurrentOptions() { return internal::CurrentOptions(); } +inline Options const& CurrentOptions() { return internal::CurrentOptions(); } GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace mocks From 5cda982f28fc54b313ffc4fe9975c37290644fd3 Mon Sep 17 00:00:00 2001 From: dbolduc Date: Wed, 15 Mar 2023 23:53:44 -0400 Subject: [PATCH 3/3] address review comments --- google/cloud/mocks/current_options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google/cloud/mocks/current_options.h b/google/cloud/mocks/current_options.h index 761eed5559f79..5f35ee8d593a4 100644 --- a/google/cloud/mocks/current_options.h +++ b/google/cloud/mocks/current_options.h @@ -37,7 +37,7 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN * EXPECT_THAT(options, ...); * }); * auto client = Client(mock); - * DoThing(client); + * MyFunctionThatCallsFoo(client); * } * @endcode */