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