/* * * Copyright 2017 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "src/core/lib/iomgr/error.h" #include #include #include #include #include #include "test/core/util/test_config.h" TEST(ErrorTest, SetGetInt) { grpc_error_handle error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test"); EXPECT_NE(error, GRPC_ERROR_NONE); intptr_t i = 0; #ifndef NDEBUG // GRPC_ERROR_INT_FILE_LINE is for debug only EXPECT_TRUE(grpc_error_get_int(error, GRPC_ERROR_INT_FILE_LINE, &i)); EXPECT_TRUE(i); // line set will never be 0 #endif EXPECT_TRUE(!grpc_error_get_int(error, GRPC_ERROR_INT_ERRNO, &i)); EXPECT_TRUE(!grpc_error_get_int(error, GRPC_ERROR_INT_SIZE, &i)); intptr_t errnumber = 314; error = grpc_error_set_int(error, GRPC_ERROR_INT_ERRNO, errnumber); EXPECT_TRUE(grpc_error_get_int(error, GRPC_ERROR_INT_ERRNO, &i)); EXPECT_EQ(i, errnumber); intptr_t http = 2; error = grpc_error_set_int(error, GRPC_ERROR_INT_HTTP2_ERROR, http); EXPECT_TRUE(grpc_error_get_int(error, GRPC_ERROR_INT_HTTP2_ERROR, &i)); EXPECT_EQ(i, http); GRPC_ERROR_UNREF(error); } TEST(ErrorTest, SetGetStr) { grpc_error_handle error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test"); std::string str; EXPECT_TRUE(!grpc_error_get_str(error, GRPC_ERROR_STR_SYSCALL, &str)); EXPECT_TRUE(!grpc_error_get_str(error, GRPC_ERROR_STR_TSI_ERROR, &str)); #ifndef NDEBUG // GRPC_ERROR_STR_FILE is for debug only EXPECT_TRUE(grpc_error_get_str(error, GRPC_ERROR_STR_FILE, &str)); EXPECT_THAT(str, testing::HasSubstr("error_test.c")); // __FILE__ expands differently on // Windows. All should at least // contain error_test.c #endif EXPECT_TRUE(grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION, &str)); EXPECT_EQ(str, "Test"); error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, "longer message"); EXPECT_TRUE(grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, &str)); EXPECT_EQ(str, "longer message"); GRPC_ERROR_UNREF(error); } TEST(ErrorTest, CopyAndUnRef) { // error1 has one ref grpc_error_handle error1 = grpc_error_set_str(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test"), GRPC_ERROR_STR_GRPC_MESSAGE, "message"); std::string str; EXPECT_TRUE(grpc_error_get_str(error1, GRPC_ERROR_STR_GRPC_MESSAGE, &str)); EXPECT_EQ(str, "message"); // error 1 has two refs (void)GRPC_ERROR_REF(error1); // this gives error3 a ref to the new error, and decrements error1 to one ref grpc_error_handle error3 = grpc_error_set_str(error1, GRPC_ERROR_STR_SYSCALL, "syscall"); EXPECT_NE(error3, error1); // should not be the same because of extra ref EXPECT_TRUE(grpc_error_get_str(error3, GRPC_ERROR_STR_GRPC_MESSAGE, &str)); EXPECT_EQ(str, "message"); // error 1 should not have a syscall but 3 should EXPECT_TRUE(!grpc_error_get_str(error1, GRPC_ERROR_STR_SYSCALL, &str)); EXPECT_TRUE(grpc_error_get_str(error3, GRPC_ERROR_STR_SYSCALL, &str)); EXPECT_EQ(str, "syscall"); GRPC_ERROR_UNREF(error1); GRPC_ERROR_UNREF(error3); } TEST(ErrorTest, CreateReferencing) { grpc_error_handle child = grpc_error_set_str(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child"), GRPC_ERROR_STR_GRPC_MESSAGE, "message"); grpc_error_handle parent = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Parent", &child, 1); EXPECT_NE(parent, GRPC_ERROR_NONE); GRPC_ERROR_UNREF(child); GRPC_ERROR_UNREF(parent); } TEST(ErrorTest, CreateReferencingMany) { grpc_error_handle children[3]; children[0] = grpc_error_set_str(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child1"), GRPC_ERROR_STR_GRPC_MESSAGE, "message"); children[1] = grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child2"), GRPC_ERROR_INT_HTTP2_ERROR, 5); children[2] = grpc_error_set_str(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child3"), GRPC_ERROR_STR_GRPC_MESSAGE, "message 3"); grpc_error_handle parent = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Parent", children, 3); EXPECT_NE(parent, GRPC_ERROR_NONE); for (size_t i = 0; i < 3; ++i) { GRPC_ERROR_UNREF(children[i]); } GRPC_ERROR_UNREF(parent); } TEST(ErrorTest, PrintErrorString) { grpc_error_handle error = grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNIMPLEMENTED); error = grpc_error_set_int(error, GRPC_ERROR_INT_SIZE, 666); error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, "message"); // gpr_log(GPR_DEBUG, "%s", grpc_error_std_string(error).c_str()); GRPC_ERROR_UNREF(error); } TEST(ErrorTest, PrintErrorStringReference) { grpc_error_handle children[2]; children[0] = grpc_error_set_str( grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("1"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNIMPLEMENTED), GRPC_ERROR_STR_GRPC_MESSAGE, "message for child 1"); children[1] = grpc_error_set_str( grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("2sd"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL), GRPC_ERROR_STR_GRPC_MESSAGE, "message for child 2"); grpc_error_handle parent = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Parent", children, 2); for (size_t i = 0; i < 2; ++i) { GRPC_ERROR_UNREF(children[i]); } GRPC_ERROR_UNREF(parent); } TEST(ErrorTest, TestOsError) { int fake_errno = 5; const char* syscall = "syscall name"; grpc_error_handle error = GRPC_OS_ERROR(fake_errno, syscall); intptr_t i = 0; EXPECT_TRUE(grpc_error_get_int(error, GRPC_ERROR_INT_ERRNO, &i)); EXPECT_EQ(i, fake_errno); std::string str; EXPECT_TRUE(grpc_error_get_str(error, GRPC_ERROR_STR_SYSCALL, &str)); EXPECT_EQ(str, syscall); GRPC_ERROR_UNREF(error); } TEST(ErrorTest, Overflow) { // absl::Status doesn't have a limit so there is no overflow #ifndef GRPC_ERROR_IS_ABSEIL_STATUS grpc_error_handle error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Overflow"); for (size_t i = 0; i < 150; ++i) { error = grpc_error_add_child(error, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child")); } error = grpc_error_set_int(error, GRPC_ERROR_INT_HTTP2_ERROR, 5); error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, "message for child 2"); error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, 5); intptr_t i; EXPECT_TRUE(grpc_error_get_int(error, GRPC_ERROR_INT_HTTP2_ERROR, &i)); EXPECT_EQ(i, 5); EXPECT_TRUE(!grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &i)); error = grpc_error_set_int(error, GRPC_ERROR_INT_HTTP2_ERROR, 10); EXPECT_TRUE(grpc_error_get_int(error, GRPC_ERROR_INT_HTTP2_ERROR, &i)); EXPECT_EQ(i, 10); GRPC_ERROR_UNREF(error); #endif } int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); grpc_init(); int retval = RUN_ALL_TESTS(); grpc_shutdown(); return retval; }