• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <grpc/grpc.h>
22 #include <grpc/support/alloc.h>
23 #include <grpc/support/log.h>
24 
25 #include <string.h>
26 
27 #include "test/core/util/test_config.h"
28 
test_set_get_int()29 static void test_set_get_int() {
30   grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test");
31   GPR_ASSERT(error);
32   intptr_t i = 0;
33   GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_FILE_LINE, &i));
34   GPR_ASSERT(i);  // line set will never be 0
35   GPR_ASSERT(!grpc_error_get_int(error, GRPC_ERROR_INT_ERRNO, &i));
36   GPR_ASSERT(!grpc_error_get_int(error, GRPC_ERROR_INT_SIZE, &i));
37 
38   intptr_t errnumber = 314;
39   error = grpc_error_set_int(error, GRPC_ERROR_INT_ERRNO, errnumber);
40   GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_ERRNO, &i));
41   GPR_ASSERT(i == errnumber);
42 
43   intptr_t http = 2;
44   error = grpc_error_set_int(error, GRPC_ERROR_INT_HTTP2_ERROR, http);
45   GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_HTTP2_ERROR, &i));
46   GPR_ASSERT(i == http);
47 
48   GRPC_ERROR_UNREF(error);
49 }
50 
test_set_get_str()51 static void test_set_get_str() {
52   grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test");
53 
54   grpc_slice str;
55   GPR_ASSERT(!grpc_error_get_str(error, GRPC_ERROR_STR_SYSCALL, &str));
56   GPR_ASSERT(!grpc_error_get_str(error, GRPC_ERROR_STR_TSI_ERROR, &str));
57 
58   GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_FILE, &str));
59   GPR_ASSERT(strstr((char*)GRPC_SLICE_START_PTR(str),
60                     "error_test.c"));  // __FILE__ expands differently on
61                                        // Windows. All should at least
62                                        // contain error_test.c
63 
64   GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION, &str));
65   GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), "Test",
66                       GRPC_SLICE_LENGTH(str)));
67 
68   error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE,
69                              grpc_slice_from_static_string("longer message"));
70   GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, &str));
71   GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), "longer message",
72                       GRPC_SLICE_LENGTH(str)));
73 
74   GRPC_ERROR_UNREF(error);
75 }
76 
test_copy_and_unref()77 static void test_copy_and_unref() {
78   // error1 has one ref
79   grpc_error* error1 = grpc_error_set_str(
80       GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test"), GRPC_ERROR_STR_GRPC_MESSAGE,
81       grpc_slice_from_static_string("message"));
82   grpc_slice str;
83   GPR_ASSERT(grpc_error_get_str(error1, GRPC_ERROR_STR_GRPC_MESSAGE, &str));
84   GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), "message",
85                       GRPC_SLICE_LENGTH(str)));
86 
87   // error 1 has two refs
88   GRPC_ERROR_REF(error1);
89   // this gives error3 a ref to the new error, and decrements error1 to one ref
90   grpc_error* error3 = grpc_error_set_str(
91       error1, GRPC_ERROR_STR_SYSCALL, grpc_slice_from_static_string("syscall"));
92   GPR_ASSERT(error3 != error1);  // should not be the same because of extra ref
93   GPR_ASSERT(grpc_error_get_str(error3, GRPC_ERROR_STR_GRPC_MESSAGE, &str));
94   GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), "message",
95                       GRPC_SLICE_LENGTH(str)));
96 
97   // error 1 should not have a syscall but 3 should
98   GPR_ASSERT(!grpc_error_get_str(error1, GRPC_ERROR_STR_SYSCALL, &str));
99   GPR_ASSERT(grpc_error_get_str(error3, GRPC_ERROR_STR_SYSCALL, &str));
100   GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), "syscall",
101                       GRPC_SLICE_LENGTH(str)));
102 
103   GRPC_ERROR_UNREF(error1);
104   GRPC_ERROR_UNREF(error3);
105 }
106 
test_create_referencing()107 static void test_create_referencing() {
108   grpc_error* child = grpc_error_set_str(
109       GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child"),
110       GRPC_ERROR_STR_GRPC_MESSAGE, grpc_slice_from_static_string("message"));
111   grpc_error* parent =
112       GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Parent", &child, 1);
113   GPR_ASSERT(parent);
114 
115   GRPC_ERROR_UNREF(child);
116   GRPC_ERROR_UNREF(parent);
117 }
118 
test_create_referencing_many()119 static void test_create_referencing_many() {
120   grpc_error* children[3];
121   children[0] = grpc_error_set_str(
122       GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child1"),
123       GRPC_ERROR_STR_GRPC_MESSAGE, grpc_slice_from_static_string("message"));
124   children[1] =
125       grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child2"),
126                          GRPC_ERROR_INT_HTTP2_ERROR, 5);
127   children[2] = grpc_error_set_str(
128       GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child3"),
129       GRPC_ERROR_STR_GRPC_MESSAGE, grpc_slice_from_static_string("message 3"));
130 
131   grpc_error* parent =
132       GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Parent", children, 3);
133   GPR_ASSERT(parent);
134 
135   for (size_t i = 0; i < 3; ++i) {
136     GRPC_ERROR_UNREF(children[i]);
137   }
138   GRPC_ERROR_UNREF(parent);
139 }
140 
print_error_string()141 static void print_error_string() {
142   grpc_error* error =
143       grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"),
144                          GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNIMPLEMENTED);
145   error = grpc_error_set_int(error, GRPC_ERROR_INT_SIZE, 666);
146   error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE,
147                              grpc_slice_from_static_string("message"));
148   // gpr_log(GPR_DEBUG, "%s", grpc_error_string(error));
149   GRPC_ERROR_UNREF(error);
150 }
151 
print_error_string_reference()152 static void print_error_string_reference() {
153   grpc_error* children[2];
154   children[0] = grpc_error_set_str(
155       grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("1"),
156                          GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNIMPLEMENTED),
157       GRPC_ERROR_STR_GRPC_MESSAGE,
158       grpc_slice_from_static_string("message for child 1"));
159   children[1] = grpc_error_set_str(
160       grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("2sd"),
161                          GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL),
162       GRPC_ERROR_STR_GRPC_MESSAGE,
163       grpc_slice_from_static_string("message for child 2"));
164 
165   grpc_error* parent =
166       GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Parent", children, 2);
167 
168   for (size_t i = 0; i < 2; ++i) {
169     GRPC_ERROR_UNREF(children[i]);
170   }
171   GRPC_ERROR_UNREF(parent);
172 }
173 
test_os_error()174 static void test_os_error() {
175   int fake_errno = 5;
176   const char* syscall = "syscall name";
177   grpc_error* error = GRPC_OS_ERROR(fake_errno, syscall);
178 
179   intptr_t i = 0;
180   GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_ERRNO, &i));
181   GPR_ASSERT(i == fake_errno);
182 
183   grpc_slice str;
184   GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_SYSCALL, &str));
185   GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), syscall,
186                       GRPC_SLICE_LENGTH(str)));
187   GRPC_ERROR_UNREF(error);
188 }
189 
test_overflow()190 static void test_overflow() {
191   grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Overflow");
192 
193   for (size_t i = 0; i < 150; ++i) {
194     error = grpc_error_add_child(error,
195                                  GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child"));
196   }
197 
198   error = grpc_error_set_int(error, GRPC_ERROR_INT_HTTP2_ERROR, 5);
199   error =
200       grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE,
201                          grpc_slice_from_static_string("message for child 2"));
202   error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, 5);
203 
204   intptr_t i;
205   GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_HTTP2_ERROR, &i));
206   GPR_ASSERT(i == 5);
207   GPR_ASSERT(!grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &i));
208 
209   error = grpc_error_set_int(error, GRPC_ERROR_INT_HTTP2_ERROR, 10);
210   GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_HTTP2_ERROR, &i));
211   GPR_ASSERT(i == 10);
212 
213   GRPC_ERROR_UNREF(error);
214   ;
215 }
216 
main(int argc,char ** argv)217 int main(int argc, char** argv) {
218   grpc_test_init(argc, argv);
219   grpc_init();
220   test_set_get_int();
221   test_set_get_str();
222   test_copy_and_unref();
223   print_error_string();
224   print_error_string_reference();
225   test_os_error();
226   test_create_referencing();
227   test_create_referencing_many();
228   test_overflow();
229   grpc_shutdown();
230 
231   return 0;
232 }
233