1 //
2 // Copyright 2021 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "src/core/lib/transport/error_utils.h"
18
19 #include <stdint.h>
20
21 #include <vector>
22
23 #include "absl/status/status.h"
24 #include "gtest/gtest.h"
25
26 #include "src/core/lib/gprpp/status_helper.h"
27 #include "src/core/lib/iomgr/error.h"
28 #include "test/core/util/test_config.h"
29
30 namespace {
31
TEST(ErrorUtilsTest,GetErrorGetStatusNone)32 TEST(ErrorUtilsTest, GetErrorGetStatusNone) {
33 grpc_error_handle error;
34 grpc_status_code code;
35 std::string message;
36 grpc_error_get_status(error, grpc_core::Timestamp(), &code, &message, nullptr,
37 nullptr);
38 ASSERT_EQ(code, GRPC_STATUS_OK);
39 ASSERT_EQ(message, "");
40 }
41
TEST(ErrorUtilsTest,GetErrorGetStatusFlat)42 TEST(ErrorUtilsTest, GetErrorGetStatusFlat) {
43 grpc_error_handle error = grpc_error_set_int(
44 GRPC_ERROR_CREATE("Msg"), grpc_core::StatusIntProperty::kRpcStatus,
45 GRPC_STATUS_CANCELLED);
46 grpc_status_code code;
47 std::string message;
48 grpc_error_get_status(error, grpc_core::Timestamp(), &code, &message, nullptr,
49 nullptr);
50 ASSERT_EQ(code, GRPC_STATUS_CANCELLED);
51 ASSERT_EQ(message, "Msg");
52 }
53
TEST(ErrorUtilsTest,GetErrorGetStatusChild)54 TEST(ErrorUtilsTest, GetErrorGetStatusChild) {
55 std::vector<grpc_error_handle> children = {
56 GRPC_ERROR_CREATE("Child1"),
57 grpc_error_set_int(GRPC_ERROR_CREATE("Child2"),
58 grpc_core::StatusIntProperty::kRpcStatus,
59 GRPC_STATUS_RESOURCE_EXHAUSTED),
60 };
61 grpc_error_handle error = GRPC_ERROR_CREATE_FROM_VECTOR("Parent", &children);
62 grpc_status_code code;
63 std::string message;
64 grpc_error_get_status(error, grpc_core::Timestamp(), &code, &message, nullptr,
65 nullptr);
66 ASSERT_EQ(code, GRPC_STATUS_RESOURCE_EXHAUSTED);
67 ASSERT_EQ(message, "Child2");
68 }
69
70 // ---- Ok Status ----
TEST(ErrorUtilsTest,AbslOkToGrpcError)71 TEST(ErrorUtilsTest, AbslOkToGrpcError) {
72 grpc_error_handle error = absl_status_to_grpc_error(absl::OkStatus());
73 ASSERT_EQ(absl::OkStatus(), error);
74 }
75
TEST(ErrorUtilsTest,GrpcSpecialErrorNoneToAbslStatus)76 TEST(ErrorUtilsTest, GrpcSpecialErrorNoneToAbslStatus) {
77 absl::Status status = grpc_error_to_absl_status(absl::OkStatus());
78 ASSERT_TRUE(status.ok());
79 ASSERT_EQ(status.message(), "");
80 }
81
82 // ---- Asymmetry of conversions of "Special" errors ----
TEST(ErrorUtilsTest,AbslStatusToGrpcErrorDoesNotReturnSpecialVariables)83 TEST(ErrorUtilsTest, AbslStatusToGrpcErrorDoesNotReturnSpecialVariables) {
84 grpc_error_handle error =
85 absl_status_to_grpc_error(absl::CancelledError("CANCELLED"));
86 ASSERT_NE(error, absl::CancelledError());
87 }
88
TEST(ErrorUtilsTest,GrpcSpecialErrorCancelledToAbslStatus)89 TEST(ErrorUtilsTest, GrpcSpecialErrorCancelledToAbslStatus) {
90 absl::Status status = grpc_error_to_absl_status(absl::CancelledError());
91 ASSERT_TRUE(absl::IsCancelled(status));
92 ASSERT_EQ(status.message(), "CANCELLED");
93 }
94
TEST(ErrorUtilsTest,GrpcSpecialErrorOOMToAbslStatus)95 TEST(ErrorUtilsTest, GrpcSpecialErrorOOMToAbslStatus) {
96 absl::Status status =
97 grpc_error_to_absl_status(absl::ResourceExhaustedError(""));
98 ASSERT_TRUE(absl::IsResourceExhausted(status));
99 ASSERT_EQ(status.message(), "RESOURCE_EXHAUSTED");
100 }
101
102 // ---- Ordinary statuses ----
TEST(ErrorUtilsTest,AbslUnavailableToGrpcError)103 TEST(ErrorUtilsTest, AbslUnavailableToGrpcError) {
104 grpc_error_handle error =
105 absl_status_to_grpc_error(absl::UnavailableError("Making tea"));
106 // Status code checks
107 intptr_t code;
108 ASSERT_TRUE(grpc_error_get_int(
109 error, grpc_core::StatusIntProperty::kRpcStatus, &code));
110 ASSERT_EQ(static_cast<grpc_status_code>(code), GRPC_STATUS_UNAVAILABLE);
111 // Status message checks
112 std::string message;
113 ASSERT_TRUE(grpc_error_get_str(
114 error, grpc_core::StatusStrProperty::kDescription, &message));
115 ASSERT_EQ(message, "Making tea");
116 }
117
TEST(ErrorUtilsTest,GrpcErrorUnavailableToAbslStatus)118 TEST(ErrorUtilsTest, GrpcErrorUnavailableToAbslStatus) {
119 grpc_error_handle error = grpc_error_set_int(
120 GRPC_ERROR_CREATE(
121 "weighted_target: all children report state TRANSIENT_FAILURE"),
122 grpc_core::StatusIntProperty::kRpcStatus, GRPC_STATUS_UNAVAILABLE);
123 absl::Status status = grpc_error_to_absl_status(error);
124 ASSERT_TRUE(absl::IsUnavailable(status));
125 ASSERT_EQ(status.message(),
126 "weighted_target: all children report state TRANSIENT_FAILURE");
127 }
128
129 } // namespace
130
main(int argc,char ** argv)131 int main(int argc, char** argv) {
132 testing::InitGoogleTest(&argc, argv);
133 grpc::testing::TestEnvironment env(&argc, argv);
134 return RUN_ALL_TESTS();
135 };
136