14 """Tests of grpc_status with gRPC AsyncIO stack."""
21 from google.rpc
import code_pb2
22 from google.rpc
import error_details_pb2
23 from google.rpc
import status_pb2
26 from grpc_status
import rpc_status
30 _STATUS_OK =
'/test/StatusOK'
31 _STATUS_NOT_OK =
'/test/StatusNotOk'
32 _ERROR_DETAILS =
'/test/ErrorDetails'
33 _INCONSISTENT =
'/test/Inconsistent'
34 _INVALID_CODE =
'/test/InvalidCode'
36 _REQUEST = b
'\x00\x00\x00'
37 _RESPONSE = b
'\x01\x01\x01'
39 _GRPC_DETAILS_METADATA_KEY =
'grpc-status-details-bin'
41 _STATUS_DETAILS =
'This is an error detail'
42 _STATUS_DETAILS_ANOTHER =
'This is another error detail'
50 await servicer_context.abort(grpc.StatusCode.INTERNAL, _STATUS_DETAILS)
54 details = any_pb2.Any()
56 error_details_pb2.DebugInfo(stack_entries=traceback.format_stack(),
57 detail=
'Intentionally invoked'))
58 rich_status = status_pb2.Status(
59 code=code_pb2.INTERNAL,
60 message=_STATUS_DETAILS,
63 await servicer_context.abort_with_status(rpc_status.to_status(rich_status))
67 rich_status = status_pb2.Status(
68 code=code_pb2.INTERNAL,
69 message=_STATUS_DETAILS,
71 servicer_context.set_code(grpc.StatusCode.NOT_FOUND)
72 servicer_context.set_details(_STATUS_DETAILS_ANOTHER)
74 servicer_context.set_trailing_metadata(
75 ((_GRPC_DETAILS_METADATA_KEY, rich_status.SerializeToString()),))
79 rich_status = status_pb2.Status(
81 message=
'Invalid code',
83 await servicer_context.abort_with_status(rpc_status.to_status(rich_status))
89 if handler_call_details.method == _STATUS_OK:
91 elif handler_call_details.method == _STATUS_NOT_OK:
93 elif handler_call_details.method == _ERROR_DETAILS:
95 _error_details_unary_unary)
96 elif handler_call_details.method == _INCONSISTENT:
98 _inconsistent_unary_unary)
99 elif handler_call_details.method == _INVALID_CODE:
101 _invalid_code_unary_unary)
111 port = self.
_server.add_insecure_port(
'[::]:0')
114 self.
_channel = aio.insecure_channel(
'localhost:%d' % port)
124 status = await rpc_status.aio.from_call(call)
125 self.assertIs(status,
None)
129 with self.assertRaises(aio.AioRpcError)
as exception_context:
131 rpc_error = exception_context.exception
133 self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL)
135 status = await rpc_status.aio.from_call(call)
136 self.assertIs(status,
None)
140 with self.assertRaises(aio.AioRpcError)
as exception_context:
142 rpc_error = exception_context.exception
144 status = await rpc_status.aio.from_call(call)
145 self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL)
146 self.assertEqual(status.code, code_pb2.Code.Value(
'INTERNAL'))
149 self.assertTrue(status.details[0].Is(
150 error_details_pb2.DebugInfo.DESCRIPTOR))
151 info = error_details_pb2.DebugInfo()
152 status.details[0].Unpack(info)
153 self.assertIn(
'_error_details_unary_unary', info.stack_entries[-1])
157 with self.assertRaises(aio.AioRpcError)
as exception_context:
159 rpc_error = exception_context.exception
160 self.assertEqual(rpc_error.code(), grpc.StatusCode.NOT_FOUND)
163 with self.assertRaises(ValueError):
164 await rpc_status.aio.from_call(call)
167 with self.assertRaises(aio.AioRpcError)
as exception_context:
169 rpc_error = exception_context.exception
170 self.assertEqual(rpc_error.code(), grpc.StatusCode.UNKNOWN)
172 self.assertIn(
'Invalid status code', rpc_error.details())
175 if __name__ ==
'__main__':
176 logging.basicConfig()
177 unittest.main(verbosity=2)