| // Copyright 2021 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/lib/util/status_builder.h" |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| #ifdef HAVE_GLOG |
| #include <string> |
| #include <vector> |
| |
| #include <glog/logging.h> |
| #endif // HAVE_GLOG |
| |
| namespace cobalt { |
| |
| using testing::HasSubstr; |
| |
| TEST(StatusBuilder, Ok) { |
| Status status = util::StatusBuilder(StatusCode::OK).Build(); |
| ASSERT_EQ(StatusCode::OK, status.error_code()); |
| } |
| |
| TEST(StatusBuilder, BasicConstructor) { |
| Status status = util::StatusBuilder(StatusCode::INTERNAL, "Internal error").Build(); |
| ASSERT_EQ(StatusCode::INTERNAL, status.error_code()); |
| ASSERT_EQ("Internal error", status.error_message()); |
| } |
| |
| TEST(StatusBuilder, SetCodeWorks) { |
| Status status = util::StatusBuilder(StatusCode::OK).SetCode(StatusCode::INVALID_ARGUMENT).Build(); |
| ASSERT_EQ(StatusCode::INVALID_ARGUMENT, status.error_code()); |
| } |
| |
| TEST(StatusBuilder, WithContextWorks) { |
| Status status = util::StatusBuilder(StatusCode::RESOURCE_EXHAUSTED) |
| .WithContext("number", 10) |
| .WithContext("string", "value") |
| .WithContext("bool", true) |
| .Build(); |
| ASSERT_EQ(StatusCode::RESOURCE_EXHAUSTED, status.error_code()); |
| ASSERT_THAT(status.error_details(), HasSubstr("number=10")); |
| ASSERT_THAT(status.error_details(), HasSubstr("string=value")); |
| ASSERT_THAT(status.error_details(), HasSubstr("bool=1")); |
| } |
| |
| TEST(StatusBuilder, AppendMsgWorks) { |
| Status status = |
| util::StatusBuilder(StatusCode::UNIMPLEMENTED, "Base msg").AppendMsg(" more message").Build(); |
| ASSERT_EQ(StatusCode::UNIMPLEMENTED, status.error_code()); |
| ASSERT_EQ(status.error_message(), "Base msg more message"); |
| } |
| |
| TEST(StatusBuilder, ContextFormatterWorks) { |
| ReportDefinition rd; |
| rd.set_report_name("Report name"); |
| Status status = util::StatusBuilder(StatusCode::UNIMPLEMENTED) |
| .WithContexts(rd) |
| .WithContext("CustomName", rd) |
| .Build(); |
| ASSERT_EQ(StatusCode::UNIMPLEMENTED, status.error_code()); |
| ASSERT_THAT(status.error_details(), HasSubstr("Report=Report name")); |
| ASSERT_THAT(status.error_details(), HasSubstr("CustomName=Report name")); |
| } |
| |
| namespace { |
| struct TestStruct { |
| int v; |
| float v2; |
| }; |
| |
| } // namespace |
| namespace util { |
| template <> |
| class ContextFormatter<TestStruct> { |
| public: |
| explicit ContextFormatter(const TestStruct &v) : v_(v) {} |
| inline static std::string default_key() { return "TestStruct"; } |
| inline void write_value(std::ostream &stream) const { |
| stream << "V(" << v_.v << "/" << v_.v2 << ")"; |
| } |
| |
| private: |
| const TestStruct &v_; |
| }; |
| |
| } // namespace util |
| |
| TEST(StatusBuilder, CustomContextFormatter) { |
| TestStruct ts; |
| ts.v = 100; |
| ts.v2 = 12.10f; |
| Status status = util::StatusBuilder(StatusCode::ABORTED) |
| .WithContexts(ts) |
| .WithContext("local_name", ts) |
| .Build(); |
| ASSERT_EQ(StatusCode::ABORTED, status.error_code()); |
| ASSERT_THAT(status.error_details(), HasSubstr("TestStruct=V(100/12.1)")); |
| ASSERT_THAT(status.error_details(), HasSubstr("local_name=V(100/12.1)")); |
| } |
| |
| // Testing the logging code. Currently only runs on platforms with GLOG. |
| #ifdef HAVE_GLOG |
| |
| class LogSink : public ::google::LogSink { |
| public: |
| std::vector<std::string> errors; |
| void send(::google::LogSeverity severity, const char *full_filename, const char *base_filename, |
| int line, const struct ::tm *tm_time, const char *message, |
| size_t message_len) override { |
| errors.push_back(ToString(severity, base_filename, line, tm_time, message, message_len)); |
| } |
| }; |
| |
| void ConstructAndDrop(util::StatusBuilder builder) { std::move(builder).Build(); } |
| |
| TEST(StatusBuilder, LogWorks) { |
| LogSink sink; |
| ::google::AddLogSink(&sink); |
| |
| ConstructAndDrop( |
| util::StatusBuilder(StatusCode::NOT_FOUND, "Msg1").Log(util::StatusBuilder::LogLevel::ERROR)); |
| ConstructAndDrop(util::StatusBuilder(StatusCode::NOT_FOUND, "Msg2").LogError()); |
| ConstructAndDrop(util::StatusBuilder(StatusCode::NOT_FOUND, "Msg3").LogWarning()); |
| ConstructAndDrop(util::StatusBuilder(StatusCode::NOT_FOUND, "Msg4").LogInfo()); |
| |
| ASSERT_EQ(size_t{4}, sink.errors.size()); |
| ASSERT_THAT(sink.errors[0], HasSubstr("NOT_FOUND: Msg1")); |
| ASSERT_THAT(sink.errors[1], HasSubstr("NOT_FOUND: Msg2")); |
| ASSERT_THAT(sink.errors[2], HasSubstr("NOT_FOUND: Msg3")); |
| ASSERT_THAT(sink.errors[3], HasSubstr("NOT_FOUND: Msg4")); |
| |
| ::google::RemoveLogSink(&sink); |
| } |
| |
| #endif // HAVE_GLOG |
| |
| } // namespace cobalt |