PageRenderTime 35ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/unit/test_disabledapps.py

https://bitbucket.org/ianb/silverlining/
Python | 169 lines | 121 code | 33 blank | 15 comment | 28 complexity | c8fea707146df63e0885bfaa01aaf4f4 MD5 | raw file
Possible License(s): GPL-2.0
  1. """Tests for the functionality around disabled applications"""
  2. import os
  3. import os.path
  4. import tempfile
  5. from contextlib import contextmanager, nested
  6. import sys
  7. import shutil
  8. from webtest import TestApp
  9. from silversupport import disabledapps
  10. from silversupport.appconfig import AppConfig
  11. from silversupport import appdata
  12. ROOT = os.path.join(os.path.dirname(__file__), '../..')
  13. @contextmanager
  14. def monkeypatch(module, global_, replacement):
  15. """Replace module.global_ with replacement"""
  16. if isinstance(module, str):
  17. __import__(module)
  18. module = sys.modules[module]
  19. old = getattr(module, global_)
  20. setattr(module, global_, replacement)
  21. try:
  22. yield
  23. finally:
  24. setattr(module, global_, old)
  25. @contextmanager
  26. def temporary_directory():
  27. """Make and then remove a temporary directory"""
  28. dirname = tempfile.mkdtemp()
  29. try:
  30. yield dirname
  31. finally:
  32. shutil.rmtree(dirname)
  33. @contextmanager
  34. def patch_disabled_apps_path(dirname):
  35. """Changes the location of the disabled apps list to be within dirname
  36. Returns the new path of the file
  37. """
  38. with monkeypatch(disabledapps, 'DISABLED_APPS_FILE',
  39. os.path.join(dirname, 'disabledapps.txt')):
  40. try:
  41. yield disabledapps.DISABLED_APPS_FILE
  42. finally:
  43. if os.path.exists(disabledapps.DISABLED_APPS_FILE):
  44. os.remove(disabledapps.DISABLED_APPS_FILE)
  45. def test_addition():
  46. """Adding an application should correctly write the file"""
  47. with temporary_directory() as tempdir:
  48. with patch_disabled_apps_path(tempdir) as path:
  49. disabledapps.disable_application('testapp')
  50. with open(path) as file_:
  51. lines = [line.strip() for line in file_]
  52. assert lines == ['testapp'], lines
  53. def test_is_disabled():
  54. """We should be able to identify disabled apps"""
  55. with temporary_directory() as tempdir:
  56. with patch_disabled_apps_path(tempdir):
  57. assert not disabledapps.is_disabled('testapp')
  58. disabledapps.disable_application('testapp')
  59. assert disabledapps.is_disabled('testapp')
  60. def test_removal():
  61. """Removing applications should work correctly"""
  62. with temporary_directory() as tempdir:
  63. with patch_disabled_apps_path(tempdir) as path:
  64. disabledapps.disable_application('testapp-a')
  65. disabledapps.disable_application('testapp-b')
  66. disabledapps.disable_application('testapp-c')
  67. disabledapps.enable_application('testapp-b')
  68. with open(path) as file_:
  69. lines = [line.strip() for line in file_]
  70. assert lines == ['testapp-a', 'testapp-c'], lines
  71. ## Utilities to help set up a disabled site
  72. def patch_deployment_location(dirname):
  73. """Replace /var/www with dirname, and set is_production to True"""
  74. return nested(
  75. patch_disabled_apps_path(dirname),
  76. monkeypatch(appdata, 'APPDATA_MAP',
  77. os.path.join(dirname, 'appdata.map')),
  78. monkeypatch('silversupport.appconfig', 'DEPLOYMENT_LOCATION', dirname),
  79. monkeypatch('silversupport.appconfig', 'is_production', lambda: True))
  80. def install_default_disabled(dirname):
  81. """Copy default-disabled into dirname"""
  82. default_disabled = os.path.join(
  83. ROOT, 'silverlining/server-root/var/www/default-disabled')
  84. shutil.copytree(default_disabled,
  85. os.path.join(dirname, 'default-disabled'))
  86. with open(os.path.join(dirname, 'appdata.map'), 'w') as file_:
  87. file_.write(
  88. "disabled / default-disabled|general_debug|/dev/null|python|\n")
  89. def install_sample_app(dirname):
  90. """copy sample app into dirname"""
  91. path = os.path.join(dirname, 'sampleapp.0')
  92. os.mkdir(path)
  93. with open(os.path.join(path, 'app.ini'), 'w') as file_:
  94. file_.write('[production]\n')
  95. file_.write('app_name = sampleapp\n')
  96. file_.write('runner = app.py#application\n')
  97. with open(os.path.join(path, 'app.py'), 'w') as file_:
  98. file_.write(
  99. 'from wsgiref.simple_server import demo_app as application\n')
  100. appdata.add_appdata('sampleapp.0', ['www.example.com'])
  101. @contextmanager
  102. def disabled_site():
  103. with temporary_directory() as tempdir:
  104. with patch_deployment_location(tempdir):
  105. install_default_disabled(tempdir)
  106. install_sample_app(tempdir)
  107. disabledapps.disable_application('sampleapp')
  108. app_config = AppConfig.from_location('www.example.com')
  109. app = app_config.get_app_from_runner()
  110. yield app
  111. def test_loading_disabled_site():
  112. """Loading a site should return a DisabledSite when the site is disabled"""
  113. with disabled_site() as app:
  114. assert isinstance(app, disabledapps.DisabledSite), app
  115. def test_disabled_site_is_disabled():
  116. with disabled_site() as app:
  117. test_app = TestApp(app)
  118. response = test_app.get(
  119. '/', headers={'X-Forwarded-For':'123.123.123.123, localhost'},
  120. status=503)
  121. def test_disabled_site_commandline_internal_access():
  122. with disabled_site() as app:
  123. test_app = TestApp(app)
  124. response = test_app.get(
  125. '/', headers={'X-Forwarded-For':'123.123.123.123, localhost'},
  126. extra_environ={'silverlining.update': True},
  127. status=200)
  128. assert response.body.startswith('Hello world!'), str(response)
  129. def test_disabled_site_local_access():
  130. with disabled_site() as app:
  131. test_app = TestApp(app)
  132. response = test_app.get(
  133. '/', headers={'X-Forwarded-For':'localhost, localhost'})
  134. assert response.status.startswith('200')
  135. assert response.body.startswith('Hello world!')