• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
15"""HTTP2 Test Server"""
16
17import argparse
18import logging
19import sys
20import twisted
21import twisted.internet
22import twisted.internet.endpoints
23import twisted.internet.reactor
24
25import http2_base_server
26import test_goaway
27import test_max_streams
28import test_ping
29import test_rst_after_data
30import test_rst_after_header
31import test_rst_during_data
32import test_data_frame_padding
33
34_TEST_CASE_MAPPING = {
35  'rst_after_header': test_rst_after_header.TestcaseRstStreamAfterHeader,
36  'rst_after_data': test_rst_after_data.TestcaseRstStreamAfterData,
37  'rst_during_data': test_rst_during_data.TestcaseRstStreamDuringData,
38  'goaway': test_goaway.TestcaseGoaway,
39  'ping': test_ping.TestcasePing,
40  'max_streams': test_max_streams.TestcaseSettingsMaxStreams,
41
42  # Positive tests below:
43  'data_frame_padding': test_data_frame_padding.TestDataFramePadding,
44  'no_df_padding_sanity_test': test_data_frame_padding.TestDataFramePadding,
45}
46
47_exit_code = 0
48
49class H2Factory(twisted.internet.protocol.Factory):
50  def __init__(self, testcase):
51    logging.info('Creating H2Factory for new connection (%s)', testcase)
52    self._num_streams = 0
53    self._testcase = testcase
54
55  def buildProtocol(self, addr):
56    self._num_streams += 1
57    logging.info('New Connection: %d' % self._num_streams)
58    if not _TEST_CASE_MAPPING.has_key(self._testcase):
59      logging.error('Unknown test case: %s' % self._testcase)
60      assert(0)
61    else:
62      t = _TEST_CASE_MAPPING[self._testcase]
63
64    if self._testcase == 'goaway':
65      return t(self._num_streams).get_base_server()
66    elif self._testcase == 'no_df_padding_sanity_test':
67      return t(use_padding=False).get_base_server()
68    else:
69      return t().get_base_server()
70
71def parse_arguments():
72  parser = argparse.ArgumentParser()
73  parser.add_argument('--base_port', type=int, default=8080,
74    help='base port to run the servers (default: 8080). One test server is '
75    'started on each incrementing port, beginning with base_port, in the '
76    'following order: data_frame_padding,goaway,max_streams,'
77    'no_df_padding_sanity_test,ping,rst_after_data,rst_after_header,'
78    'rst_during_data'
79    )
80  return parser.parse_args()
81
82def listen(endpoint, test_case):
83  deferred = endpoint.listen(H2Factory(test_case))
84  def listen_error(reason):
85    # If listening fails, we stop the reactor and exit the program
86    # with exit code 1.
87    global _exit_code
88    _exit_code = 1
89    logging.error('Listening failed: %s' % reason.value)
90    twisted.internet.reactor.stop()
91  deferred.addErrback(listen_error)
92
93def start_test_servers(base_port):
94  """ Start one server per test case on incrementing port numbers
95  beginning with base_port """
96  index = 0
97  for test_case in sorted(_TEST_CASE_MAPPING.keys()):
98    portnum = base_port + index
99    logging.warning('serving on port %d : %s'%(portnum, test_case))
100    endpoint = twisted.internet.endpoints.TCP4ServerEndpoint(
101      twisted.internet.reactor, portnum, backlog=128)
102    # Wait until the reactor is running before calling endpoint.listen().
103    twisted.internet.reactor.callWhenRunning(listen, endpoint, test_case)
104
105    index += 1
106
107if __name__ == '__main__':
108  logging.basicConfig(
109    format='%(levelname) -10s %(asctime)s %(module)s:%(lineno)s | %(message)s',
110    level=logging.INFO)
111  args = parse_arguments()
112  start_test_servers(args.base_port)
113  twisted.internet.reactor.run()
114  sys.exit(_exit_code)
115