OLD | NEW |
---|---|
(Empty) | |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 import optparse | |
6 import os | |
7 import struct | |
8 import sys | |
9 import warnings | |
10 | |
11 # Ignore deprecation warnings, they make our output more cluttered. | |
12 warnings.filterwarnings("ignore", category=DeprecationWarning) | |
13 | |
14 try: | |
15 import json | |
16 except ImportError: | |
17 import simplejson as json | |
M-A Ruel
2012/08/31 22:04:05
We do not support python < 2.6 anymore, so please
mattm
2012/09/01 01:44:54
Done.
| |
18 | |
19 if sys.platform == 'win32': | |
20 import msvcrt | |
21 | |
22 | |
23 class FileMultiplexer: | |
M-A Ruel
2012/08/31 22:04:05
class FileMultiplexer(object):
and everywhere
mattm
2012/09/01 01:44:54
Done.
| |
24 def __init__(self, fd1, fd2) : | |
25 self.__fd1 = fd1 | |
26 self.__fd2 = fd2 | |
27 | |
28 def __del__(self) : | |
M-A Ruel
2012/08/31 22:04:05
Why?
mattm
2012/09/01 01:44:54
I don't know. This is just moved from testserver.p
| |
29 if self.__fd1 != sys.stdout and self.__fd1 != sys.stderr: | |
30 self.__fd1.close() | |
31 if self.__fd2 != sys.stdout and self.__fd2 != sys.stderr: | |
32 self.__fd2.close() | |
33 | |
34 def write(self, text) : | |
35 self.__fd1.write(text) | |
36 self.__fd2.write(text) | |
37 | |
38 def flush(self) : | |
39 self.__fd1.flush() | |
40 self.__fd2.flush() | |
41 | |
42 | |
43 class TestServerRunner: | |
44 def __init__(self): | |
45 self.option_parser = optparse.OptionParser() | |
46 self.add_options() | |
47 | |
48 def main(self): | |
49 self.options, self.args = self.option_parser.parse_args() | |
50 | |
51 logfile = open('testserver.log', 'w') | |
52 sys.stderr = FileMultiplexer(sys.stderr, logfile) | |
53 if self.options.log_to_console: | |
54 sys.stdout = FileMultiplexer(sys.stdout, logfile) | |
55 else: | |
56 sys.stdout = logfile | |
57 | |
58 server_data = {} | |
M-A Ruel
2012/08/31 22:04:05
server_data = {
'host': self.options.host,
}
mattm
2012/09/01 01:44:54
Done.
| |
59 server_data['host'] = self.options.host | |
60 | |
M-A Ruel
2012/08/31 22:04:05
why
so
much
whitespace?
mattm
2012/09/01 01:44:54
Done.
| |
61 self.server = self.create_server(server_data) | |
62 | |
63 self._notify_startup_complete(server_data) | |
64 | |
65 self.run_server() | |
66 | |
67 def create_server(self, server_data): | |
68 """Creates a server object and returns it. | |
69 | |
70 Must populate server_data['port'], and can set additional server_data | |
71 elements if desired.""" | |
72 raise NotImplementedError | |
M-A Ruel
2012/08/31 22:04:05
raise NotImplementedError()
mattm
2012/09/01 01:44:54
Done.
| |
73 | |
74 def run_server(self): | |
75 try: | |
76 self.server.serve_forever() | |
77 except KeyboardInterrupt: | |
78 print 'shutting down server' | |
79 self.server.stop = True | |
80 | |
81 def add_options(self): | |
82 self.option_parser.add_option('', '--startup-pipe', type='int', | |
M-A Ruel
2012/08/31 22:04:05
I'm not sure why all the "'', ".
mattm
2012/09/01 01:44:54
dunno either, but fixed.
| |
83 dest='startup_pipe', | |
84 help='File handle of pipe to parent process') | |
85 self.option_parser.add_option('', '--log-to-console', action='store_const', | |
86 const=True, default=False, | |
87 dest='log_to_console', | |
88 help='Enables or disables sys.stdout logging ' | |
89 'to the console.') | |
90 self.option_parser.add_option('', '--port', default='0', type='int', | |
M-A Ruel
2012/08/31 22:04:05
default=0 since you used type int
mattm
2012/09/01 01:44:54
Done.
| |
91 help='Port used by the server. If ' | |
92 'unspecified, the server will listen on an ' | |
93 'ephemeral port.') | |
94 self.option_parser.add_option('', '--host', default='127.0.0.1', | |
95 dest='host', | |
96 help='Hostname or IP upon which the server ' | |
97 'will listen. Client connections will also ' | |
98 'only be allowed from this address.') | |
99 | |
100 def _notify_startup_complete(self, server_data): | |
101 # Notify the parent that we've started. (BaseServer subclasses | |
102 # bind their sockets on construction.) | |
103 if self.options.startup_pipe is not None: | |
M-A Ruel
2012/08/31 22:04:05
if self.options.startup_pipe:
mattm
2012/09/01 01:44:54
0 is a valid file descripton
mattm
2012/09/01 01:45:43
s/descripton/descriptor/
| |
104 server_data_json = json.dumps(server_data) | |
105 server_data_len = len(server_data_json) | |
106 print 'sending server_data: %s (%d bytes)' % ( | |
107 server_data_json, server_data_len) | |
108 if sys.platform == 'win32': | |
109 fd = msvcrt.open_osfhandle(self.options.startup_pipe, 0) | |
110 else: | |
111 fd = self.options.startup_pipe | |
112 startup_pipe = os.fdopen(fd, "w") | |
113 # First write the data length as an unsigned 4-byte value. This | |
114 # is _not_ using network byte ordering since the other end of the | |
115 # pipe is on the same machine. | |
116 startup_pipe.write(struct.pack('=L', server_data_len)) | |
117 startup_pipe.write(server_data_json) | |
118 startup_pipe.close() | |
OLD | NEW |