Patchwork [2,of,7,V3] tests: pull common http server setup out of individual tests

login
register
mail settings
Submitter Mike Hommey
Date Oct. 16, 2014, 8:22 a.m.
Message ID <e13a2965567b090b5dfc.1413447747@zenigata.glandium.org>
Download mbox | patch
Permalink /patch/6315/
State Accepted
Headers show

Comments

Mike Hommey - Oct. 16, 2014, 8:22 a.m.
# HG changeset patch
# User Mike Hommey <mh@glandium.org>
# Date 1413434931 -32400
#      Thu Oct 16 13:48:51 2014 +0900
# Node ID e13a2965567b090b5dfc2c1d42547956840a2581
# Parent  97135fb11cee697a17fbc2409c730e2c5b0a1edc
tests: pull common http server setup out of individual tests

There are currently two different tests using roughly the same code to
create temporary scripts acting as HTTP servers. As there is going to
be at least one more in an upcoming change, factor those out in a
standalone dumbhttp.py script.

Patch

diff --git a/tests/dumbhttp.py b/tests/dumbhttp.py
new file mode 100644
--- /dev/null
+++ b/tests/dumbhttp.py
@@ -0,0 +1,54 @@ 
+#!/usr/bin/env python
+
+"""
+Small and dumb HTTP server for use in tests.
+"""
+
+from optparse import OptionParser
+import BaseHTTPServer, SimpleHTTPServer, os, signal, subprocess, sys
+
+
+def run(server_class=BaseHTTPServer.HTTPServer,
+        handler_class=SimpleHTTPServer.SimpleHTTPRequestHandler,
+        server_address=('localhost', 8000)):
+    httpd = server_class(server_address, handler_class)
+    httpd.serve_forever()
+
+
+if __name__ == '__main__':
+    parser = OptionParser()
+    parser.add_option('-p', '--port', dest='port', type='int', default=8000,
+        help='TCP port to listen on', metavar='PORT')
+    parser.add_option('-H', '--host', dest='host', default='localhost',
+        help='hostname or IP to listen on', metavar='HOST')
+    parser.add_option('--pid', dest='pid',
+        help='file name where the PID of the server is stored')
+    parser.add_option('-f', '--foreground', dest='foreground',
+        action='store_true',
+        help='do not start the HTTP server in the background')
+
+    (options, args) = parser.parse_args()
+
+    signal.signal(signal.SIGTERM, lambda x, y: sys.exit(0))
+
+    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()
diff --git a/tests/test-bad-pull.t b/tests/test-bad-pull.t
--- a/tests/test-bad-pull.t
+++ b/tests/test-bad-pull.t
@@ -1,33 +1,21 @@ 
-#require serve
+#require serve killdaemons
 
 #if windows
   $ hg clone http://localhost:$HGPORT/ copy
   abort: * (glob)
   [255]
 #else
   $ hg clone http://localhost:$HGPORT/ copy
   abort: error: Connection refused
   [255]
 #endif
 
   $ test -d copy
   [1]
 
-  $ cat > dumb.py <<EOF
-  > import BaseHTTPServer, SimpleHTTPServer, os, signal
-  > def run(server_class=BaseHTTPServer.HTTPServer,
-  >         handler_class=SimpleHTTPServer.SimpleHTTPRequestHandler):
-  >     server_address = ('localhost', int(os.environ['HGPORT']))
-  >     httpd = server_class(server_address, handler_class)
-  >     open("listening", "w")
-  >     httpd.handle_request()
-  > run()
-  > EOF
-
-  $ python dumb.py 2> log &
-  $ P=$!
-  $ while [ ! -f listening ]; do sleep 0; done
+  $ python "$TESTDIR/dumbhttp.py" -p $HGPORT --pid dumb.pid
+  $ cat dumb.pid >> $DAEMON_PIDS
   $ hg clone http://localhost:$HGPORT/foo copy2
   abort: HTTP Error 404: * (glob)
   [255]
-  $ wait $P
+  $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
diff --git a/tests/test-static-http.t b/tests/test-static-http.t
--- a/tests/test-static-http.t
+++ b/tests/test-static-http.t
@@ -10,46 +10,17 @@ 
   [255]
 #endif
   $ test -d copy
   [1]
 
 This server doesn't do range requests so it's basically only good for
 one pull
 
-  $ cat > dumb.py <<EOF
-  > import BaseHTTPServer, SimpleHTTPServer, os, signal, sys
-  > 
-  > def run(server_class=BaseHTTPServer.HTTPServer,
-  >         handler_class=SimpleHTTPServer.SimpleHTTPRequestHandler):
-  >     server_address = ('localhost', int(os.environ['HGPORT']))
-  >     httpd = server_class(server_address, handler_class)
-  >     httpd.serve_forever()
-  > 
-  > signal.signal(signal.SIGTERM, lambda x, y: sys.exit(0))
-  > fp = file('dumb.pid', 'wb')
-  > fp.write(str(os.getpid()) + '\n')
-  > fp.close()
-  > run()
-  > EOF
-  $ python dumb.py 2>/dev/null &
-
-Cannot just read $!, it will not be set to the right value on Windows/MinGW
-
-  $ cat > wait.py <<EOF
-  > import time
-  > while True:
-  >     try:
-  >         if '\n' in file('dumb.pid', 'rb').read():
-  >             break
-  >     except IOError:
-  >         pass
-  >     time.sleep(0.2)
-  > EOF
-  $ python wait.py
+  $ python "$TESTDIR/dumbhttp.py" -p $HGPORT --pid dumb.pid
   $ cat dumb.pid >> $DAEMON_PIDS
   $ hg init remote
   $ cd remote
   $ echo foo > bar
   $ echo c2 > '.dotfile with spaces'
   $ hg add
   adding .dotfile with spaces
   adding bar