1 //
2 // Copyright 2021 the gRPC authors.
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 "src/core/lib/gprpp/status_helper.h"
18
19 #include <stddef.h>
20
21 #include "absl/status/status.h"
22 #include "absl/strings/str_cat.h"
23 #include "absl/time/civil_time.h"
24 #include "absl/time/clock.h"
25 #include "gmock/gmock.h"
26 #include "google/rpc/status.upb.h"
27 #include "gtest/gtest.h"
28 #include "upb/mem/arena.hpp"
29
30 namespace grpc_core {
31 namespace {
32
TEST(StatusUtilTest,CreateStatus)33 TEST(StatusUtilTest, CreateStatus) {
34 absl::Status s =
35 StatusCreate(absl::StatusCode::kUnknown, "Test", DEBUG_LOCATION,
36 {absl::OkStatus(), absl::CancelledError()});
37 EXPECT_EQ(absl::StatusCode::kUnknown, s.code());
38 EXPECT_EQ("Test", s.message());
39 #ifndef NDEBUG
40 EXPECT_EQ(true, StatusGetStr(s, StatusStrProperty::kFile).has_value());
41 EXPECT_EQ(true, StatusGetInt(s, StatusIntProperty::kFileLine).has_value());
42 #endif
43 EXPECT_EQ(true, StatusGetTime(s, StatusTimeProperty::kCreated).has_value());
44 EXPECT_THAT(StatusGetChildren(s),
45 ::testing::ElementsAre(absl::CancelledError()));
46 }
47
TEST(StatusUtilTest,SetAndGetInt)48 TEST(StatusUtilTest, SetAndGetInt) {
49 absl::Status s = absl::CancelledError();
50 StatusSetInt(&s, StatusIntProperty::kErrorNo, 2021);
51 EXPECT_EQ(2021, StatusGetInt(s, StatusIntProperty::kErrorNo));
52 }
53
TEST(StatusUtilTest,GetIntNotExistent)54 TEST(StatusUtilTest, GetIntNotExistent) {
55 absl::Status s = absl::CancelledError();
56 EXPECT_EQ(absl::optional<intptr_t>(),
57 StatusGetInt(s, StatusIntProperty::kErrorNo));
58 }
59
TEST(StatusUtilTest,SetAndGetStr)60 TEST(StatusUtilTest, SetAndGetStr) {
61 absl::Status s = absl::CancelledError();
62 StatusSetStr(&s, StatusStrProperty::kOsError, "value");
63 EXPECT_EQ("value", StatusGetStr(s, StatusStrProperty::kOsError));
64 }
65
TEST(StatusUtilTest,GetStrNotExistent)66 TEST(StatusUtilTest, GetStrNotExistent) {
67 absl::Status s = absl::CancelledError();
68 EXPECT_EQ(absl::optional<std::string>(),
69 StatusGetStr(s, StatusStrProperty::kOsError));
70 }
71
TEST(StatusUtilTest,SetAndGetTime)72 TEST(StatusUtilTest, SetAndGetTime) {
73 absl::Status s = absl::CancelledError();
74 absl::Time t = absl::Now();
75 StatusSetTime(&s, StatusTimeProperty::kCreated, t);
76 EXPECT_EQ(t, StatusGetTime(s, StatusTimeProperty::kCreated));
77 }
78
TEST(StatusUtilTest,GetTimeNotExistent)79 TEST(StatusUtilTest, GetTimeNotExistent) {
80 absl::Status s = absl::CancelledError();
81 EXPECT_EQ(absl::optional<absl::Time>(),
82 StatusGetTime(s, StatusTimeProperty::kCreated));
83 }
84
TEST(StatusUtilTest,AddAndGetChildren)85 TEST(StatusUtilTest, AddAndGetChildren) {
86 absl::Status s = absl::CancelledError();
87 absl::Status child1 = absl::AbortedError("Message1");
88 absl::Status child2 = absl::DeadlineExceededError("Message2");
89 absl::Status child3 = absl::UnimplementedError("");
90 StatusAddChild(&s, child1);
91 StatusAddChild(&s, child2);
92 StatusAddChild(&s, child3);
93 EXPECT_THAT(StatusGetChildren(s),
94 ::testing::ElementsAre(child1, child2, child3));
95 }
96
TEST(StatusUtilTest,ToAndFromProto)97 TEST(StatusUtilTest, ToAndFromProto) {
98 absl::Status s = absl::CancelledError("Message");
99 StatusSetInt(&s, StatusIntProperty::kErrorNo, 2021);
100 StatusSetStr(&s, StatusStrProperty::kOsError, "value");
101 upb::Arena arena;
102 google_rpc_Status* msg = internal::StatusToProto(s, arena.ptr());
103 size_t len;
104 const char* buf = google_rpc_Status_serialize(msg, arena.ptr(), &len);
105 google_rpc_Status* msg2 = google_rpc_Status_parse(buf, len, arena.ptr());
106 absl::Status s2 = internal::StatusFromProto(msg2);
107 EXPECT_EQ(s, s2);
108 }
109
TEST(StatusUtilTest,ToAndFromProtoWithNonUTF8Characters)110 TEST(StatusUtilTest, ToAndFromProtoWithNonUTF8Characters) {
111 absl::Status s = absl::CancelledError("_\xAB\xCD\xEF_");
112 StatusSetInt(&s, StatusIntProperty::kErrorNo, 2021);
113 StatusSetStr(&s, StatusStrProperty::kOsError, "!\xFF\xCC\xAA!");
114 upb::Arena arena;
115 google_rpc_Status* msg = internal::StatusToProto(s, arena.ptr());
116 size_t len;
117 const char* buf = google_rpc_Status_serialize(msg, arena.ptr(), &len);
118 google_rpc_Status* msg2 = google_rpc_Status_parse(buf, len, arena.ptr());
119 absl::Status s2 = internal::StatusFromProto(msg2);
120 EXPECT_EQ(s, s2);
121 }
122
TEST(StatusUtilTest,OkToString)123 TEST(StatusUtilTest, OkToString) {
124 absl::Status s;
125 std::string t = StatusToString(s);
126 EXPECT_EQ("OK", t);
127 }
128
TEST(StatusUtilTest,CancelledErrorToString)129 TEST(StatusUtilTest, CancelledErrorToString) {
130 absl::Status s = absl::CancelledError();
131 std::string t = StatusToString(s);
132 EXPECT_EQ("CANCELLED", t);
133 }
134
TEST(StatusUtilTest,ErrorWithIntPropertyToString)135 TEST(StatusUtilTest, ErrorWithIntPropertyToString) {
136 absl::Status s = absl::CancelledError("Message");
137 StatusSetInt(&s, StatusIntProperty::kErrorNo, 2021);
138 std::string t = StatusToString(s);
139 EXPECT_EQ("CANCELLED:Message {errno:2021}", t);
140 }
141
TEST(StatusUtilTest,ErrorWithStrPropertyToString)142 TEST(StatusUtilTest, ErrorWithStrPropertyToString) {
143 absl::Status s = absl::CancelledError("Message");
144 StatusSetStr(&s, StatusStrProperty::kDescription, "Hey");
145 std::string t = StatusToString(s);
146 EXPECT_EQ("CANCELLED:Message {description:\"Hey\"}", t);
147 }
148
TEST(StatusUtilTest,ErrorWithTimePropertyToString)149 TEST(StatusUtilTest, ErrorWithTimePropertyToString) {
150 absl::Status s = absl::CancelledError("Message");
151 absl::Time t = absl::FromCivil(absl::CivilSecond(2021, 4, 29, 8, 56, 30),
152 absl::LocalTimeZone());
153 StatusSetTime(&s, StatusTimeProperty::kCreated, t);
154 EXPECT_EQ(StatusToString(s),
155 absl::StrCat("CANCELLED:Message {created_time:\"",
156 absl::FormatTime(t), "\"}"));
157 }
158
TEST(StatusUtilTest,ComplexErrorWithChildrenToString)159 TEST(StatusUtilTest, ComplexErrorWithChildrenToString) {
160 absl::Status s = absl::CancelledError("Message");
161 StatusSetInt(&s, StatusIntProperty::kErrorNo, 2021);
162 absl::Status s1 = absl::AbortedError("Message1");
163 StatusAddChild(&s, s1);
164 absl::Status s2 = absl::AlreadyExistsError("Message2");
165 StatusSetStr(&s2, StatusStrProperty::kOsError, "value");
166 StatusAddChild(&s, s2);
167 std::string t = StatusToString(s);
168 EXPECT_EQ(
169 "CANCELLED:Message {errno:2021, children:["
170 "ABORTED:Message1, ALREADY_EXISTS:Message2 {os_error:\"value\"}]}",
171 t);
172 }
173
TEST(StatusUtilTest,AllocHeapPtr)174 TEST(StatusUtilTest, AllocHeapPtr) {
175 absl::Status statuses[] = {absl::OkStatus(), absl::CancelledError(),
176 absl::AbortedError("Message")};
177 for (const auto& s : statuses) {
178 uintptr_t p = internal::StatusAllocHeapPtr(s);
179 EXPECT_EQ(s, internal::StatusGetFromHeapPtr(p));
180 internal::StatusFreeHeapPtr(p);
181 }
182 }
183
TEST(StatusUtilTest,MoveHeapPtr)184 TEST(StatusUtilTest, MoveHeapPtr) {
185 absl::Status statuses[] = {absl::OkStatus(), absl::CancelledError(),
186 absl::AbortedError("Message")};
187 for (const auto& s : statuses) {
188 uintptr_t p = internal::StatusAllocHeapPtr(s);
189 EXPECT_EQ(s, internal::StatusMoveFromHeapPtr(p));
190 }
191 }
192
193 } // namespace
194 } // namespace grpc_core
195
main(int argc,char ** argv)196 int main(int argc, char** argv) {
197 ::testing::InitGoogleTest(&argc, argv);
198 int ret = RUN_ALL_TESTS();
199 return ret;
200 }
201