blob: 083597f2fff61a39361abdb0f4eab3084828a96d [file] [log] [blame]
Jan Tattermusch7897ae92017-06-07 22:57:36 +02001# Copyright 2016 gRPC authors.
ncteisen65a45ae2016-12-15 14:35:17 -08002#
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003# 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
ncteisen65a45ae2016-12-15 14:35:17 -08006#
Jan Tattermusch7897ae92017-06-07 22:57:36 +02007# http://www.apache.org/licenses/LICENSE-2.0
ncteisen65a45ae2016-12-15 14:35:17 -08008#
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009# 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.
ncteisen65a45ae2016-12-15 14:35:17 -080014
15"""HTTP2 Test Server"""
16
Makarand Dharmapurikaraf37b802016-11-29 12:28:51 -080017import argparse
18import logging
Eric Gribkoff5ae42a12017-03-10 12:04:49 -080019import sys
Makarand Dharmapurikar8c579172016-12-12 13:58:15 -080020import twisted
21import twisted.internet
22import twisted.internet.endpoints
23import twisted.internet.reactor
Makarand Dharmapurikaraf37b802016-11-29 12:28:51 -080024
Makarand Dharmapurikaraf37b802016-11-29 12:28:51 -080025import http2_base_server
Makarand Dharmapurikar28d19802016-12-01 10:56:52 -080026import test_goaway
Makarand Dharmapurikar28d19802016-12-01 10:56:52 -080027import test_max_streams
Makarand Dharmapurikar8c579172016-12-12 13:58:15 -080028import test_ping
29import test_rst_after_data
30import test_rst_after_header
31import test_rst_during_data
Alexander Polcyn50fdc8a2017-02-09 21:06:08 -080032import test_data_frame_padding
Makarand Dharmapurikaraf37b802016-11-29 12:28:51 -080033
Makarand Dharmapurikar8c579172016-12-12 13:58:15 -080034_TEST_CASE_MAPPING = {
Makarand Dharmapurikara16ea7f2016-12-02 10:17:03 -080035 '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,
Alexander Polcyn50fdc8a2017-02-09 21:06:08 -080041
42 # Positive tests below:
43 'data_frame_padding': test_data_frame_padding.TestDataFramePadding,
44 'no_df_padding_sanity_test': test_data_frame_padding.TestDataFramePadding,
Makarand Dharmapurikara16ea7f2016-12-02 10:17:03 -080045}
46
Eric Gribkoff69e2f822017-03-10 12:21:05 -080047_exit_code = 0
48
Makarand Dharmapurikar8c579172016-12-12 13:58:15 -080049class H2Factory(twisted.internet.protocol.Factory):
Makarand Dharmapurikaraf37b802016-11-29 12:28:51 -080050 def __init__(self, testcase):
Eric Gribkoff5ae42a12017-03-10 12:04:49 -080051 logging.info('Creating H2Factory for new connection (%s)', testcase)
Makarand Dharmapurikaraf37b802016-11-29 12:28:51 -080052 self._num_streams = 0
53 self._testcase = testcase
54
55 def buildProtocol(self, addr):
56 self._num_streams += 1
Makarand Dharmapurikar8c579172016-12-12 13:58:15 -080057 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)
Makarand Dharmapurikaraf37b802016-11-29 12:28:51 -080060 assert(0)
Makarand Dharmapurikara16ea7f2016-12-02 10:17:03 -080061 else:
Makarand Dharmapurikar8c579172016-12-12 13:58:15 -080062 t = _TEST_CASE_MAPPING[self._testcase]
Makarand Dharmapurikara16ea7f2016-12-02 10:17:03 -080063
64 if self._testcase == 'goaway':
65 return t(self._num_streams).get_base_server()
Alexander Polcyn50fdc8a2017-02-09 21:06:08 -080066 elif self._testcase == 'no_df_padding_sanity_test':
67 return t(use_padding=False).get_base_server()
Makarand Dharmapurikara16ea7f2016-12-02 10:17:03 -080068 else:
69 return t().get_base_server()
Makarand Dharmapurikaraf37b802016-11-29 12:28:51 -080070
Makarand Dharmapurikar7fc6f3b2017-01-09 10:55:51 -080071def 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 '
Alexander Polcyn50fdc8a2017-02-09 21:06:08 -080076 'following order: data_frame_padding,goaway,max_streams,'
77 'no_df_padding_sanity_test,ping,rst_after_data,rst_after_header,'
Makarand Dharmapurikar7fc6f3b2017-01-09 10:55:51 -080078 'rst_during_data'
79 )
80 return parser.parse_args()
81
Eric Gribkoff5ae42a12017-03-10 12:04:49 -080082def 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
Eric Gribkoff95f48c12017-03-10 14:01:11 -080086 # with exit code 1.
Eric Gribkoff69e2f822017-03-10 12:21:05 -080087 global _exit_code
Eric Gribkoff95f48c12017-03-10 14:01:11 -080088 _exit_code = 1
Eric Gribkoff5ae42a12017-03-10 12:04:49 -080089 logging.error('Listening failed: %s' % reason.value)
90 twisted.internet.reactor.stop()
91 deferred.addErrback(listen_error)
92
Makarand Dharmapurikar7fc6f3b2017-01-09 10:55:51 -080093def 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)
Eric Gribkoff5ae42a12017-03-10 12:04:49 -0800102 # Wait until the reactor is running before calling endpoint.listen().
103 twisted.internet.reactor.callWhenRunning(listen, endpoint, test_case)
104
Makarand Dharmapurikar7fc6f3b2017-01-09 10:55:51 -0800105 index += 1
106
Eric Gribkoffb3bda542016-12-15 11:02:59 -0800107if __name__ == '__main__':
108 logging.basicConfig(
109 format='%(levelname) -10s %(asctime)s %(module)s:%(lineno)s | %(message)s',
110 level=logging.INFO)
Makarand Dharmapurikar7fc6f3b2017-01-09 10:55:51 -0800111 args = parse_arguments()
112 start_test_servers(args.base_port)
Eric Gribkoffb3bda542016-12-15 11:02:59 -0800113 twisted.internet.reactor.run()
Eric Gribkoff69e2f822017-03-10 12:21:05 -0800114 sys.exit(_exit_code)