test_wsgi.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. # Copyright (c) 2015 Hewlett-Packard Development Company, L.P. (HP)
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. # not use this file except in compliance with the License. You may obtain
  5. # a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. # License for the specific language governing permissions and limitations
  13. # under the License.
  14. import os
  15. import re
  16. import subprocess
  17. import sys
  18. try:
  19. # python 2
  20. from urllib2 import urlopen
  21. except ImportError:
  22. # python 3
  23. from urllib.request import urlopen
  24. from pbr.tests import base
  25. class TestWsgiScripts(base.BaseTestCase):
  26. cmd_names = ('pbr_test_wsgi', 'pbr_test_wsgi_with_class')
  27. def _get_path(self):
  28. if os.path.isdir("%s/lib64" % self.temp_dir):
  29. path = "%s/lib64" % self.temp_dir
  30. elif os.path.isdir("%s/lib" % self.temp_dir):
  31. path = "%s/lib" % self.temp_dir
  32. elif os.path.isdir("%s/site-packages" % self.temp_dir):
  33. return ".:%s/site-packages" % self.temp_dir
  34. else:
  35. raise Exception("Could not determine path for test")
  36. return ".:%s/python%s.%s/site-packages" % (
  37. path,
  38. sys.version_info[0],
  39. sys.version_info[1])
  40. def test_wsgi_script_install(self):
  41. """Test that we install a non-pkg-resources wsgi script."""
  42. if os.name == 'nt':
  43. self.skipTest('Windows support is passthrough')
  44. stdout, _, return_code = self.run_setup(
  45. 'install', '--prefix=%s' % self.temp_dir)
  46. self._check_wsgi_install_content(stdout)
  47. def test_wsgi_script_run(self):
  48. """Test that we install a runnable wsgi script.
  49. This test actually attempts to start and interact with the
  50. wsgi script in question to demonstrate that it's a working
  51. wsgi script using simple server.
  52. """
  53. if os.name == 'nt':
  54. self.skipTest('Windows support is passthrough')
  55. stdout, _, return_code = self.run_setup(
  56. 'install', '--prefix=%s' % self.temp_dir)
  57. self._check_wsgi_install_content(stdout)
  58. # Live test run the scripts and see that they respond to wsgi
  59. # requests.
  60. for cmd_name in self.cmd_names:
  61. self._test_wsgi(cmd_name, b'Hello World')
  62. def _test_wsgi(self, cmd_name, output, extra_args=None):
  63. cmd = os.path.join(self.temp_dir, 'bin', cmd_name)
  64. print("Running %s -p 0 -b 127.0.0.1" % cmd)
  65. popen_cmd = [cmd, '-p', '0', '-b', '127.0.0.1']
  66. if extra_args:
  67. popen_cmd.extend(extra_args)
  68. env = {'PYTHONPATH': self._get_path()}
  69. p = subprocess.Popen(popen_cmd, stdout=subprocess.PIPE,
  70. stderr=subprocess.PIPE, cwd=self.temp_dir,
  71. env=env)
  72. self.addCleanup(p.kill)
  73. stdoutdata = p.stdout.readline() # ****...
  74. stdoutdata = p.stdout.readline() # STARTING test server...
  75. self.assertIn(
  76. b"STARTING test server pbr_testpackage.wsgi",
  77. stdoutdata)
  78. stdoutdata = p.stdout.readline() # Available at ...
  79. print(stdoutdata)
  80. m = re.search(br'(http://[^:]+:\d+)/', stdoutdata)
  81. self.assertIsNotNone(m, "Regex failed to match on %s" % stdoutdata)
  82. stdoutdata = p.stdout.readline() # DANGER! ...
  83. self.assertIn(
  84. b"DANGER! For testing only, do not use in production",
  85. stdoutdata)
  86. stdoutdata = p.stdout.readline() # ***...
  87. f = urlopen(m.group(1).decode('utf-8'))
  88. self.assertEqual(output, f.read())
  89. # Request again so that the application can force stderr.flush(),
  90. # otherwise the log is buffered and the next readline() will hang.
  91. urlopen(m.group(1).decode('utf-8'))
  92. stdoutdata = p.stderr.readline()
  93. # we should have logged an HTTP request, return code 200, that
  94. # returned the right amount of bytes
  95. status = '"GET / HTTP/1.1" 200 %d' % len(output)
  96. self.assertIn(status.encode('utf-8'), stdoutdata)
  97. def _check_wsgi_install_content(self, install_stdout):
  98. for cmd_name in self.cmd_names:
  99. install_txt = 'Installing %s script to %s' % (cmd_name,
  100. self.temp_dir)
  101. self.assertIn(install_txt, install_stdout)
  102. cmd_filename = os.path.join(self.temp_dir, 'bin', cmd_name)
  103. script_txt = open(cmd_filename, 'r').read()
  104. self.assertNotIn('pkg_resources', script_txt)
  105. main_block = """if __name__ == "__main__":
  106. import argparse
  107. import socket
  108. import sys
  109. import wsgiref.simple_server as wss"""
  110. if cmd_name == 'pbr_test_wsgi':
  111. app_name = "main"
  112. else:
  113. app_name = "WSGI.app"
  114. starting_block = ("STARTING test server pbr_testpackage.wsgi."
  115. "%s" % app_name)
  116. else_block = """else:
  117. application = None"""
  118. self.assertIn(main_block, script_txt)
  119. self.assertIn(starting_block, script_txt)
  120. self.assertIn(else_block, script_txt)
  121. def test_with_argument(self):
  122. if os.name == 'nt':
  123. self.skipTest('Windows support is passthrough')
  124. stdout, _, return_code = self.run_setup(
  125. 'install', '--prefix=%s' % self.temp_dir)
  126. self._test_wsgi('pbr_test_wsgi', b'Foo Bar', ["--", "-c", "Foo Bar"])