Add some of the basic status matchers for QUICHE. Status matchers are commonly used inside google3, but the open-source version of Abseil/gtest does not ship those. This CL contains the most basic ones (IsOk, IsOkAndHolds and two-argument version of StatusIs). Since we are using Status/StatusOr more widely these days, this will be helpful for writing unit tests and porting the existing ones. PiperOrigin-RevId: 502628290
diff --git a/build/source_list.bzl b/build/source_list.bzl index 0db8800..91be1a0 100644 --- a/build/source_list.bzl +++ b/build/source_list.bzl
@@ -1048,6 +1048,7 @@ "common/simple_buffer_allocator_test.cc", "common/structured_headers_generated_test.cc", "common/structured_headers_test.cc", + "common/test_tools/quiche_test_utils_test.cc", "http2/adapter/event_forwarder_test.cc", "http2/adapter/header_validator_test.cc", "http2/adapter/noop_header_validator_test.cc",
diff --git a/build/source_list.gni b/build/source_list.gni index 62962e7..965802a 100644 --- a/build/source_list.gni +++ b/build/source_list.gni
@@ -1048,6 +1048,7 @@ "src/quiche/common/simple_buffer_allocator_test.cc", "src/quiche/common/structured_headers_generated_test.cc", "src/quiche/common/structured_headers_test.cc", + "src/quiche/common/test_tools/quiche_test_utils_test.cc", "src/quiche/http2/adapter/event_forwarder_test.cc", "src/quiche/http2/adapter/header_validator_test.cc", "src/quiche/http2/adapter/noop_header_validator_test.cc",
diff --git a/build/source_list.json b/build/source_list.json index e7cde56..a79092f 100644 --- a/build/source_list.json +++ b/build/source_list.json
@@ -1047,6 +1047,7 @@ "quiche/common/simple_buffer_allocator_test.cc", "quiche/common/structured_headers_generated_test.cc", "quiche/common/structured_headers_test.cc", + "quiche/common/test_tools/quiche_test_utils_test.cc", "quiche/http2/adapter/event_forwarder_test.cc", "quiche/http2/adapter/header_validator_test.cc", "quiche/http2/adapter/noop_header_validator_test.cc",
diff --git a/quiche/common/test_tools/quiche_test_utils.h b/quiche/common/test_tools/quiche_test_utils.h index c233051..d35ed7f 100644 --- a/quiche/common/test_tools/quiche_test_utils.h +++ b/quiche/common/test_tools/quiche_test_utils.h
@@ -7,6 +7,8 @@ #include <string> +#include "absl/status/status.h" +#include "absl/status/statusor.h" #include "absl/strings/string_view.h" #include "quiche/common/platform/api/quiche_iovec.h" #include "quiche/common/platform/api/quiche_test.h" @@ -27,16 +29,44 @@ // This function checks if IDNAs are supported. bool GoogleUrlSupportsIdnaForTest(); +// Takes either a Status or StatusOr<T>, and returns just the Status. +inline const absl::Status& ExtractStatus(const absl::Status& status) { + return status; +} +template <typename T> +const absl::Status& ExtractStatus(const absl::StatusOr<T>& status_or) { + return status_or.status(); +} + // Abseil does not provide absl::Status-related macros, so we have to provide // those instead. MATCHER(IsOk, "Checks if an instance of absl::Status is ok.") { if (arg.ok()) { return true; } - *result_listener << "Expected status OK, got " << arg; + *result_listener << "Expected status OK, got " << ExtractStatus(arg); return false; } +MATCHER_P(IsOkAndHolds, matcher, + "Matcher against the inner value of absl::StatusOr") { + if (!arg.ok()) { + *result_listener << "Expected status OK, got " << arg.status(); + return false; + } + return ::testing::ExplainMatchResult(matcher, arg.value(), result_listener); +} + +MATCHER_P2(StatusIs, code, matcher, "Matcher against a specific status code") { + if (ExtractStatus(arg).code() != code) { + *result_listener << "Expected status " << absl::StatusCodeToString(code) + << ", got " << ExtractStatus(arg); + return false; + } + return ::testing::ExplainMatchResult(matcher, ExtractStatus(arg).message(), + result_listener); +} + #define QUICHE_EXPECT_OK(arg) EXPECT_THAT((arg), ::quiche::test::IsOk()) #define QUICHE_ASSERT_OK(arg) ASSERT_THAT((arg), ::quiche::test::IsOk())
diff --git a/quiche/common/test_tools/quiche_test_utils_test.cc b/quiche/common/test_tools/quiche_test_utils_test.cc new file mode 100644 index 0000000..17427a5 --- /dev/null +++ b/quiche/common/test_tools/quiche_test_utils_test.cc
@@ -0,0 +1,37 @@ +#include "quiche/common/test_tools/quiche_test_utils.h" + +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "quiche/common/platform/api/quiche_test.h" + +namespace quiche::test { +namespace { + +using ::testing::HasSubstr; +using ::testing::Not; + +TEST(QuicheTestUtilsTest, StatusMatchers) { + const absl::Status ok = absl::OkStatus(); + QUICHE_EXPECT_OK(ok); + QUICHE_ASSERT_OK(ok); + EXPECT_THAT(ok, IsOk()); + + const absl::StatusOr<int> ok_with_value = 2023; + QUICHE_EXPECT_OK(ok_with_value); + QUICHE_ASSERT_OK(ok_with_value); + EXPECT_THAT(ok_with_value, IsOk()); + EXPECT_THAT(ok_with_value, IsOkAndHolds(2023)); + + const absl::Status err = absl::InternalError("test error"); + EXPECT_THAT(err, Not(IsOk())); + EXPECT_THAT(err, StatusIs(absl::StatusCode::kInternal, HasSubstr("test"))); + + const absl::StatusOr<int> err_with_value = absl::InternalError("test error"); + EXPECT_THAT(err_with_value, Not(IsOk())); + EXPECT_THAT(err_with_value, Not(IsOkAndHolds(2023))); + EXPECT_THAT(err_with_value, + StatusIs(absl::StatusCode::kInternal, HasSubstr("test"))); +} + +} // namespace +} // namespace quiche::test