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 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 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 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 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 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 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 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 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 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 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