Patchwork tests: have dumbhttp.py use cmdutil.service() to wait for child to listen()

login
register
mail settings
Submitter Yuya Nishihara
Date Nov. 2, 2014, 5:31 a.m.
Message ID <c9458f88c411d38726ae.1414906299@mimosa>
Download mbox | patch
Permalink /patch/6516/
State Accepted
Headers show

Comments

Yuya Nishihara - Nov. 2, 2014, 5:31 a.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1414901326 -32400
#      Sun Nov 02 13:08:46 2014 +0900
# Branch stable
# Node ID c9458f88c411d38726ae8b715b7f942a40957fb4
# Parent  cc1cbb0bba8ed1d95c8f1b8e27d4d2893e0dcca7
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.
Matt Mackall - Nov. 3, 2014, 8:04 p.m.
On Sun, 2014-11-02 at 14:31 +0900, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1414901326 -32400
> #      Sun Nov 02 13:08:46 2014 +0900
> # Branch stable
> # Node ID c9458f88c411d38726ae8b715b7f942a40957fb4
> # Parent  cc1cbb0bba8ed1d95c8f1b8e27d4d2893e0dcca7
> tests: have dumbhttp.py use cmdutil.service() to wait for child to listen()

Queued for default, thanks.

Patch

diff --git a/tests/dumbhttp.py b/tests/dumbhttp.py
--- a/tests/dumbhttp.py
+++ b/tests/dumbhttp.py
@@ -5,15 +5,18 @@  Small and dumb HTTP server for use in te
 """
 
 from optparse import OptionParser
-import BaseHTTPServer, SimpleHTTPServer, os, signal, subprocess, sys
+import BaseHTTPServer, SimpleHTTPServer, signal, sys
 
+from mercurial import cmdutil
 
-def run(server_class=BaseHTTPServer.HTTPServer,
-        handler_class=SimpleHTTPServer.SimpleHTTPRequestHandler,
-        server_address=('localhost', 8000)):
-    httpd = server_class(server_address, handler_class)
-    httpd.serve_forever()
-
+class simplehttpservice(object):
+    def __init__(self, host, port):
+        self.address = (host, port)
+    def init(self):
+        self.httpd = BaseHTTPServer.HTTPServer(
+            self.address, SimpleHTTPServer.SimpleHTTPRequestHandler)
+    def run(self):
+        self.httpd.serve_forever()
 
 if __name__ == '__main__':
     parser = OptionParser()
@@ -26,6 +29,7 @@  if __name__ == '__main__':
     parser.add_option('-f', '--foreground', dest='foreground',
         action='store_true',
         help='do not start the HTTP server in the background')
+    parser.add_option('--daemon-pipefds')
 
     (options, args) = parser.parse_args()
 
@@ -34,21 +38,9 @@  if __name__ == '__main__':
     if options.foreground and options.pid:
         parser.error("options --pid and --foreground are mutually exclusive")
 
-    if options.foreground:
-        run(server_address=(options.host, options.port))
-    else:
-        # This doesn't attempt to cleanly detach the process, as it's not
-        # meant to be a long-lived, independent process. As a consequence,
-        # it's still part of the same process group, and keeps any file
-        # descriptors it might have inherited besided stdin/stdout/stderr.
-        # Trying to do things cleanly is more complicated, requires
-        # OS-dependent code, and is not worth the effort.
-        proc = subprocess.Popen([sys.executable, __file__, '-f',
-            '-H', options.host, '-p', str(options.port)],
-            stdin=open(os.devnull, 'r'),
-            stdout=open(os.devnull, 'w'),
-            stderr=subprocess.STDOUT)
-        if options.pid:
-            fp = file(options.pid, 'wb')
-            fp.write(str(proc.pid) + '\n')
-            fp.close()
+    opts = {'pid_file': options.pid,
+            'daemon': not options.foreground,
+            'daemon_pipefds': options.daemon_pipefds}
+    service = simplehttpservice(options.host, options.port)
+    cmdutil.service(opts, initfn=service.init, runfn=service.run,
+                    runargs=[sys.executable, __file__] + sys.argv[1:])