xref: /aosp_15_r20/external/grpc-grpc/test/core/iomgr/error_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 //
3 // Copyright 2017 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18 
19 #include "src/core/lib/iomgr/error.h"
20 
21 #include <string.h>
22 
23 #include <gmock/gmock.h>
24 
25 #include <grpc/grpc.h>
26 #include <grpc/support/alloc.h>
27 #include <grpc/support/log.h>
28 
29 #include "src/core/lib/gprpp/crash.h"
30 #include "test/core/util/test_config.h"
31 
TEST(ErrorTest,SetGetInt)32 TEST(ErrorTest, SetGetInt) {
33   grpc_error_handle error = GRPC_ERROR_CREATE("Test");
34   EXPECT_NE(error, absl::OkStatus());
35   intptr_t i = 0;
36 #ifndef NDEBUG
37   // grpc_core::StatusIntProperty::kFileLine is for debug only
38   EXPECT_TRUE(
39       grpc_error_get_int(error, grpc_core::StatusIntProperty::kFileLine, &i));
40   EXPECT_TRUE(i);  // line set will never be 0
41 #endif
42   EXPECT_TRUE(
43       !grpc_error_get_int(error, grpc_core::StatusIntProperty::kErrorNo, &i));
44   EXPECT_TRUE(
45       !grpc_error_get_int(error, grpc_core::StatusIntProperty::kSize, &i));
46 
47   intptr_t errnumber = 314;
48   error = grpc_error_set_int(error, grpc_core::StatusIntProperty::kErrorNo,
49                              errnumber);
50   EXPECT_TRUE(
51       grpc_error_get_int(error, grpc_core::StatusIntProperty::kErrorNo, &i));
52   EXPECT_EQ(i, errnumber);
53 
54   intptr_t http = 2;
55   error = grpc_error_set_int(error, grpc_core::StatusIntProperty::kHttp2Error,
56                              http);
57   EXPECT_TRUE(
58       grpc_error_get_int(error, grpc_core::StatusIntProperty::kHttp2Error, &i));
59   EXPECT_EQ(i, http);
60 }
61 
TEST(ErrorTest,SetGetStr)62 TEST(ErrorTest, SetGetStr) {
63   grpc_error_handle error = GRPC_ERROR_CREATE("Test");
64 
65   std::string str;
66   EXPECT_TRUE(
67       !grpc_error_get_str(error, grpc_core::StatusStrProperty::kSyscall, &str));
68   EXPECT_TRUE(!grpc_error_get_str(
69       error, grpc_core::StatusStrProperty::kTsiError, &str));
70 #ifndef NDEBUG
71   // grpc_core::StatusStrProperty::kFile   is for debug only
72   EXPECT_TRUE(
73       grpc_error_get_str(error, grpc_core::StatusStrProperty::kFile, &str));
74   EXPECT_THAT(str, testing::HasSubstr("error_test.c"));
75   // __FILE__ expands differently on
76   // Windows. All should at least
77   // contain error_test.c
78 #endif
79   EXPECT_TRUE(grpc_error_get_str(
80       error, grpc_core::StatusStrProperty::kDescription, &str));
81   EXPECT_EQ(str, "Test");
82 
83   error = grpc_error_set_str(error, grpc_core::StatusStrProperty::kGrpcMessage,
84                              "longer message");
85   EXPECT_TRUE(grpc_error_get_str(
86       error, grpc_core::StatusStrProperty::kGrpcMessage, &str));
87   EXPECT_EQ(str, "longer message");
88 }
89 
TEST(ErrorTest,CopyAndUnRef)90 TEST(ErrorTest, CopyAndUnRef) {
91   // error1 has one ref
92   grpc_error_handle error1 =
93       grpc_error_set_str(GRPC_ERROR_CREATE("Test"),
94                          grpc_core::StatusStrProperty::kGrpcMessage, "message");
95   std::string str;
96   EXPECT_TRUE(grpc_error_get_str(
97       error1, grpc_core::StatusStrProperty::kGrpcMessage, &str));
98   EXPECT_EQ(str, "message");
99 
100   // this gives error3 a ref to the new error, and decrements error1 to one ref
101   grpc_error_handle error3 = grpc_error_set_str(
102       error1, grpc_core::StatusStrProperty::kSyscall, "syscall");
103   EXPECT_NE(error3, error1);  // should not be the same because of extra ref
104   EXPECT_TRUE(grpc_error_get_str(
105       error3, grpc_core::StatusStrProperty::kGrpcMessage, &str));
106   EXPECT_EQ(str, "message");
107 
108   // error 1 should not have a syscall but 3 should
109   EXPECT_TRUE(!grpc_error_get_str(
110       error1, grpc_core::StatusStrProperty::kSyscall, &str));
111   EXPECT_TRUE(
112       grpc_error_get_str(error3, grpc_core::StatusStrProperty::kSyscall, &str));
113   EXPECT_EQ(str, "syscall");
114 }
115 
TEST(ErrorTest,CreateReferencing)116 TEST(ErrorTest, CreateReferencing) {
117   grpc_error_handle child =
118       grpc_error_set_str(GRPC_ERROR_CREATE("Child"),
119                          grpc_core::StatusStrProperty::kGrpcMessage, "message");
120   grpc_error_handle parent = GRPC_ERROR_CREATE_REFERENCING("Parent", &child, 1);
121   EXPECT_NE(parent, absl::OkStatus());
122 }
123 
TEST(ErrorTest,CreateReferencingMany)124 TEST(ErrorTest, CreateReferencingMany) {
125   grpc_error_handle children[3];
126   children[0] =
127       grpc_error_set_str(GRPC_ERROR_CREATE("Child1"),
128                          grpc_core::StatusStrProperty::kGrpcMessage, "message");
129   children[1] =
130       grpc_error_set_int(GRPC_ERROR_CREATE("Child2"),
131                          grpc_core::StatusIntProperty::kHttp2Error, 5);
132   children[2] = grpc_error_set_str(GRPC_ERROR_CREATE("Child3"),
133                                    grpc_core::StatusStrProperty::kGrpcMessage,
134                                    "message 3");
135 
136   grpc_error_handle parent =
137       GRPC_ERROR_CREATE_REFERENCING("Parent", children, 3);
138   EXPECT_NE(parent, absl::OkStatus());
139 
140   for (size_t i = 0; i < 3; ++i) {
141   }
142 }
143 
TEST(ErrorTest,PrintErrorString)144 TEST(ErrorTest, PrintErrorString) {
145   grpc_error_handle error = grpc_error_set_int(
146       GRPC_ERROR_CREATE("Error"), grpc_core::StatusIntProperty::kRpcStatus,
147       GRPC_STATUS_UNIMPLEMENTED);
148   error = grpc_error_set_int(error, grpc_core::StatusIntProperty::kSize, 666);
149   error = grpc_error_set_str(error, grpc_core::StatusStrProperty::kGrpcMessage,
150                              "message");
151   // gpr_log(GPR_DEBUG, "%s", grpc_core::StatusToString(error).c_str());
152 }
153 
TEST(ErrorTest,PrintErrorStringReference)154 TEST(ErrorTest, PrintErrorStringReference) {
155   grpc_error_handle children[2];
156   children[0] = grpc_error_set_str(
157       grpc_error_set_int(GRPC_ERROR_CREATE("1"),
158                          grpc_core::StatusIntProperty::kRpcStatus,
159                          GRPC_STATUS_UNIMPLEMENTED),
160       grpc_core::StatusStrProperty::kGrpcMessage, "message for child 1");
161   children[1] = grpc_error_set_str(
162       grpc_error_set_int(GRPC_ERROR_CREATE("2sd"),
163                          grpc_core::StatusIntProperty::kRpcStatus,
164                          GRPC_STATUS_INTERNAL),
165       grpc_core::StatusStrProperty::kGrpcMessage, "message for child 2");
166 
167   grpc_error_handle parent =
168       GRPC_ERROR_CREATE_REFERENCING("Parent", children, 2);
169 
170   for (size_t i = 0; i < 2; ++i) {
171   }
172 }
173 
TEST(ErrorTest,TestOsError)174 TEST(ErrorTest, TestOsError) {
175   int fake_errno = 5;
176   const char* syscall = "syscall name";
177   grpc_error_handle error = GRPC_OS_ERROR(fake_errno, syscall);
178 
179   intptr_t i = 0;
180   EXPECT_TRUE(
181       grpc_error_get_int(error, grpc_core::StatusIntProperty::kErrorNo, &i));
182   EXPECT_EQ(i, fake_errno);
183 
184   std::string str;
185   EXPECT_TRUE(
186       grpc_error_get_str(error, grpc_core::StatusStrProperty::kSyscall, &str));
187   EXPECT_EQ(str, syscall);
188 }
189 
main(int argc,char ** argv)190 int main(int argc, char** argv) {
191   grpc::testing::TestEnvironment env(&argc, argv);
192   ::testing::InitGoogleTest(&argc, argv);
193   grpc_init();
194   int retval = RUN_ALL_TESTS();
195   grpc_shutdown();
196   return retval;
197 }
198