xref: /aosp_15_r20/external/federated-compute/fcp/base/monitoring_test.cc (revision 14675a029014e728ec732f129a32e299b2da0601)
1 /*
2  * Copyright 2017 Google LLC
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "fcp/base/monitoring.h"
18 
19 #include <stdio.h>
20 
21 #include <array>
22 #include <memory>
23 #include <string>
24 #include <utility>
25 
26 #include "gmock/gmock.h"
27 #include "gtest/gtest.h"
28 #include "absl/base/log_severity.h"
29 #include "absl/strings/str_format.h"
30 #include "fcp/base/base_name.h"
31 
32 namespace fcp {
33 namespace {
34 
35 using ::testing::Eq;
36 using ::testing::MatchesRegex;
37 using ::testing::Not;
38 
39 MATCHER(IsOk, "") { return arg.ok(); }
40 
41 MATCHER_P(IsOkAndHolds, m, "") {
42   return testing::ExplainMatchResult(IsOk(), arg, result_listener) &&
43          testing::ExplainMatchResult(m, arg.value(), result_listener);
44 }
45 
46 class BaremetalLogger final : public internal::Logger {
47  public:
Log(const char * file,int line,LogSeverity severity,const char * message)48   void Log(const char* file, int line, LogSeverity severity,
49            const char* message) override {
50     absl::FPrintF(stderr, "%c %s:%d %s\n",
51                   absl::LogSeverityName(static_cast<absl::LogSeverity>(
52                       static_cast<int>(severity)))[0],
53                   BaseName(file), line, message);
54   }
55 };
56 
57 class MonitoringTest : public ::testing::TestWithParam<bool> {
58  public:
SetUp()59   void SetUp() override {
60     if (replace_logger_) {
61       prev_logger_ = internal::logger();
62       internal::set_logger(&logger_);
63     }
64   }
TearDown()65   void TearDown() override {
66     if (replace_logger_) {
67       internal::set_logger(prev_logger_);
68     }
69   }
70 
71  private:
72   const bool replace_logger_ = GetParam();
73   internal::Logger* prev_logger_ = nullptr;
74   BaremetalLogger logger_;
75 };
76 
77 #ifdef FCP_BAREMETAL
78 INSTANTIATE_TEST_SUITE_P(Baremetal, MonitoringTest, testing::Values(true));
79 #else
80 INSTANTIATE_TEST_SUITE_P(Base, MonitoringTest, testing::Values(false));
81 #endif
82 
TEST_P(MonitoringTest,LogInfo)83 TEST_P(MonitoringTest, LogInfo) {
84   testing::internal::CaptureStderr();
85   FCP_LOG(INFO) << "info log of something happening";
86   std::string output = testing::internal::GetCapturedStderr();
87   ASSERT_THAT(output, MatchesRegex("I.*info log of something happening\n"));
88 }
89 
TEST_P(MonitoringTest,LogWarning)90 TEST_P(MonitoringTest, LogWarning) {
91   testing::internal::CaptureStderr();
92   FCP_LOG(WARNING) << "warning log of something happening";
93   std::string output = testing::internal::GetCapturedStderr();
94   ASSERT_THAT(output, MatchesRegex("W.*warning log of something happening\n"));
95 }
96 
TEST_P(MonitoringTest,LogError)97 TEST_P(MonitoringTest, LogError) {
98   testing::internal::CaptureStderr();
99   FCP_LOG(ERROR) << "error log of something happening";
100   std::string output = testing::internal::GetCapturedStderr();
101   ASSERT_THAT(output, MatchesRegex("E.*error log of something happening\n"));
102 }
103 
TEST_P(MonitoringTest,LogFatal)104 TEST_P(MonitoringTest, LogFatal) {
105   ASSERT_DEATH({ FCP_LOG(FATAL) << "fatal log"; }, "fatal log");
106 }
107 
TEST_P(MonitoringTest,StatusBuilderLogInfo)108 TEST_P(MonitoringTest, StatusBuilderLogInfo) {
109   testing::internal::CaptureStderr();
110   Status status = (FCP_STATUS(ABORTED) << "something happened").LogInfo();
111   std::string output = testing::internal::GetCapturedStderr();
112   ASSERT_THAT(output, MatchesRegex("I.*something happened\n"));
113 }
114 
TEST_P(MonitoringTest,StatusBuilderLogWarning)115 TEST_P(MonitoringTest, StatusBuilderLogWarning) {
116   testing::internal::CaptureStderr();
117   Status status = (FCP_STATUS(ABORTED) << "something happened").LogWarning();
118   std::string output = testing::internal::GetCapturedStderr();
119   ASSERT_THAT(output, MatchesRegex("W.*something happened\n"));
120 }
121 
TEST_P(MonitoringTest,StatusBuilderLogError)122 TEST_P(MonitoringTest, StatusBuilderLogError) {
123   testing::internal::CaptureStderr();
124   Status status = (FCP_STATUS(ABORTED) << "something happened").LogError();
125   std::string output = testing::internal::GetCapturedStderr();
126   ASSERT_THAT(output, MatchesRegex("E.*something happened\n"));
127 }
128 
TEST_P(MonitoringTest,StatusBuilderLogFatal)129 TEST_P(MonitoringTest, StatusBuilderLogFatal) {
130   ASSERT_DEATH(
131       {
132         Status status =
133             (FCP_STATUS(ABORTED) << "something happened").LogFatal();
134       },
135       "something happened");
136 }
137 
TEST_P(MonitoringTest,LogIfTrue)138 TEST_P(MonitoringTest, LogIfTrue) {
139   testing::internal::CaptureStderr();
140   FCP_LOG_IF(INFO, true) << "some log";
141   std::string output = testing::internal::GetCapturedStderr();
142   ASSERT_THAT(output, MatchesRegex("I.*some log\n"));
143 }
144 
TEST_P(MonitoringTest,LogIfFalse)145 TEST_P(MonitoringTest, LogIfFalse) {
146   testing::internal::CaptureStderr();
147   FCP_LOG_IF(INFO, false) << "some log";
148   std::string output = testing::internal::GetCapturedStderr();
149   ASSERT_EQ(output, "");
150 }
151 
TEST_P(MonitoringTest,CheckSucceeds)152 TEST_P(MonitoringTest, CheckSucceeds) { FCP_CHECK(1 < 2); }
153 
TEST_P(MonitoringTest,CheckFails)154 TEST_P(MonitoringTest, CheckFails) {
155   ASSERT_DEATH({ FCP_CHECK(1 < 0); }, "Check failed: 1 < 0.");
156 }
157 
TEST_P(MonitoringTest,StatusOr)158 TEST_P(MonitoringTest, StatusOr) {
159   StatusOr<int> default_constructed_status;
160   ASSERT_FALSE(default_constructed_status.ok());
161   ASSERT_EQ(default_constructed_status.status().code(), UNKNOWN);
162 
163   StatusOr<int> fail_status = FCP_STATUS(ABORTED) << "operation aborted";
164   ASSERT_FALSE(fail_status.ok());
165   ASSERT_EQ(fail_status.status().code(), ABORTED);
166   // TODO(team): Port StatusIs matcher to avoid casting message(),
167   // which is string_view, to std::string.
168   ASSERT_THAT(fail_status.status().message(),
169               MatchesRegex(".*operation aborted"));
170 }
171 
TEST_P(MonitoringTest,StatusOrCopyAssignment)172 TEST_P(MonitoringTest, StatusOrCopyAssignment) {
173   StatusOr<int> fail_status = FCP_STATUS(ABORTED) << "operation aborted";
174   StatusOr<int> copy_of_fail_status(fail_status);
175   ASSERT_FALSE(copy_of_fail_status.ok());
176   ASSERT_EQ(copy_of_fail_status.status().code(), ABORTED);
177   ASSERT_THAT(copy_of_fail_status.status().message(),
178               MatchesRegex(".*operation aborted"));
179 
180   StatusOr<int> ok_status = 42;
181   StatusOr<int> copy_of_ok_status(ok_status);
182   ASSERT_THAT(copy_of_ok_status, IsOkAndHolds(Eq(42)));
183   ASSERT_EQ(copy_of_ok_status.value(), 42);
184 }
185 
TEST_P(MonitoringTest,StatusOrMoveAssignment)186 TEST_P(MonitoringTest, StatusOrMoveAssignment) {
187   StatusOr<std::unique_ptr<std::string>> fail_status = FCP_STATUS(ABORTED)
188                                                        << "operation aborted";
189   StatusOr<std::unique_ptr<std::string>> moved_fail_status(
190       std::move(fail_status));
191   ASSERT_FALSE(moved_fail_status.ok());
192   ASSERT_EQ(moved_fail_status.status().code(), ABORTED);
193   ASSERT_THAT(moved_fail_status.status().message(),
194               MatchesRegex(".*operation aborted"));
195 
196   auto value = std::make_unique<std::string>("foobar");
197   StatusOr<std::unique_ptr<std::string>> ok_status = std::move(value);
198   StatusOr<std::unique_ptr<std::string>> moved_ok_status(std::move(ok_status));
199   ASSERT_TRUE(moved_ok_status.ok());
200   ASSERT_EQ(*moved_ok_status.value(), "foobar");
201 }
202 
TEST_P(MonitoringTest,StatusOrCopying)203 TEST_P(MonitoringTest, StatusOrCopying) {
204   StatusOr<int> fail_status = FCP_STATUS(ABORTED) << "operation aborted";
205   StatusOr<int> copy_of_status = fail_status;
206   ASSERT_FALSE(copy_of_status.ok());
207   ASSERT_EQ(copy_of_status.status().code(), ABORTED);
208   ASSERT_THAT(copy_of_status.status().message(),
209               MatchesRegex(".*operation aborted"));
210 
211   StatusOr<int> ok_status = 42;
212   copy_of_status = ok_status;
213   ASSERT_THAT(copy_of_status, IsOkAndHolds(Eq(42)));
214   ASSERT_EQ(copy_of_status.value(), 42);
215 }
216 
TEST_P(MonitoringTest,StatusOrMoving)217 TEST_P(MonitoringTest, StatusOrMoving) {
218   StatusOr<std::unique_ptr<std::string>> fail_status = FCP_STATUS(ABORTED)
219                                                        << "operation aborted";
220   StatusOr<std::unique_ptr<std::string>> moved_status = std::move(fail_status);
221   ASSERT_FALSE(moved_status.ok());
222   ASSERT_EQ(moved_status.status().code(), ABORTED);
223   ASSERT_THAT(moved_status.status().message(),
224               MatchesRegex(".*operation aborted"));
225 
226   auto value = std::make_unique<std::string>("foobar");
227   StatusOr<std::unique_ptr<std::string>> ok_status = std::move(value);
228   moved_status = std::move(ok_status);
229   ASSERT_TRUE(moved_status.ok());
230   ASSERT_EQ(*moved_status.value(), "foobar");
231 }
232 
TEST_P(MonitoringTest,StatusBuilder)233 TEST_P(MonitoringTest, StatusBuilder) {
234   ASSERT_FALSE(FCP_STATUS(ABORTED).ok());
235   ASSERT_EQ(FCP_STATUS(ABORTED).code(), ABORTED);
236 }
237 
TEST_P(MonitoringTest,FcpReturnIfError)238 TEST_P(MonitoringTest, FcpReturnIfError) {
239   ASSERT_THAT(
240       []() -> StatusOr<int> {
241         Status fail_status = FCP_STATUS(ABORTED);
242         FCP_RETURN_IF_ERROR(fail_status);
243         return 0;
244       }(),
245       Not(IsOk()));
246   ASSERT_THAT(
247       []() -> StatusOr<int> {
248         FCP_RETURN_IF_ERROR(Status());
249         return 0;
250       }(),
251       IsOkAndHolds(0));
252 
253   ASSERT_THAT(
254       []() -> StatusOr<int> {
255         StatusOr<int> fail_statusor = FCP_STATUS(ABORTED);
256         FCP_RETURN_IF_ERROR(fail_statusor);
257         return 0;
258       }(),
259       Not(IsOk()));
260   ASSERT_THAT(
261       []() -> StatusOr<int> {
262         FCP_RETURN_IF_ERROR(StatusOr<int>(0));
263         return 0;
264       }(),
265       IsOkAndHolds(0));
266 }
267 
268 }  // namespace
269 }  // namespace fcp
270