tests.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. import sys
  4. from django.apps import apps
  5. from django.core import checks
  6. from django.core.checks import Error, Warning
  7. from django.core.checks.registry import CheckRegistry
  8. from django.core.management import call_command
  9. from django.core.management.base import CommandError
  10. from django.db import models
  11. from django.test import SimpleTestCase
  12. from django.test.utils import override_settings, override_system_checks
  13. from django.utils.encoding import force_text
  14. from django.utils.six import StringIO
  15. from .models import SimpleModel
  16. class DummyObj(object):
  17. def __repr__(self):
  18. return "obj"
  19. class SystemCheckFrameworkTests(SimpleTestCase):
  20. def test_register_and_run_checks(self):
  21. def f(**kwargs):
  22. calls[0] += 1
  23. return [1, 2, 3]
  24. def f2(**kwargs):
  25. return [4, ]
  26. def f3(**kwargs):
  27. return [5, ]
  28. calls = [0]
  29. # test register as decorator
  30. registry = CheckRegistry()
  31. registry.register()(f)
  32. registry.register("tag1", "tag2")(f2)
  33. registry.register("tag2", deploy=True)(f3)
  34. # test register as function
  35. registry2 = CheckRegistry()
  36. registry2.register(f)
  37. registry2.register(f2, "tag1", "tag2")
  38. registry2.register(f3, "tag2", deploy=True)
  39. # check results
  40. errors = registry.run_checks()
  41. errors2 = registry2.run_checks()
  42. self.assertEqual(errors, errors2)
  43. self.assertEqual(sorted(errors), [1, 2, 3, 4])
  44. self.assertEqual(calls[0], 2)
  45. errors = registry.run_checks(tags=["tag1"])
  46. errors2 = registry2.run_checks(tags=["tag1"])
  47. self.assertEqual(errors, errors2)
  48. self.assertEqual(sorted(errors), [4])
  49. errors = registry.run_checks(tags=["tag1", "tag2"], include_deployment_checks=True)
  50. errors2 = registry2.run_checks(tags=["tag1", "tag2"], include_deployment_checks=True)
  51. self.assertEqual(errors, errors2)
  52. self.assertEqual(sorted(errors), [4, 5])
  53. class MessageTests(SimpleTestCase):
  54. def test_printing(self):
  55. e = Error("Message", hint="Hint", obj=DummyObj())
  56. expected = "obj: Message\n\tHINT: Hint"
  57. self.assertEqual(force_text(e), expected)
  58. def test_printing_no_hint(self):
  59. e = Error("Message", hint=None, obj=DummyObj())
  60. expected = "obj: Message"
  61. self.assertEqual(force_text(e), expected)
  62. def test_printing_no_object(self):
  63. e = Error("Message", hint="Hint", obj=None)
  64. expected = "?: Message\n\tHINT: Hint"
  65. self.assertEqual(force_text(e), expected)
  66. def test_printing_with_given_id(self):
  67. e = Error("Message", hint="Hint", obj=DummyObj(), id="ID")
  68. expected = "obj: (ID) Message\n\tHINT: Hint"
  69. self.assertEqual(force_text(e), expected)
  70. def test_printing_field_error(self):
  71. field = SimpleModel._meta.get_field('field')
  72. e = Error("Error", hint=None, obj=field)
  73. expected = "check_framework.SimpleModel.field: Error"
  74. self.assertEqual(force_text(e), expected)
  75. def test_printing_model_error(self):
  76. e = Error("Error", hint=None, obj=SimpleModel)
  77. expected = "check_framework.SimpleModel: Error"
  78. self.assertEqual(force_text(e), expected)
  79. def test_printing_manager_error(self):
  80. manager = SimpleModel.manager
  81. e = Error("Error", hint=None, obj=manager)
  82. expected = "check_framework.SimpleModel.manager: Error"
  83. self.assertEqual(force_text(e), expected)
  84. def simple_system_check(**kwargs):
  85. simple_system_check.kwargs = kwargs
  86. return []
  87. def tagged_system_check(**kwargs):
  88. tagged_system_check.kwargs = kwargs
  89. return []
  90. tagged_system_check.tags = ['simpletag']
  91. def deployment_system_check(**kwargs):
  92. deployment_system_check.kwargs = kwargs
  93. return [checks.Warning('Deployment Check')]
  94. deployment_system_check.tags = ['deploymenttag']
  95. class CheckCommandTests(SimpleTestCase):
  96. def setUp(self):
  97. simple_system_check.kwargs = None
  98. tagged_system_check.kwargs = None
  99. self.old_stdout, self.old_stderr = sys.stdout, sys.stderr
  100. sys.stdout, sys.stderr = StringIO(), StringIO()
  101. def tearDown(self):
  102. sys.stdout, sys.stderr = self.old_stdout, self.old_stderr
  103. @override_system_checks([simple_system_check, tagged_system_check])
  104. def test_simple_call(self):
  105. call_command('check')
  106. self.assertEqual(simple_system_check.kwargs, {'app_configs': None})
  107. self.assertEqual(tagged_system_check.kwargs, {'app_configs': None})
  108. @override_system_checks([simple_system_check, tagged_system_check])
  109. def test_given_app(self):
  110. call_command('check', 'auth', 'admin')
  111. auth_config = apps.get_app_config('auth')
  112. admin_config = apps.get_app_config('admin')
  113. self.assertEqual(simple_system_check.kwargs, {'app_configs': [auth_config, admin_config]})
  114. self.assertEqual(tagged_system_check.kwargs, {'app_configs': [auth_config, admin_config]})
  115. @override_system_checks([simple_system_check, tagged_system_check])
  116. def test_given_tag(self):
  117. call_command('check', tags=['simpletag'])
  118. self.assertEqual(simple_system_check.kwargs, None)
  119. self.assertEqual(tagged_system_check.kwargs, {'app_configs': None})
  120. @override_system_checks([simple_system_check, tagged_system_check])
  121. def test_invalid_tag(self):
  122. self.assertRaises(CommandError, call_command, 'check', tags=['missingtag'])
  123. @override_system_checks([simple_system_check])
  124. def test_list_tags_empty(self):
  125. call_command('check', list_tags=True)
  126. self.assertEqual('\n', sys.stdout.getvalue())
  127. @override_system_checks([tagged_system_check])
  128. def test_list_tags(self):
  129. call_command('check', list_tags=True)
  130. self.assertEqual('simpletag\n', sys.stdout.getvalue())
  131. @override_system_checks([tagged_system_check], deployment_checks=[deployment_system_check])
  132. def test_list_deployment_check_omitted(self):
  133. call_command('check', list_tags=True)
  134. self.assertEqual('simpletag\n', sys.stdout.getvalue())
  135. @override_system_checks([tagged_system_check], deployment_checks=[deployment_system_check])
  136. def test_list_deployment_check_included(self):
  137. call_command('check', deploy=True, list_tags=True)
  138. self.assertEqual('deploymenttag\nsimpletag\n', sys.stdout.getvalue())
  139. @override_system_checks([tagged_system_check], deployment_checks=[deployment_system_check])
  140. def test_tags_deployment_check_omitted(self):
  141. msg = 'There is no system check with the "deploymenttag" tag.'
  142. with self.assertRaisesMessage(CommandError, msg):
  143. call_command('check', tags=['deploymenttag'])
  144. @override_system_checks([tagged_system_check], deployment_checks=[deployment_system_check])
  145. def test_tags_deployment_check_included(self):
  146. call_command('check', deploy=True, tags=['deploymenttag'])
  147. self.assertIn('Deployment Check', sys.stderr.getvalue())
  148. def custom_error_system_check(app_configs, **kwargs):
  149. return [
  150. Error(
  151. 'Error',
  152. hint=None,
  153. id='myerrorcheck.E001',
  154. )
  155. ]
  156. def custom_warning_system_check(app_configs, **kwargs):
  157. return [
  158. Warning(
  159. 'Warning',
  160. hint=None,
  161. id='mywarningcheck.E001',
  162. )
  163. ]
  164. class SilencingCheckTests(SimpleTestCase):
  165. def setUp(self):
  166. self.old_stdout, self.old_stderr = sys.stdout, sys.stderr
  167. self.stdout, self.stderr = StringIO(), StringIO()
  168. sys.stdout, sys.stderr = self.stdout, self.stderr
  169. def tearDown(self):
  170. sys.stdout, sys.stderr = self.old_stdout, self.old_stderr
  171. @override_settings(SILENCED_SYSTEM_CHECKS=['myerrorcheck.E001'])
  172. @override_system_checks([custom_error_system_check])
  173. def test_silenced_error(self):
  174. out = StringIO()
  175. err = StringIO()
  176. try:
  177. call_command('check', stdout=out, stderr=err)
  178. except CommandError:
  179. self.fail("The mycheck.E001 check should be silenced.")
  180. self.assertEqual(out.getvalue(), '')
  181. self.assertEqual(
  182. err.getvalue(),
  183. 'System check identified some issues:\n\n'
  184. 'ERRORS:\n'
  185. '?: (myerrorcheck.E001) Error\n\n'
  186. 'System check identified 1 issue (0 silenced).\n'
  187. )
  188. @override_settings(SILENCED_SYSTEM_CHECKS=['mywarningcheck.E001'])
  189. @override_system_checks([custom_warning_system_check])
  190. def test_silenced_warning(self):
  191. out = StringIO()
  192. err = StringIO()
  193. try:
  194. call_command('check', stdout=out, stderr=err)
  195. except CommandError:
  196. self.fail("The mycheck.E001 check should be silenced.")
  197. self.assertEqual(out.getvalue(), 'System check identified no issues (1 silenced).\n')
  198. self.assertEqual(err.getvalue(), '')
  199. class IsolateModelsMixin(object):
  200. def setUp(self):
  201. self.current_models = apps.all_models[__package__]
  202. self.saved_models = set(self.current_models)
  203. def tearDown(self):
  204. for model in (set(self.current_models) - self.saved_models):
  205. del self.current_models[model]
  206. apps.clear_cache()
  207. class CheckFrameworkReservedNamesTests(IsolateModelsMixin, SimpleTestCase):
  208. @override_settings(
  209. SILENCED_SYSTEM_CHECKS=['models.E20', 'fields.W342'], # ForeignKey(unique=True)
  210. INSTALLED_APPS=['django.contrib.auth', 'django.contrib.contenttypes', 'check_framework']
  211. )
  212. def test_model_check_method_not_shadowed(self):
  213. class ModelWithAttributeCalledCheck(models.Model):
  214. check = 42
  215. class ModelWithFieldCalledCheck(models.Model):
  216. check = models.IntegerField()
  217. class ModelWithRelatedManagerCalledCheck(models.Model):
  218. pass
  219. class ModelWithDescriptorCalledCheck(models.Model):
  220. check = models.ForeignKey(ModelWithRelatedManagerCalledCheck, models.CASCADE)
  221. article = models.ForeignKey(
  222. ModelWithRelatedManagerCalledCheck,
  223. models.CASCADE,
  224. related_name='check',
  225. )
  226. errors = checks.run_checks()
  227. expected = [
  228. Error(
  229. "The 'ModelWithAttributeCalledCheck.check()' class method is "
  230. "currently overridden by 42.",
  231. hint=None,
  232. obj=ModelWithAttributeCalledCheck,
  233. id='models.E020'
  234. ),
  235. Error(
  236. "The 'ModelWithRelatedManagerCalledCheck.check()' class method is "
  237. "currently overridden by %r." % ModelWithRelatedManagerCalledCheck.check,
  238. hint=None,
  239. obj=ModelWithRelatedManagerCalledCheck,
  240. id='models.E020'
  241. ),
  242. Error(
  243. "The 'ModelWithDescriptorCalledCheck.check()' class method is "
  244. "currently overridden by %r." % ModelWithDescriptorCalledCheck.check,
  245. hint=None,
  246. obj=ModelWithDescriptorCalledCheck,
  247. id='models.E020'
  248. ),
  249. ]
  250. self.assertEqual(errors, expected)