negative_http2_client.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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. """The Python client used to test negative http2 conditions."""
  15. import argparse
  16. import grpc
  17. import time
  18. from src.proto.grpc.testing import test_pb2_grpc
  19. from src.proto.grpc.testing import messages_pb2
  20. def _validate_payload_type_and_length(response, expected_type, expected_length):
  21. if response.payload.type is not expected_type:
  22. raise ValueError('expected payload type %s, got %s' %
  23. (expected_type, type(response.payload.type)))
  24. elif len(response.payload.body) != expected_length:
  25. raise ValueError('expected payload body size %d, got %d' %
  26. (expected_length, len(response.payload.body)))
  27. def _expect_status_code(call, expected_code):
  28. if call.code() != expected_code:
  29. raise ValueError('expected code %s, got %s' % (expected_code,
  30. call.code()))
  31. def _expect_status_details(call, expected_details):
  32. if call.details() != expected_details:
  33. raise ValueError('expected message %s, got %s' % (expected_details,
  34. call.details()))
  35. def _validate_status_code_and_details(call, expected_code, expected_details):
  36. _expect_status_code(call, expected_code)
  37. _expect_status_details(call, expected_details)
  38. # common requests
  39. _REQUEST_SIZE = 314159
  40. _RESPONSE_SIZE = 271828
  41. _SIMPLE_REQUEST = messages_pb2.SimpleRequest(
  42. response_type=messages_pb2.COMPRESSABLE,
  43. response_size=_RESPONSE_SIZE,
  44. payload=messages_pb2.Payload(body=b'\x00' * _REQUEST_SIZE))
  45. def _goaway(stub):
  46. first_response = stub.UnaryCall(_SIMPLE_REQUEST)
  47. _validate_payload_type_and_length(first_response, messages_pb2.COMPRESSABLE,
  48. _RESPONSE_SIZE)
  49. time.sleep(1)
  50. second_response = stub.UnaryCall(_SIMPLE_REQUEST)
  51. _validate_payload_type_and_length(second_response,
  52. messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
  53. def _rst_after_header(stub):
  54. resp_future = stub.UnaryCall.future(_SIMPLE_REQUEST)
  55. _validate_status_code_and_details(resp_future, grpc.StatusCode.INTERNAL,
  56. "Received RST_STREAM with error code 0")
  57. def _rst_during_data(stub):
  58. resp_future = stub.UnaryCall.future(_SIMPLE_REQUEST)
  59. _validate_status_code_and_details(resp_future, grpc.StatusCode.INTERNAL,
  60. "Received RST_STREAM with error code 0")
  61. def _rst_after_data(stub):
  62. resp_future = stub.UnaryCall.future(_SIMPLE_REQUEST)
  63. _validate_status_code_and_details(resp_future, grpc.StatusCode.INTERNAL,
  64. "Received RST_STREAM with error code 0")
  65. def _ping(stub):
  66. response = stub.UnaryCall(_SIMPLE_REQUEST)
  67. _validate_payload_type_and_length(response, messages_pb2.COMPRESSABLE,
  68. _RESPONSE_SIZE)
  69. def _max_streams(stub):
  70. # send one req to ensure server sets MAX_STREAMS
  71. response = stub.UnaryCall(_SIMPLE_REQUEST)
  72. _validate_payload_type_and_length(response, messages_pb2.COMPRESSABLE,
  73. _RESPONSE_SIZE)
  74. # give the streams a workout
  75. futures = []
  76. for _ in range(15):
  77. futures.append(stub.UnaryCall.future(_SIMPLE_REQUEST))
  78. for future in futures:
  79. _validate_payload_type_and_length(
  80. future.result(), messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
  81. def _run_test_case(test_case, stub):
  82. if test_case == 'goaway':
  83. _goaway(stub)
  84. elif test_case == 'rst_after_header':
  85. _rst_after_header(stub)
  86. elif test_case == 'rst_during_data':
  87. _rst_during_data(stub)
  88. elif test_case == 'rst_after_data':
  89. _rst_after_data(stub)
  90. elif test_case == 'ping':
  91. _ping(stub)
  92. elif test_case == 'max_streams':
  93. _max_streams(stub)
  94. else:
  95. raise ValueError("Invalid test case: %s" % test_case)
  96. def _args():
  97. parser = argparse.ArgumentParser()
  98. parser.add_argument(
  99. '--server_host',
  100. help='the host to which to connect',
  101. type=str,
  102. default="127.0.0.1")
  103. parser.add_argument(
  104. '--server_port',
  105. help='the port to which to connect',
  106. type=int,
  107. default="8080")
  108. parser.add_argument(
  109. '--test_case',
  110. help='the test case to execute',
  111. type=str,
  112. default="goaway")
  113. return parser.parse_args()
  114. def _stub(server_host, server_port):
  115. target = '{}:{}'.format(server_host, server_port)
  116. channel = grpc.insecure_channel(target)
  117. grpc.channel_ready_future(channel).result()
  118. return test_pb2_grpc.TestServiceStub(channel)
  119. def main():
  120. args = _args()
  121. stub = _stub(args.server_host, args.server_port)
  122. _run_test_case(args.test_case, stub)
  123. if __name__ == '__main__':
  124. main()