tests: pull common http server setup out of individual tests
authorMike Hommey <mh@glandium.org>
Thu, 16 Oct 2014 13:48:51 +0900
changeset 22959 10116463b0b1
parent 22958 bb7a911b138e
child 22960 7c13c9404c2c
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.
tests/dumbhttp.py
tests/test-bad-pull.t
tests/test-static-http.t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/dumbhttp.py	Thu Oct 16 13:48:51 2014 +0900
@@ -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()
--- a/tests/test-bad-pull.t	Wed Sep 24 16:00:47 2014 +0900
+++ b/tests/test-bad-pull.t	Thu Oct 16 13:48:51 2014 +0900
@@ -1,4 +1,4 @@
-#require serve
+#require serve killdaemons
 
 #if windows
   $ hg clone http://localhost:$HGPORT/ copy
@@ -13,21 +13,9 @@
   $ 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
--- a/tests/test-static-http.t	Wed Sep 24 16:00:47 2014 +0900
+++ b/tests/test-static-http.t	Thu Oct 16 13:48:51 2014 +0900
@@ -15,36 +15,7 @@
 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