Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_common.py 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. from __future__ import absolute_import
  2. import os
  3. import signal
  4. import sys
  5. from contextlib import contextmanager
  6. from time import time
  7. from nose import SkipTest
  8. from billiard.common import (
  9. _shutdown_cleanup,
  10. reset_signals,
  11. restart_state,
  12. )
  13. from .utils import Case
  14. try:
  15. from unittest.mock import Mock, call, patch
  16. except ImportError:
  17. from mock import Mock, call, patch # noqa
  18. def signo(name):
  19. return getattr(signal, name)
  20. @contextmanager
  21. def termsigs(default, full):
  22. from billiard import common
  23. prev_def, common.TERMSIGS_DEFAULT = common.TERMSIGS_DEFAULT, default
  24. prev_full, common.TERMSIGS_FULL = common.TERMSIGS_FULL, full
  25. try:
  26. yield
  27. finally:
  28. common.TERMSIGS_DEFAULT, common.TERMSIGS_FULL = prev_def, prev_full
  29. class test_reset_signals(Case):
  30. def setUp(self):
  31. if sys.platform == 'win32':
  32. raise SkipTest('win32: skip')
  33. def test_shutdown_handler(self):
  34. with patch('sys.exit') as exit:
  35. _shutdown_cleanup(15, Mock())
  36. self.assertTrue(exit.called)
  37. self.assertEqual(os.WTERMSIG(exit.call_args[0][0]), 15)
  38. def test_does_not_reset_ignored_signal(self, sigs=['SIGTERM']):
  39. with self.assert_context(sigs, [], signal.SIG_IGN) as (_, SET):
  40. self.assertFalse(SET.called)
  41. def test_does_not_reset_if_current_is_None(self, sigs=['SIGTERM']):
  42. with self.assert_context(sigs, [], None) as (_, SET):
  43. self.assertFalse(SET.called)
  44. def test_resets_for_SIG_DFL(self, sigs=['SIGTERM', 'SIGINT', 'SIGUSR1']):
  45. with self.assert_context(sigs, [], signal.SIG_DFL) as (_, SET):
  46. SET.assert_has_calls([
  47. call(signo(sig), _shutdown_cleanup) for sig in sigs
  48. ])
  49. def test_resets_for_obj(self, sigs=['SIGTERM', 'SIGINT', 'SIGUSR1']):
  50. with self.assert_context(sigs, [], object()) as (_, SET):
  51. SET.assert_has_calls([
  52. call(signo(sig), _shutdown_cleanup) for sig in sigs
  53. ])
  54. def test_handles_errors(self, sigs=['SIGTERM']):
  55. for exc in (OSError(), AttributeError(),
  56. ValueError(), RuntimeError()):
  57. with self.assert_context(sigs, [], signal.SIG_DFL, exc) as (_, S):
  58. self.assertTrue(S.called)
  59. @contextmanager
  60. def assert_context(self, default, full, get_returns=None, set_effect=None):
  61. with termsigs(default, full):
  62. with patch('signal.getsignal') as GET:
  63. with patch('signal.signal') as SET:
  64. GET.return_value = get_returns
  65. SET.side_effect = set_effect
  66. reset_signals()
  67. GET.assert_has_calls([
  68. call(signo(sig)) for sig in default
  69. ])
  70. yield GET, SET
  71. class test_restart_state(Case):
  72. def test_raises(self):
  73. s = restart_state(100, 1) # max 100 restarts in 1 second.
  74. s.R = 99
  75. s.step()
  76. with self.assertRaises(s.RestartFreqExceeded):
  77. s.step()
  78. def test_time_passed_resets_counter(self):
  79. s = restart_state(100, 10)
  80. s.R, s.T = 100, time()
  81. with self.assertRaises(s.RestartFreqExceeded):
  82. s.step()
  83. s.R, s.T = 100, time()
  84. s.step(time() + 20)
  85. self.assertEqual(s.R, 1)