action_plugin_test.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import pytest
  2. from ansible.playbook.play_context import PlayContext
  3. from openshift_health_check import ActionModule, resolve_checks
  4. from openshift_checks import OpenShiftCheckException
  5. def fake_check(name='fake_check', tags=None, is_active=True, run_return=None, run_exception=None):
  6. """Returns a new class that is compatible with OpenShiftCheck for testing."""
  7. _name, _tags = name, tags
  8. class FakeCheck(object):
  9. name = _name
  10. tags = _tags or []
  11. def __init__(self, execute_module=None, task_vars=None, tmp=None):
  12. pass
  13. def is_active(self):
  14. return is_active
  15. def run(self):
  16. if run_exception is not None:
  17. raise run_exception
  18. return run_return
  19. return FakeCheck
  20. # Fixtures
  21. @pytest.fixture
  22. def plugin():
  23. task = FakeTask('openshift_health_check', {'checks': ['fake_check']})
  24. plugin = ActionModule(task, None, PlayContext(), None, None, None)
  25. return plugin
  26. class FakeTask(object):
  27. def __init__(self, action, args):
  28. self.action = action
  29. self.args = args
  30. self.async = 0
  31. @pytest.fixture
  32. def task_vars():
  33. return dict(openshift=dict(), ansible_host='unit-test-host')
  34. # Assertion helpers
  35. def failed(result, msg_has=None):
  36. if msg_has is not None:
  37. assert 'msg' in result
  38. for term in msg_has:
  39. assert term.lower() in result['msg'].lower()
  40. return result.get('failed', False)
  41. def changed(result):
  42. return result.get('changed', False)
  43. # tests whether task is skipped, not individual checks
  44. def skipped(result):
  45. return result.get('skipped', False)
  46. # Tests
  47. @pytest.mark.parametrize('task_vars', [
  48. None,
  49. {},
  50. ])
  51. def test_action_plugin_missing_openshift_facts(plugin, task_vars):
  52. result = plugin.run(tmp=None, task_vars=task_vars)
  53. assert failed(result, msg_has=['openshift_facts'])
  54. def test_action_plugin_cannot_load_checks_with_the_same_name(plugin, task_vars, monkeypatch):
  55. FakeCheck1 = fake_check('duplicate_name')
  56. FakeCheck2 = fake_check('duplicate_name')
  57. checks = [FakeCheck1, FakeCheck2]
  58. monkeypatch.setattr('openshift_checks.OpenShiftCheck.subclasses', classmethod(lambda cls: checks))
  59. result = plugin.run(tmp=None, task_vars=task_vars)
  60. assert failed(result, msg_has=['unique', 'duplicate_name', 'FakeCheck'])
  61. def test_action_plugin_skip_non_active_checks(plugin, task_vars, monkeypatch):
  62. checks = [fake_check(is_active=False)]
  63. monkeypatch.setattr('openshift_checks.OpenShiftCheck.subclasses', classmethod(lambda cls: checks))
  64. result = plugin.run(tmp=None, task_vars=task_vars)
  65. assert result['checks']['fake_check'] == dict(skipped=True, skipped_reason="Not active for this host")
  66. assert not failed(result)
  67. assert not changed(result)
  68. assert not skipped(result)
  69. def test_action_plugin_skip_disabled_checks(plugin, task_vars, monkeypatch):
  70. checks = [fake_check('fake_check', is_active=True)]
  71. monkeypatch.setattr('openshift_checks.OpenShiftCheck.subclasses', classmethod(lambda cls: checks))
  72. task_vars['openshift_disable_check'] = 'fake_check'
  73. result = plugin.run(tmp=None, task_vars=task_vars)
  74. assert result['checks']['fake_check'] == dict(skipped=True, skipped_reason="Disabled by user request")
  75. assert not failed(result)
  76. assert not changed(result)
  77. assert not skipped(result)
  78. def test_action_plugin_run_check_ok(plugin, task_vars, monkeypatch):
  79. check_return_value = {'ok': 'test'}
  80. check_class = fake_check(run_return=check_return_value)
  81. monkeypatch.setattr(plugin, 'load_known_checks', lambda tmp, task_vars: {'fake_check': check_class()})
  82. monkeypatch.setattr('openshift_health_check.resolve_checks', lambda *args: ['fake_check'])
  83. result = plugin.run(tmp=None, task_vars=task_vars)
  84. assert result['checks']['fake_check'] == check_return_value
  85. assert not failed(result)
  86. assert not changed(result)
  87. assert not skipped(result)
  88. def test_action_plugin_run_check_changed(plugin, task_vars, monkeypatch):
  89. check_return_value = {'ok': 'test', 'changed': True}
  90. check_class = fake_check(run_return=check_return_value)
  91. monkeypatch.setattr(plugin, 'load_known_checks', lambda tmp, task_vars: {'fake_check': check_class()})
  92. monkeypatch.setattr('openshift_health_check.resolve_checks', lambda *args: ['fake_check'])
  93. result = plugin.run(tmp=None, task_vars=task_vars)
  94. assert result['checks']['fake_check'] == check_return_value
  95. assert not failed(result)
  96. assert changed(result)
  97. assert not skipped(result)
  98. def test_action_plugin_run_check_fail(plugin, task_vars, monkeypatch):
  99. check_return_value = {'failed': True}
  100. check_class = fake_check(run_return=check_return_value)
  101. monkeypatch.setattr(plugin, 'load_known_checks', lambda tmp, task_vars: {'fake_check': check_class()})
  102. monkeypatch.setattr('openshift_health_check.resolve_checks', lambda *args: ['fake_check'])
  103. result = plugin.run(tmp=None, task_vars=task_vars)
  104. assert result['checks']['fake_check'] == check_return_value
  105. assert failed(result, msg_has=['failed'])
  106. assert not changed(result)
  107. assert not skipped(result)
  108. def test_action_plugin_run_check_exception(plugin, task_vars, monkeypatch):
  109. exception_msg = 'fake check has an exception'
  110. run_exception = OpenShiftCheckException(exception_msg)
  111. check_class = fake_check(run_exception=run_exception)
  112. monkeypatch.setattr(plugin, 'load_known_checks', lambda tmp, task_vars: {'fake_check': check_class()})
  113. monkeypatch.setattr('openshift_health_check.resolve_checks', lambda *args: ['fake_check'])
  114. result = plugin.run(tmp=None, task_vars=task_vars)
  115. assert failed(result['checks']['fake_check'], msg_has=exception_msg)
  116. assert failed(result, msg_has=['failed'])
  117. assert not changed(result)
  118. assert not skipped(result)
  119. def test_action_plugin_resolve_checks_exception(plugin, task_vars, monkeypatch):
  120. monkeypatch.setattr(plugin, 'load_known_checks', lambda tmp, task_vars: {})
  121. result = plugin.run(tmp=None, task_vars=task_vars)
  122. assert failed(result, msg_has=['unknown', 'name'])
  123. assert not changed(result)
  124. assert not skipped(result)
  125. @pytest.mark.parametrize('names,all_checks,expected', [
  126. ([], [], set()),
  127. (
  128. ['a', 'b'],
  129. [
  130. fake_check('a'),
  131. fake_check('b'),
  132. ],
  133. set(['a', 'b']),
  134. ),
  135. (
  136. ['a', 'b', '@group'],
  137. [
  138. fake_check('from_group_1', ['group', 'another_group']),
  139. fake_check('not_in_group', ['another_group']),
  140. fake_check('from_group_2', ['preflight', 'group']),
  141. fake_check('a'),
  142. fake_check('b'),
  143. ],
  144. set(['a', 'b', 'from_group_1', 'from_group_2']),
  145. ),
  146. ])
  147. def test_resolve_checks_ok(names, all_checks, expected):
  148. assert resolve_checks(names, all_checks) == expected
  149. @pytest.mark.parametrize('names,all_checks,words_in_exception,words_not_in_exception', [
  150. (
  151. ['testA', 'testB'],
  152. [],
  153. ['check', 'name', 'testA', 'testB'],
  154. ['tag', 'group', '@'],
  155. ),
  156. (
  157. ['@group'],
  158. [],
  159. ['tag', 'name', 'group'],
  160. ['check', '@'],
  161. ),
  162. (
  163. ['testA', 'testB', '@group'],
  164. [],
  165. ['check', 'name', 'testA', 'testB', 'tag', 'group'],
  166. ['@'],
  167. ),
  168. (
  169. ['testA', 'testB', '@group'],
  170. [
  171. fake_check('from_group_1', ['group', 'another_group']),
  172. fake_check('not_in_group', ['another_group']),
  173. fake_check('from_group_2', ['preflight', 'group']),
  174. ],
  175. ['check', 'name', 'testA', 'testB'],
  176. ['tag', 'group', '@'],
  177. ),
  178. ])
  179. def test_resolve_checks_failure(names, all_checks, words_in_exception, words_not_in_exception):
  180. with pytest.raises(Exception) as excinfo:
  181. resolve_checks(names, all_checks)
  182. for word in words_in_exception:
  183. assert word in str(excinfo.value)
  184. for word in words_not_in_exception:
  185. assert word not in str(excinfo.value)