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