| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- import os
- import shutil
- import subprocess
- from subprocess import Popen
- import sys
- from tempfile import mkdtemp
- import time
- import unittest
- class AutoreloadTest(unittest.TestCase):
- def setUp(self):
- self.path = mkdtemp()
- def tearDown(self):
- try:
- shutil.rmtree(self.path)
- except OSError:
- # Windows disallows deleting files that are in use by
- # another process, and even though we've waited for our
- # child process below, it appears that its lock on these
- # files is not guaranteed to be released by this point.
- # Sleep and try again (once).
- time.sleep(1)
- shutil.rmtree(self.path)
- def test_reload_module(self):
- main = """\
- import os
- import sys
- from tornado import autoreload
- # This import will fail if path is not set up correctly
- import testapp
- print('Starting')
- if 'TESTAPP_STARTED' not in os.environ:
- os.environ['TESTAPP_STARTED'] = '1'
- sys.stdout.flush()
- autoreload._reload()
- """
- # Create temporary test application
- os.mkdir(os.path.join(self.path, "testapp"))
- open(os.path.join(self.path, "testapp/__init__.py"), "w").close()
- with open(os.path.join(self.path, "testapp/__main__.py"), "w") as f:
- f.write(main)
- # Make sure the tornado module under test is available to the test
- # application
- pythonpath = os.getcwd()
- if "PYTHONPATH" in os.environ:
- pythonpath += os.pathsep + os.environ["PYTHONPATH"]
- p = Popen(
- [sys.executable, "-m", "testapp"],
- stdout=subprocess.PIPE,
- cwd=self.path,
- env=dict(os.environ, PYTHONPATH=pythonpath),
- universal_newlines=True,
- )
- out = p.communicate()[0]
- self.assertEqual(out, "Starting\nStarting\n")
- def test_reload_wrapper_preservation(self):
- # This test verifies that when `python -m tornado.autoreload`
- # is used on an application that also has an internal
- # autoreload, the reload wrapper is preserved on restart.
- main = """\
- import os
- import sys
- # This import will fail if path is not set up correctly
- import testapp
- if 'tornado.autoreload' not in sys.modules:
- raise Exception('started without autoreload wrapper')
- import tornado.autoreload
- print('Starting')
- sys.stdout.flush()
- if 'TESTAPP_STARTED' not in os.environ:
- os.environ['TESTAPP_STARTED'] = '1'
- # Simulate an internal autoreload (one not caused
- # by the wrapper).
- tornado.autoreload._reload()
- else:
- # Exit directly so autoreload doesn't catch it.
- os._exit(0)
- """
- # Create temporary test application
- os.mkdir(os.path.join(self.path, "testapp"))
- init_file = os.path.join(self.path, "testapp", "__init__.py")
- open(init_file, "w").close()
- main_file = os.path.join(self.path, "testapp", "__main__.py")
- with open(main_file, "w") as f:
- f.write(main)
- # Make sure the tornado module under test is available to the test
- # application
- pythonpath = os.getcwd()
- if "PYTHONPATH" in os.environ:
- pythonpath += os.pathsep + os.environ["PYTHONPATH"]
- autoreload_proc = Popen(
- [sys.executable, "-m", "tornado.autoreload", "-m", "testapp"],
- stdout=subprocess.PIPE,
- cwd=self.path,
- env=dict(os.environ, PYTHONPATH=pythonpath),
- universal_newlines=True,
- )
- # This timeout needs to be fairly generous for pypy due to jit
- # warmup costs.
- for i in range(40):
- if autoreload_proc.poll() is not None:
- break
- time.sleep(0.1)
- else:
- autoreload_proc.kill()
- raise Exception("subprocess failed to terminate")
- out = autoreload_proc.communicate()[0]
- self.assertEqual(out, "Starting\n" * 2)
|