Correct server test
This test was relying on the short sleep allowing the subprocess time to write to an external file. Rather than write to an external file, have the output go to a pipe that the test process can read so that the test doesn't have to guess how long to sleep. Change-Id: I128a9dc5c7525d941f6e00c0073d983eab1e44e6
This commit is contained in:
@@ -259,6 +259,7 @@ from %(module_name)s import %(import_target)s
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import argparse
|
import argparse
|
||||||
import socket
|
import socket
|
||||||
|
import sys
|
||||||
import wsgiref.simple_server as wss
|
import wsgiref.simple_server as wss
|
||||||
|
|
||||||
my_ip = socket.gethostbyname(socket.gethostname())
|
my_ip = socket.gethostbyname(socket.gethostname())
|
||||||
@@ -276,6 +277,7 @@ if __name__ == "__main__":
|
|||||||
print("Available at %%s" %% url)
|
print("Available at %%s" %% url)
|
||||||
print("DANGER! For testing only, do not use in production")
|
print("DANGER! For testing only, do not use in production")
|
||||||
print("*" * 80)
|
print("*" * 80)
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
server.serve_forever()
|
server.serve_forever()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ import os
|
|||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
|
||||||
import time
|
|
||||||
try:
|
try:
|
||||||
# python 2
|
# python 2
|
||||||
from urllib2 import urlopen
|
from urllib2 import urlopen
|
||||||
@@ -56,13 +54,9 @@ class TestWsgiScripts(base.BaseTestCase):
|
|||||||
|
|
||||||
This test actually attempts to start and interact with the
|
This test actually attempts to start and interact with the
|
||||||
wsgi script in question to demonstrate that it's a working
|
wsgi script in question to demonstrate that it's a working
|
||||||
wsgi script using simple server. It's a bit hokey because of
|
wsgi script using simple server.
|
||||||
process management that has to be done.
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.skipTest("Test skipped until we can determine a reliable "
|
|
||||||
"way to capture subprocess stdout without blocking")
|
|
||||||
|
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
self.skipTest('Windows support is passthrough')
|
self.skipTest('Windows support is passthrough')
|
||||||
|
|
||||||
@@ -75,12 +69,6 @@ class TestWsgiScripts(base.BaseTestCase):
|
|||||||
self.temp_dir,
|
self.temp_dir,
|
||||||
sys.version_info[0],
|
sys.version_info[0],
|
||||||
sys.version_info[1])))
|
sys.version_info[1])))
|
||||||
# NOTE(sdague): making python unbuffered is critical to
|
|
||||||
# getting output out of the subprocess.
|
|
||||||
self.useFixture(
|
|
||||||
fixtures.EnvironmentVariable(
|
|
||||||
'PYTHONUNBUFFERED', '1'))
|
|
||||||
|
|
||||||
self._check_wsgi_install_content(stdout)
|
self._check_wsgi_install_content(stdout)
|
||||||
|
|
||||||
# Live test run the scripts and see that they respond to wsgi
|
# Live test run the scripts and see that they respond to wsgi
|
||||||
@@ -90,54 +78,41 @@ class TestWsgiScripts(base.BaseTestCase):
|
|||||||
def _test_wsgi(self):
|
def _test_wsgi(self):
|
||||||
for cmd_name in self.cmd_names:
|
for cmd_name in self.cmd_names:
|
||||||
cmd = os.path.join(self.temp_dir, 'bin', cmd_name)
|
cmd = os.path.join(self.temp_dir, 'bin', cmd_name)
|
||||||
stdout = tempfile.NamedTemporaryFile()
|
print("Running %s -p 0" % cmd)
|
||||||
print("Running %s > %s" % (cmd, stdout.name))
|
p = subprocess.Popen([cmd, '-p', '0'], stdout=subprocess.PIPE,
|
||||||
# NOTE(sdague): ok, this looks a little janky, and it
|
stderr=subprocess.PIPE, cwd=self.temp_dir)
|
||||||
# is. However getting python to not hang with
|
|
||||||
# popen.communicate is beyond me.
|
|
||||||
#
|
|
||||||
# We're opening with a random port (so no conflicts), and
|
|
||||||
# redirecting all stdout and stderr to files. We can then
|
|
||||||
# safely read these files and not deadlock later in the
|
|
||||||
# test. This requires shell expansion.
|
|
||||||
p = subprocess.Popen(
|
|
||||||
"%s -p 0 > %s 2>&1" % (cmd, stdout.name),
|
|
||||||
shell=True,
|
|
||||||
close_fds=True,
|
|
||||||
cwd=self.temp_dir)
|
|
||||||
|
|
||||||
self.addCleanup(p.kill)
|
self.addCleanup(p.kill)
|
||||||
|
|
||||||
# the sleep is important to force a context switch to the
|
stdoutdata = p.stdout.readline() # ****...
|
||||||
# subprocess
|
|
||||||
time.sleep(0.1)
|
|
||||||
|
|
||||||
stdoutdata = stdout.read()
|
stdoutdata = p.stdout.readline() # STARTING test server...
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
"STARTING test server pbr_testpackage.wsgi",
|
b"STARTING test server pbr_testpackage.wsgi",
|
||||||
stdoutdata)
|
|
||||||
self.assertIn(
|
|
||||||
"DANGER! For testing only, do not use in production",
|
|
||||||
stdoutdata)
|
stdoutdata)
|
||||||
|
|
||||||
m = re.search('(http://[^:]+:\d+)/', stdoutdata)
|
stdoutdata = p.stdout.readline() # Available at ...
|
||||||
|
print(stdoutdata)
|
||||||
|
m = re.search(b'(http://[^:]+:\d+)/', stdoutdata)
|
||||||
self.assertIsNotNone(m, "Regex failed to match on %s" % stdoutdata)
|
self.assertIsNotNone(m, "Regex failed to match on %s" % stdoutdata)
|
||||||
|
|
||||||
f = urlopen(m.group(1))
|
stdoutdata = p.stdout.readline() # DANGER! ...
|
||||||
self.assertEqual("Hello World", f.read())
|
self.assertIn(
|
||||||
|
b"DANGER! For testing only, do not use in production",
|
||||||
|
stdoutdata)
|
||||||
|
|
||||||
# the sleep is important to force a context switch to the
|
stdoutdata = p.stdout.readline() # ***...
|
||||||
# subprocess
|
|
||||||
time.sleep(0.1)
|
|
||||||
|
|
||||||
# Kill off the child, it should force a flush of the stdout.
|
f = urlopen(m.group(1).decode('utf-8'))
|
||||||
p.kill()
|
self.assertEqual(b"Hello World", f.read())
|
||||||
time.sleep(0.1)
|
|
||||||
|
|
||||||
stdoutdata = stdout.read()
|
# Request again so that the application can force stderr.flush(),
|
||||||
|
# otherwise the log is buffered and the next readline() will hang.
|
||||||
|
urlopen(m.group(1).decode('utf-8'))
|
||||||
|
|
||||||
|
stdoutdata = p.stderr.readline()
|
||||||
# we should have logged an HTTP request, return code 200, that
|
# we should have logged an HTTP request, return code 200, that
|
||||||
# returned 11 bytes
|
# returned 11 bytes
|
||||||
self.assertIn('"GET / HTTP/1.1" 200 11', stdoutdata)
|
self.assertIn(b'"GET / HTTP/1.1" 200 11', stdoutdata)
|
||||||
|
|
||||||
def _check_wsgi_install_content(self, install_stdout):
|
def _check_wsgi_install_content(self, install_stdout):
|
||||||
for cmd_name in self.cmd_names:
|
for cmd_name in self.cmd_names:
|
||||||
@@ -153,6 +128,7 @@ class TestWsgiScripts(base.BaseTestCase):
|
|||||||
main_block = """if __name__ == "__main__":
|
main_block = """if __name__ == "__main__":
|
||||||
import argparse
|
import argparse
|
||||||
import socket
|
import socket
|
||||||
|
import sys
|
||||||
import wsgiref.simple_server as wss"""
|
import wsgiref.simple_server as wss"""
|
||||||
|
|
||||||
if cmd_name == 'pbr_test_wsgi':
|
if cmd_name == 'pbr_test_wsgi':
|
||||||
|
|||||||
@@ -14,10 +14,13 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
def application(env, start_response):
|
def application(env, start_response):
|
||||||
|
sys.stderr.flush() # Force the previous request log to be written.
|
||||||
start_response('200 OK', [('Content-Type', 'text/html')])
|
start_response('200 OK', [('Content-Type', 'text/html')])
|
||||||
return ["Hello World"]
|
return [b"Hello World"]
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|||||||
Reference in New Issue
Block a user