autoreload_test.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. from __future__ import absolute_import, division, print_function
  2. import os
  3. import shutil
  4. import subprocess
  5. from subprocess import Popen
  6. import sys
  7. from tempfile import mkdtemp
  8. import time
  9. from tornado.test.util import unittest
  10. class AutoreloadTest(unittest.TestCase):
  11. def test_reload_module(self):
  12. main = """\
  13. import os
  14. import sys
  15. from tornado import autoreload
  16. # This import will fail if path is not set up correctly
  17. import testapp
  18. print('Starting')
  19. if 'TESTAPP_STARTED' not in os.environ:
  20. os.environ['TESTAPP_STARTED'] = '1'
  21. sys.stdout.flush()
  22. autoreload._reload()
  23. """
  24. # Create temporary test application
  25. path = mkdtemp()
  26. self.addCleanup(shutil.rmtree, path)
  27. os.mkdir(os.path.join(path, 'testapp'))
  28. open(os.path.join(path, 'testapp/__init__.py'), 'w').close()
  29. with open(os.path.join(path, 'testapp/__main__.py'), 'w') as f:
  30. f.write(main)
  31. # Make sure the tornado module under test is available to the test
  32. # application
  33. pythonpath = os.getcwd()
  34. if 'PYTHONPATH' in os.environ:
  35. pythonpath += os.pathsep + os.environ['PYTHONPATH']
  36. p = Popen(
  37. [sys.executable, '-m', 'testapp'], stdout=subprocess.PIPE,
  38. cwd=path, env=dict(os.environ, PYTHONPATH=pythonpath),
  39. universal_newlines=True)
  40. out = p.communicate()[0]
  41. self.assertEqual(out, 'Starting\nStarting\n')
  42. def test_reload_wrapper_preservation(self):
  43. # This test verifies that when `python -m tornado.autoreload`
  44. # is used on an application that also has an internal
  45. # autoreload, the reload wrapper is preserved on restart.
  46. main = """\
  47. import os
  48. import sys
  49. # This import will fail if path is not set up correctly
  50. import testapp
  51. if 'tornado.autoreload' not in sys.modules:
  52. raise Exception('started without autoreload wrapper')
  53. import tornado.autoreload
  54. print('Starting')
  55. sys.stdout.flush()
  56. if 'TESTAPP_STARTED' not in os.environ:
  57. os.environ['TESTAPP_STARTED'] = '1'
  58. # Simulate an internal autoreload (one not caused
  59. # by the wrapper).
  60. tornado.autoreload._reload()
  61. else:
  62. # Exit directly so autoreload doesn't catch it.
  63. os._exit(0)
  64. """
  65. # Create temporary test application
  66. path = mkdtemp()
  67. os.mkdir(os.path.join(path, 'testapp'))
  68. self.addCleanup(shutil.rmtree, path)
  69. init_file = os.path.join(path, 'testapp', '__init__.py')
  70. open(init_file, 'w').close()
  71. main_file = os.path.join(path, 'testapp', '__main__.py')
  72. with open(main_file, 'w') as f:
  73. f.write(main)
  74. # Make sure the tornado module under test is available to the test
  75. # application
  76. pythonpath = os.getcwd()
  77. if 'PYTHONPATH' in os.environ:
  78. pythonpath += os.pathsep + os.environ['PYTHONPATH']
  79. autoreload_proc = Popen(
  80. [sys.executable, '-m', 'tornado.autoreload', '-m', 'testapp'],
  81. stdout=subprocess.PIPE, cwd=path,
  82. env=dict(os.environ, PYTHONPATH=pythonpath),
  83. universal_newlines=True)
  84. # This timeout needs to be fairly generous for pypy due to jit
  85. # warmup costs.
  86. for i in range(40):
  87. if autoreload_proc.poll() is not None:
  88. break
  89. time.sleep(0.1)
  90. else:
  91. autoreload_proc.kill()
  92. raise Exception("subprocess failed to terminate")
  93. out = autoreload_proc.communicate()[0]
  94. self.assertEqual(out, 'Starting\n' * 2)