Mercurial > hg
comparison tests/dumbhttp.py @ 23136:6eab50a34fed
tests: have dumbhttp.py use cmdutil.service() to wait for child to listen()
Because the original dumbhttp.py exited without waiting for listen(), several
tests could fail with "abort: error: Connection refused" if subsequent hg
command is fast enough.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 02 Nov 2014 13:08:46 +0900 |
parents | 10116463b0b1 |
children | 0bb8c405a7c7 |
comparison
equal
deleted
inserted
replaced
23135:e637dd64ba72 | 23136:6eab50a34fed |
---|---|
3 """ | 3 """ |
4 Small and dumb HTTP server for use in tests. | 4 Small and dumb HTTP server for use in tests. |
5 """ | 5 """ |
6 | 6 |
7 from optparse import OptionParser | 7 from optparse import OptionParser |
8 import BaseHTTPServer, SimpleHTTPServer, os, signal, subprocess, sys | 8 import BaseHTTPServer, SimpleHTTPServer, signal, sys |
9 | 9 |
10 from mercurial import cmdutil | |
10 | 11 |
11 def run(server_class=BaseHTTPServer.HTTPServer, | 12 class simplehttpservice(object): |
12 handler_class=SimpleHTTPServer.SimpleHTTPRequestHandler, | 13 def __init__(self, host, port): |
13 server_address=('localhost', 8000)): | 14 self.address = (host, port) |
14 httpd = server_class(server_address, handler_class) | 15 def init(self): |
15 httpd.serve_forever() | 16 self.httpd = BaseHTTPServer.HTTPServer( |
16 | 17 self.address, SimpleHTTPServer.SimpleHTTPRequestHandler) |
18 def run(self): | |
19 self.httpd.serve_forever() | |
17 | 20 |
18 if __name__ == '__main__': | 21 if __name__ == '__main__': |
19 parser = OptionParser() | 22 parser = OptionParser() |
20 parser.add_option('-p', '--port', dest='port', type='int', default=8000, | 23 parser.add_option('-p', '--port', dest='port', type='int', default=8000, |
21 help='TCP port to listen on', metavar='PORT') | 24 help='TCP port to listen on', metavar='PORT') |
24 parser.add_option('--pid', dest='pid', | 27 parser.add_option('--pid', dest='pid', |
25 help='file name where the PID of the server is stored') | 28 help='file name where the PID of the server is stored') |
26 parser.add_option('-f', '--foreground', dest='foreground', | 29 parser.add_option('-f', '--foreground', dest='foreground', |
27 action='store_true', | 30 action='store_true', |
28 help='do not start the HTTP server in the background') | 31 help='do not start the HTTP server in the background') |
32 parser.add_option('--daemon-pipefds') | |
29 | 33 |
30 (options, args) = parser.parse_args() | 34 (options, args) = parser.parse_args() |
31 | 35 |
32 signal.signal(signal.SIGTERM, lambda x, y: sys.exit(0)) | 36 signal.signal(signal.SIGTERM, lambda x, y: sys.exit(0)) |
33 | 37 |
34 if options.foreground and options.pid: | 38 if options.foreground and options.pid: |
35 parser.error("options --pid and --foreground are mutually exclusive") | 39 parser.error("options --pid and --foreground are mutually exclusive") |
36 | 40 |
37 if options.foreground: | 41 opts = {'pid_file': options.pid, |
38 run(server_address=(options.host, options.port)) | 42 'daemon': not options.foreground, |
39 else: | 43 'daemon_pipefds': options.daemon_pipefds} |
40 # This doesn't attempt to cleanly detach the process, as it's not | 44 service = simplehttpservice(options.host, options.port) |
41 # meant to be a long-lived, independent process. As a consequence, | 45 cmdutil.service(opts, initfn=service.init, runfn=service.run, |
42 # it's still part of the same process group, and keeps any file | 46 runargs=[sys.executable, __file__] + sys.argv[1:]) |
43 # descriptors it might have inherited besided stdin/stdout/stderr. | |
44 # Trying to do things cleanly is more complicated, requires | |
45 # OS-dependent code, and is not worth the effort. | |
46 proc = subprocess.Popen([sys.executable, __file__, '-f', | |
47 '-H', options.host, '-p', str(options.port)], | |
48 stdin=open(os.devnull, 'r'), | |
49 stdout=open(os.devnull, 'w'), | |
50 stderr=subprocess.STDOUT) | |
51 if options.pid: | |
52 fp = file(options.pid, 'wb') | |
53 fp.write(str(proc.pid) + '\n') | |
54 fp.close() |