1# Copyright 2016 gRPC authors. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""Tests application-provided metadata, status code, and details.""" 15 16import threading 17import unittest 18 19import grpc 20 21from tests.unit import test_common 22from tests.unit.framework.common import test_constants 23from tests.unit.framework.common import test_control 24 25_SERIALIZED_REQUEST = b'\x46\x47\x48' 26_SERIALIZED_RESPONSE = b'\x49\x50\x51' 27 28_REQUEST_SERIALIZER = lambda unused_request: _SERIALIZED_REQUEST 29_REQUEST_DESERIALIZER = lambda unused_serialized_request: object() 30_RESPONSE_SERIALIZER = lambda unused_response: _SERIALIZED_RESPONSE 31_RESPONSE_DESERIALIZER = lambda unused_serialized_response: object() 32 33_SERVICE = 'test.TestService' 34_UNARY_UNARY = 'UnaryUnary' 35_UNARY_STREAM = 'UnaryStream' 36_STREAM_UNARY = 'StreamUnary' 37_STREAM_STREAM = 'StreamStream' 38 39_CLIENT_METADATA = (('client-md-key', 'client-md-key'), ('client-md-key-bin', 40 b'\x00\x01')) 41 42_SERVER_INITIAL_METADATA = (('server-initial-md-key', 43 'server-initial-md-value'), 44 ('server-initial-md-key-bin', b'\x00\x02')) 45 46_SERVER_TRAILING_METADATA = (('server-trailing-md-key', 47 'server-trailing-md-value'), 48 ('server-trailing-md-key-bin', b'\x00\x03')) 49 50_NON_OK_CODE = grpc.StatusCode.NOT_FOUND 51_DETAILS = 'Test details!' 52 53# calling abort should always fail an RPC, even for "invalid" codes 54_ABORT_CODES = (_NON_OK_CODE, 3, grpc.StatusCode.OK) 55_EXPECTED_CLIENT_CODES = (_NON_OK_CODE, grpc.StatusCode.UNKNOWN, 56 grpc.StatusCode.UNKNOWN) 57_EXPECTED_DETAILS = (_DETAILS, _DETAILS, '') 58 59 60class _Servicer(object): 61 62 def __init__(self): 63 self._lock = threading.Lock() 64 self._abort_call = False 65 self._code = None 66 self._details = None 67 self._exception = False 68 self._return_none = False 69 self._received_client_metadata = None 70 71 def unary_unary(self, request, context): 72 with self._lock: 73 self._received_client_metadata = context.invocation_metadata() 74 context.send_initial_metadata(_SERVER_INITIAL_METADATA) 75 context.set_trailing_metadata(_SERVER_TRAILING_METADATA) 76 if self._abort_call: 77 context.abort(self._code, self._details) 78 else: 79 if self._code is not None: 80 context.set_code(self._code) 81 if self._details is not None: 82 context.set_details(self._details) 83 if self._exception: 84 raise test_control.Defect() 85 else: 86 return None if self._return_none else object() 87 88 def unary_stream(self, request, context): 89 with self._lock: 90 self._received_client_metadata = context.invocation_metadata() 91 context.send_initial_metadata(_SERVER_INITIAL_METADATA) 92 context.set_trailing_metadata(_SERVER_TRAILING_METADATA) 93 if self._abort_call: 94 context.abort(self._code, self._details) 95 else: 96 if self._code is not None: 97 context.set_code(self._code) 98 if self._details is not None: 99 context.set_details(self._details) 100 for _ in range(test_constants.STREAM_LENGTH // 2): 101 yield _SERIALIZED_RESPONSE 102 if self._exception: 103 raise test_control.Defect() 104 105 def stream_unary(self, request_iterator, context): 106 with self._lock: 107 self._received_client_metadata = context.invocation_metadata() 108 context.send_initial_metadata(_SERVER_INITIAL_METADATA) 109 context.set_trailing_metadata(_SERVER_TRAILING_METADATA) 110 # TODO(https://github.com/grpc/grpc/issues/6891): just ignore the 111 # request iterator. 112 list(request_iterator) 113 if self._abort_call: 114 context.abort(self._code, self._details) 115 else: 116 if self._code is not None: 117 context.set_code(self._code) 118 if self._details is not None: 119 context.set_details(self._details) 120 if self._exception: 121 raise test_control.Defect() 122 else: 123 return None if self._return_none else _SERIALIZED_RESPONSE 124 125 def stream_stream(self, request_iterator, context): 126 with self._lock: 127 self._received_client_metadata = context.invocation_metadata() 128 context.send_initial_metadata(_SERVER_INITIAL_METADATA) 129 context.set_trailing_metadata(_SERVER_TRAILING_METADATA) 130 # TODO(https://github.com/grpc/grpc/issues/6891): just ignore the 131 # request iterator. 132 list(request_iterator) 133 if self._abort_call: 134 context.abort(self._code, self._details) 135 else: 136 if self._code is not None: 137 context.set_code(self._code) 138 if self._details is not None: 139 context.set_details(self._details) 140 for _ in range(test_constants.STREAM_LENGTH // 3): 141 yield object() 142 if self._exception: 143 raise test_control.Defect() 144 145 def set_abort_call(self): 146 with self._lock: 147 self._abort_call = True 148 149 def set_code(self, code): 150 with self._lock: 151 self._code = code 152 153 def set_details(self, details): 154 with self._lock: 155 self._details = details 156 157 def set_exception(self): 158 with self._lock: 159 self._exception = True 160 161 def set_return_none(self): 162 with self._lock: 163 self._return_none = True 164 165 def received_client_metadata(self): 166 with self._lock: 167 return self._received_client_metadata 168 169 170def _generic_handler(servicer): 171 method_handlers = { 172 _UNARY_UNARY: 173 grpc.unary_unary_rpc_method_handler( 174 servicer.unary_unary, 175 request_deserializer=_REQUEST_DESERIALIZER, 176 response_serializer=_RESPONSE_SERIALIZER), 177 _UNARY_STREAM: 178 grpc.unary_stream_rpc_method_handler(servicer.unary_stream), 179 _STREAM_UNARY: 180 grpc.stream_unary_rpc_method_handler(servicer.stream_unary), 181 _STREAM_STREAM: 182 grpc.stream_stream_rpc_method_handler( 183 servicer.stream_stream, 184 request_deserializer=_REQUEST_DESERIALIZER, 185 response_serializer=_RESPONSE_SERIALIZER), 186 } 187 return grpc.method_handlers_generic_handler(_SERVICE, method_handlers) 188 189 190class MetadataCodeDetailsTest(unittest.TestCase): 191 192 def setUp(self): 193 self._servicer = _Servicer() 194 self._server = test_common.test_server() 195 self._server.add_generic_rpc_handlers( 196 (_generic_handler(self._servicer),)) 197 port = self._server.add_insecure_port('[::]:0') 198 self._server.start() 199 200 channel = grpc.insecure_channel('localhost:{}'.format(port)) 201 self._unary_unary = channel.unary_unary( 202 '/'.join(( 203 '', 204 _SERVICE, 205 _UNARY_UNARY, 206 )), 207 request_serializer=_REQUEST_SERIALIZER, 208 response_deserializer=_RESPONSE_DESERIALIZER, 209 ) 210 self._unary_stream = channel.unary_stream('/'.join(( 211 '', 212 _SERVICE, 213 _UNARY_STREAM, 214 )),) 215 self._stream_unary = channel.stream_unary('/'.join(( 216 '', 217 _SERVICE, 218 _STREAM_UNARY, 219 )),) 220 self._stream_stream = channel.stream_stream( 221 '/'.join(( 222 '', 223 _SERVICE, 224 _STREAM_STREAM, 225 )), 226 request_serializer=_REQUEST_SERIALIZER, 227 response_deserializer=_RESPONSE_DESERIALIZER, 228 ) 229 230 def testSuccessfulUnaryUnary(self): 231 self._servicer.set_details(_DETAILS) 232 233 unused_response, call = self._unary_unary.with_call( 234 object(), metadata=_CLIENT_METADATA) 235 236 self.assertTrue( 237 test_common.metadata_transmitted( 238 _CLIENT_METADATA, self._servicer.received_client_metadata())) 239 self.assertTrue( 240 test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, 241 call.initial_metadata())) 242 self.assertTrue( 243 test_common.metadata_transmitted(_SERVER_TRAILING_METADATA, 244 call.trailing_metadata())) 245 self.assertIs(grpc.StatusCode.OK, call.code()) 246 self.assertEqual(_DETAILS, call.details()) 247 248 def testSuccessfulUnaryStream(self): 249 self._servicer.set_details(_DETAILS) 250 251 response_iterator_call = self._unary_stream( 252 _SERIALIZED_REQUEST, metadata=_CLIENT_METADATA) 253 received_initial_metadata = response_iterator_call.initial_metadata() 254 list(response_iterator_call) 255 256 self.assertTrue( 257 test_common.metadata_transmitted( 258 _CLIENT_METADATA, self._servicer.received_client_metadata())) 259 self.assertTrue( 260 test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, 261 received_initial_metadata)) 262 self.assertTrue( 263 test_common.metadata_transmitted( 264 _SERVER_TRAILING_METADATA, 265 response_iterator_call.trailing_metadata())) 266 self.assertIs(grpc.StatusCode.OK, response_iterator_call.code()) 267 self.assertEqual(_DETAILS, response_iterator_call.details()) 268 269 def testSuccessfulStreamUnary(self): 270 self._servicer.set_details(_DETAILS) 271 272 unused_response, call = self._stream_unary.with_call( 273 iter([_SERIALIZED_REQUEST] * test_constants.STREAM_LENGTH), 274 metadata=_CLIENT_METADATA) 275 276 self.assertTrue( 277 test_common.metadata_transmitted( 278 _CLIENT_METADATA, self._servicer.received_client_metadata())) 279 self.assertTrue( 280 test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, 281 call.initial_metadata())) 282 self.assertTrue( 283 test_common.metadata_transmitted(_SERVER_TRAILING_METADATA, 284 call.trailing_metadata())) 285 self.assertIs(grpc.StatusCode.OK, call.code()) 286 self.assertEqual(_DETAILS, call.details()) 287 288 def testSuccessfulStreamStream(self): 289 self._servicer.set_details(_DETAILS) 290 291 response_iterator_call = self._stream_stream( 292 iter([object()] * test_constants.STREAM_LENGTH), 293 metadata=_CLIENT_METADATA) 294 received_initial_metadata = response_iterator_call.initial_metadata() 295 list(response_iterator_call) 296 297 self.assertTrue( 298 test_common.metadata_transmitted( 299 _CLIENT_METADATA, self._servicer.received_client_metadata())) 300 self.assertTrue( 301 test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, 302 received_initial_metadata)) 303 self.assertTrue( 304 test_common.metadata_transmitted( 305 _SERVER_TRAILING_METADATA, 306 response_iterator_call.trailing_metadata())) 307 self.assertIs(grpc.StatusCode.OK, response_iterator_call.code()) 308 self.assertEqual(_DETAILS, response_iterator_call.details()) 309 310 def testAbortedUnaryUnary(self): 311 test_cases = zip(_ABORT_CODES, _EXPECTED_CLIENT_CODES, 312 _EXPECTED_DETAILS) 313 for abort_code, expected_code, expected_details in test_cases: 314 self._servicer.set_code(abort_code) 315 self._servicer.set_details(_DETAILS) 316 self._servicer.set_abort_call() 317 318 with self.assertRaises(grpc.RpcError) as exception_context: 319 self._unary_unary.with_call(object(), metadata=_CLIENT_METADATA) 320 321 self.assertTrue( 322 test_common.metadata_transmitted( 323 _CLIENT_METADATA, 324 self._servicer.received_client_metadata())) 325 self.assertTrue( 326 test_common.metadata_transmitted( 327 _SERVER_INITIAL_METADATA, 328 exception_context.exception.initial_metadata())) 329 self.assertTrue( 330 test_common.metadata_transmitted( 331 _SERVER_TRAILING_METADATA, 332 exception_context.exception.trailing_metadata())) 333 self.assertIs(expected_code, exception_context.exception.code()) 334 self.assertEqual(expected_details, 335 exception_context.exception.details()) 336 337 def testAbortedUnaryStream(self): 338 test_cases = zip(_ABORT_CODES, _EXPECTED_CLIENT_CODES, 339 _EXPECTED_DETAILS) 340 for abort_code, expected_code, expected_details in test_cases: 341 self._servicer.set_code(abort_code) 342 self._servicer.set_details(_DETAILS) 343 self._servicer.set_abort_call() 344 345 response_iterator_call = self._unary_stream( 346 _SERIALIZED_REQUEST, metadata=_CLIENT_METADATA) 347 received_initial_metadata = \ 348 response_iterator_call.initial_metadata() 349 with self.assertRaises(grpc.RpcError): 350 self.assertEqual(len(list(response_iterator_call)), 0) 351 352 self.assertTrue( 353 test_common.metadata_transmitted( 354 _CLIENT_METADATA, 355 self._servicer.received_client_metadata())) 356 self.assertTrue( 357 test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, 358 received_initial_metadata)) 359 self.assertTrue( 360 test_common.metadata_transmitted( 361 _SERVER_TRAILING_METADATA, 362 response_iterator_call.trailing_metadata())) 363 self.assertIs(expected_code, response_iterator_call.code()) 364 self.assertEqual(expected_details, response_iterator_call.details()) 365 366 def testAbortedStreamUnary(self): 367 test_cases = zip(_ABORT_CODES, _EXPECTED_CLIENT_CODES, 368 _EXPECTED_DETAILS) 369 for abort_code, expected_code, expected_details in test_cases: 370 self._servicer.set_code(abort_code) 371 self._servicer.set_details(_DETAILS) 372 self._servicer.set_abort_call() 373 374 with self.assertRaises(grpc.RpcError) as exception_context: 375 self._stream_unary.with_call( 376 iter([_SERIALIZED_REQUEST] * test_constants.STREAM_LENGTH), 377 metadata=_CLIENT_METADATA) 378 379 self.assertTrue( 380 test_common.metadata_transmitted( 381 _CLIENT_METADATA, 382 self._servicer.received_client_metadata())) 383 self.assertTrue( 384 test_common.metadata_transmitted( 385 _SERVER_INITIAL_METADATA, 386 exception_context.exception.initial_metadata())) 387 self.assertTrue( 388 test_common.metadata_transmitted( 389 _SERVER_TRAILING_METADATA, 390 exception_context.exception.trailing_metadata())) 391 self.assertIs(expected_code, exception_context.exception.code()) 392 self.assertEqual(expected_details, 393 exception_context.exception.details()) 394 395 def testAbortedStreamStream(self): 396 test_cases = zip(_ABORT_CODES, _EXPECTED_CLIENT_CODES, 397 _EXPECTED_DETAILS) 398 for abort_code, expected_code, expected_details in test_cases: 399 self._servicer.set_code(abort_code) 400 self._servicer.set_details(_DETAILS) 401 self._servicer.set_abort_call() 402 403 response_iterator_call = self._stream_stream( 404 iter([object()] * test_constants.STREAM_LENGTH), 405 metadata=_CLIENT_METADATA) 406 received_initial_metadata = \ 407 response_iterator_call.initial_metadata() 408 with self.assertRaises(grpc.RpcError): 409 self.assertEqual(len(list(response_iterator_call)), 0) 410 411 self.assertTrue( 412 test_common.metadata_transmitted( 413 _CLIENT_METADATA, 414 self._servicer.received_client_metadata())) 415 self.assertTrue( 416 test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, 417 received_initial_metadata)) 418 self.assertTrue( 419 test_common.metadata_transmitted( 420 _SERVER_TRAILING_METADATA, 421 response_iterator_call.trailing_metadata())) 422 self.assertIs(expected_code, response_iterator_call.code()) 423 self.assertEqual(expected_details, response_iterator_call.details()) 424 425 def testCustomCodeUnaryUnary(self): 426 self._servicer.set_code(_NON_OK_CODE) 427 self._servicer.set_details(_DETAILS) 428 429 with self.assertRaises(grpc.RpcError) as exception_context: 430 self._unary_unary.with_call(object(), metadata=_CLIENT_METADATA) 431 432 self.assertTrue( 433 test_common.metadata_transmitted( 434 _CLIENT_METADATA, self._servicer.received_client_metadata())) 435 self.assertTrue( 436 test_common.metadata_transmitted( 437 _SERVER_INITIAL_METADATA, 438 exception_context.exception.initial_metadata())) 439 self.assertTrue( 440 test_common.metadata_transmitted( 441 _SERVER_TRAILING_METADATA, 442 exception_context.exception.trailing_metadata())) 443 self.assertIs(_NON_OK_CODE, exception_context.exception.code()) 444 self.assertEqual(_DETAILS, exception_context.exception.details()) 445 446 def testCustomCodeUnaryStream(self): 447 self._servicer.set_code(_NON_OK_CODE) 448 self._servicer.set_details(_DETAILS) 449 450 response_iterator_call = self._unary_stream( 451 _SERIALIZED_REQUEST, metadata=_CLIENT_METADATA) 452 received_initial_metadata = response_iterator_call.initial_metadata() 453 with self.assertRaises(grpc.RpcError): 454 list(response_iterator_call) 455 456 self.assertTrue( 457 test_common.metadata_transmitted( 458 _CLIENT_METADATA, self._servicer.received_client_metadata())) 459 self.assertTrue( 460 test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, 461 received_initial_metadata)) 462 self.assertTrue( 463 test_common.metadata_transmitted( 464 _SERVER_TRAILING_METADATA, 465 response_iterator_call.trailing_metadata())) 466 self.assertIs(_NON_OK_CODE, response_iterator_call.code()) 467 self.assertEqual(_DETAILS, response_iterator_call.details()) 468 469 def testCustomCodeStreamUnary(self): 470 self._servicer.set_code(_NON_OK_CODE) 471 self._servicer.set_details(_DETAILS) 472 473 with self.assertRaises(grpc.RpcError) as exception_context: 474 self._stream_unary.with_call( 475 iter([_SERIALIZED_REQUEST] * test_constants.STREAM_LENGTH), 476 metadata=_CLIENT_METADATA) 477 478 self.assertTrue( 479 test_common.metadata_transmitted( 480 _CLIENT_METADATA, self._servicer.received_client_metadata())) 481 self.assertTrue( 482 test_common.metadata_transmitted( 483 _SERVER_INITIAL_METADATA, 484 exception_context.exception.initial_metadata())) 485 self.assertTrue( 486 test_common.metadata_transmitted( 487 _SERVER_TRAILING_METADATA, 488 exception_context.exception.trailing_metadata())) 489 self.assertIs(_NON_OK_CODE, exception_context.exception.code()) 490 self.assertEqual(_DETAILS, exception_context.exception.details()) 491 492 def testCustomCodeStreamStream(self): 493 self._servicer.set_code(_NON_OK_CODE) 494 self._servicer.set_details(_DETAILS) 495 496 response_iterator_call = self._stream_stream( 497 iter([object()] * test_constants.STREAM_LENGTH), 498 metadata=_CLIENT_METADATA) 499 received_initial_metadata = response_iterator_call.initial_metadata() 500 with self.assertRaises(grpc.RpcError) as exception_context: 501 list(response_iterator_call) 502 503 self.assertTrue( 504 test_common.metadata_transmitted( 505 _CLIENT_METADATA, self._servicer.received_client_metadata())) 506 self.assertTrue( 507 test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, 508 received_initial_metadata)) 509 self.assertTrue( 510 test_common.metadata_transmitted( 511 _SERVER_TRAILING_METADATA, 512 exception_context.exception.trailing_metadata())) 513 self.assertIs(_NON_OK_CODE, exception_context.exception.code()) 514 self.assertEqual(_DETAILS, exception_context.exception.details()) 515 516 def testCustomCodeExceptionUnaryUnary(self): 517 self._servicer.set_code(_NON_OK_CODE) 518 self._servicer.set_details(_DETAILS) 519 self._servicer.set_exception() 520 521 with self.assertRaises(grpc.RpcError) as exception_context: 522 self._unary_unary.with_call(object(), metadata=_CLIENT_METADATA) 523 524 self.assertTrue( 525 test_common.metadata_transmitted( 526 _CLIENT_METADATA, self._servicer.received_client_metadata())) 527 self.assertTrue( 528 test_common.metadata_transmitted( 529 _SERVER_INITIAL_METADATA, 530 exception_context.exception.initial_metadata())) 531 self.assertTrue( 532 test_common.metadata_transmitted( 533 _SERVER_TRAILING_METADATA, 534 exception_context.exception.trailing_metadata())) 535 self.assertIs(_NON_OK_CODE, exception_context.exception.code()) 536 self.assertEqual(_DETAILS, exception_context.exception.details()) 537 538 def testCustomCodeExceptionUnaryStream(self): 539 self._servicer.set_code(_NON_OK_CODE) 540 self._servicer.set_details(_DETAILS) 541 self._servicer.set_exception() 542 543 response_iterator_call = self._unary_stream( 544 _SERIALIZED_REQUEST, metadata=_CLIENT_METADATA) 545 received_initial_metadata = response_iterator_call.initial_metadata() 546 with self.assertRaises(grpc.RpcError): 547 list(response_iterator_call) 548 549 self.assertTrue( 550 test_common.metadata_transmitted( 551 _CLIENT_METADATA, self._servicer.received_client_metadata())) 552 self.assertTrue( 553 test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, 554 received_initial_metadata)) 555 self.assertTrue( 556 test_common.metadata_transmitted( 557 _SERVER_TRAILING_METADATA, 558 response_iterator_call.trailing_metadata())) 559 self.assertIs(_NON_OK_CODE, response_iterator_call.code()) 560 self.assertEqual(_DETAILS, response_iterator_call.details()) 561 562 def testCustomCodeExceptionStreamUnary(self): 563 self._servicer.set_code(_NON_OK_CODE) 564 self._servicer.set_details(_DETAILS) 565 self._servicer.set_exception() 566 567 with self.assertRaises(grpc.RpcError) as exception_context: 568 self._stream_unary.with_call( 569 iter([_SERIALIZED_REQUEST] * test_constants.STREAM_LENGTH), 570 metadata=_CLIENT_METADATA) 571 572 self.assertTrue( 573 test_common.metadata_transmitted( 574 _CLIENT_METADATA, self._servicer.received_client_metadata())) 575 self.assertTrue( 576 test_common.metadata_transmitted( 577 _SERVER_INITIAL_METADATA, 578 exception_context.exception.initial_metadata())) 579 self.assertTrue( 580 test_common.metadata_transmitted( 581 _SERVER_TRAILING_METADATA, 582 exception_context.exception.trailing_metadata())) 583 self.assertIs(_NON_OK_CODE, exception_context.exception.code()) 584 self.assertEqual(_DETAILS, exception_context.exception.details()) 585 586 def testCustomCodeExceptionStreamStream(self): 587 self._servicer.set_code(_NON_OK_CODE) 588 self._servicer.set_details(_DETAILS) 589 self._servicer.set_exception() 590 591 response_iterator_call = self._stream_stream( 592 iter([object()] * test_constants.STREAM_LENGTH), 593 metadata=_CLIENT_METADATA) 594 received_initial_metadata = response_iterator_call.initial_metadata() 595 with self.assertRaises(grpc.RpcError): 596 list(response_iterator_call) 597 598 self.assertTrue( 599 test_common.metadata_transmitted( 600 _CLIENT_METADATA, self._servicer.received_client_metadata())) 601 self.assertTrue( 602 test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, 603 received_initial_metadata)) 604 self.assertTrue( 605 test_common.metadata_transmitted( 606 _SERVER_TRAILING_METADATA, 607 response_iterator_call.trailing_metadata())) 608 self.assertIs(_NON_OK_CODE, response_iterator_call.code()) 609 self.assertEqual(_DETAILS, response_iterator_call.details()) 610 611 def testCustomCodeReturnNoneUnaryUnary(self): 612 self._servicer.set_code(_NON_OK_CODE) 613 self._servicer.set_details(_DETAILS) 614 self._servicer.set_return_none() 615 616 with self.assertRaises(grpc.RpcError) as exception_context: 617 self._unary_unary.with_call(object(), metadata=_CLIENT_METADATA) 618 619 self.assertTrue( 620 test_common.metadata_transmitted( 621 _CLIENT_METADATA, self._servicer.received_client_metadata())) 622 self.assertTrue( 623 test_common.metadata_transmitted( 624 _SERVER_INITIAL_METADATA, 625 exception_context.exception.initial_metadata())) 626 self.assertTrue( 627 test_common.metadata_transmitted( 628 _SERVER_TRAILING_METADATA, 629 exception_context.exception.trailing_metadata())) 630 self.assertIs(_NON_OK_CODE, exception_context.exception.code()) 631 self.assertEqual(_DETAILS, exception_context.exception.details()) 632 633 def testCustomCodeReturnNoneStreamUnary(self): 634 self._servicer.set_code(_NON_OK_CODE) 635 self._servicer.set_details(_DETAILS) 636 self._servicer.set_return_none() 637 638 with self.assertRaises(grpc.RpcError) as exception_context: 639 self._stream_unary.with_call( 640 iter([_SERIALIZED_REQUEST] * test_constants.STREAM_LENGTH), 641 metadata=_CLIENT_METADATA) 642 643 self.assertTrue( 644 test_common.metadata_transmitted( 645 _CLIENT_METADATA, self._servicer.received_client_metadata())) 646 self.assertTrue( 647 test_common.metadata_transmitted( 648 _SERVER_INITIAL_METADATA, 649 exception_context.exception.initial_metadata())) 650 self.assertTrue( 651 test_common.metadata_transmitted( 652 _SERVER_TRAILING_METADATA, 653 exception_context.exception.trailing_metadata())) 654 self.assertIs(_NON_OK_CODE, exception_context.exception.code()) 655 self.assertEqual(_DETAILS, exception_context.exception.details()) 656 657 658if __name__ == '__main__': 659 unittest.main(verbosity=2) 660