From fe0dafda921b604f6a01e405b4a07df8aa340b03 Mon Sep 17 00:00:00 2001 From: Rodolfo Carvalho Date: Mon, 27 Mar 2017 20:15:40 +0200 Subject: Make resolve_checks more strict So that all names it return are directly usable, without checking for existence. --- .../test/action_plugin_test.py | 74 ++++++++++++++++++++++ roles/openshift_health_checker/test/conftest.py | 9 ++- 2 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 roles/openshift_health_checker/test/action_plugin_test.py (limited to 'roles/openshift_health_checker/test') diff --git a/roles/openshift_health_checker/test/action_plugin_test.py b/roles/openshift_health_checker/test/action_plugin_test.py new file mode 100644 index 000000000..9667dc803 --- /dev/null +++ b/roles/openshift_health_checker/test/action_plugin_test.py @@ -0,0 +1,74 @@ +import pytest + +from openshift_health_check import resolve_checks + + +class FakeCheck(object): + def __init__(self, name, tags=None): + self.name = name + self.tags = tags or [] + + +@pytest.mark.parametrize('names,all_checks,expected', [ + ([], [], set()), + ( + ['a', 'b'], + [ + FakeCheck('a'), + FakeCheck('b'), + ], + set(['a', 'b']), + ), + ( + ['a', 'b', '@group'], + [ + FakeCheck('from_group_1', ['group', 'another_group']), + FakeCheck('not_in_group', ['another_group']), + FakeCheck('from_group_2', ['preflight', 'group']), + FakeCheck('a'), + FakeCheck('b'), + ], + set(['a', 'b', 'from_group_1', 'from_group_2']), + ), +]) +def test_resolve_checks_ok(names, all_checks, expected): + assert resolve_checks(names, all_checks) == expected + + +@pytest.mark.parametrize('names,all_checks,words_in_exception,words_not_in_exception', [ + ( + ['testA', 'testB'], + [], + ['check', 'name', 'testA', 'testB'], + ['tag', 'group', '@'], + ), + ( + ['@group'], + [], + ['tag', 'name', 'group'], + ['check', '@'], + ), + ( + ['testA', 'testB', '@group'], + [], + ['check', 'name', 'testA', 'testB', 'tag', 'group'], + ['@'], + ), + ( + ['testA', 'testB', '@group'], + [ + FakeCheck('from_group_1', ['group', 'another_group']), + FakeCheck('not_in_group', ['another_group']), + FakeCheck('from_group_2', ['preflight', 'group']), + ], + ['check', 'name', 'testA', 'testB'], + ['tag', 'group', '@'], + ), +]) +def test_resolve_checks_failure(names, all_checks, words_in_exception, words_not_in_exception): + with pytest.raises(Exception) as excinfo: + resolve_checks(names, all_checks) + for word in words_in_exception: + assert word in str(excinfo.value) + for word in words_not_in_exception: + assert word not in str(excinfo.value) diff --git a/roles/openshift_health_checker/test/conftest.py b/roles/openshift_health_checker/test/conftest.py index bf717ae85..d16401260 100644 --- a/roles/openshift_health_checker/test/conftest.py +++ b/roles/openshift_health_checker/test/conftest.py @@ -1,5 +1,10 @@ import os import sys -# extend sys.path so that tests can import openshift_checks -sys.path.insert(1, os.path.dirname(os.path.dirname(__file__))) +# extend sys.path so that tests can import openshift_checks and action plugins +# from this role. +openshift_health_checker_path = os.path.dirname(os.path.dirname(__file__)) +sys.path[1:1] = [ + openshift_health_checker_path, + os.path.join(openshift_health_checker_path, 'action_plugins') +] -- cgit v1.2.3 From cf4a978d230040bed9c2c203bfa0ca0c70d98d64 Mon Sep 17 00:00:00 2001 From: Rodolfo Carvalho Date: Tue, 4 Apr 2017 11:17:51 +0200 Subject: Add tests for action plugin --- .../test/action_plugin_test.py | 183 +++++++++++++++++++-- 1 file changed, 168 insertions(+), 15 deletions(-) (limited to 'roles/openshift_health_checker/test') diff --git a/roles/openshift_health_checker/test/action_plugin_test.py b/roles/openshift_health_checker/test/action_plugin_test.py index 9667dc803..a877246f4 100644 --- a/roles/openshift_health_checker/test/action_plugin_test.py +++ b/roles/openshift_health_checker/test/action_plugin_test.py @@ -1,12 +1,165 @@ import pytest -from openshift_health_check import resolve_checks +from openshift_health_check import ActionModule, resolve_checks +from openshift_checks import OpenShiftCheckException -class FakeCheck(object): - def __init__(self, name, tags=None): - self.name = name - self.tags = tags or [] +def fake_check(name='fake_check', tags=None, is_active=True, run_return=None, run_exception=None): + """Returns a new class that is compatible with OpenShiftCheck for testing.""" + + _name, _tags = name, tags + + class FakeCheck(object): + name = _name + tags = _tags or [] + + def __init__(self, execute_module=None): + pass + + @classmethod + def is_active(cls, task_vars): + return is_active + + def run(self, tmp, task_vars): + if run_exception is not None: + raise run_exception + return run_return + + return FakeCheck + + +# Fixtures + + +@pytest.fixture +def plugin(): + task = FakeTask('openshift_health_check', {'checks': ['fake_check']}) + plugin = ActionModule(task, None, None, None, None, None) + return plugin + + +class FakeTask(object): + def __init__(self, action, args): + self.action = action + self.args = args + self.async = 0 + + +@pytest.fixture +def task_vars(): + return dict(openshift=dict(), ansible_host='unit-test-host') + + +# Assertion helpers + + +def failed(result, msg_has=None): + if msg_has is not None: + assert 'msg' in result + for term in msg_has: + assert term in result['msg'] + return result.get('failed', False) + + +def changed(result): + return result.get('changed', False) + + +def skipped(result): + return result.get('skipped', False) + + +# Tests + + +@pytest.mark.parametrize('task_vars', [ + None, + {}, +]) +def test_action_plugin_missing_openshift_facts(plugin, task_vars): + result = plugin.run(tmp=None, task_vars=task_vars) + + assert failed(result, msg_has=['openshift_facts']) + + +def test_action_plugin_cannot_load_checks_with_the_same_name(plugin, task_vars, monkeypatch): + FakeCheck1 = fake_check('duplicate_name') + FakeCheck2 = fake_check('duplicate_name') + checks = [FakeCheck1, FakeCheck2] + monkeypatch.setattr('openshift_checks.OpenShiftCheck.subclasses', classmethod(lambda cls: checks)) + + result = plugin.run(tmp=None, task_vars=task_vars) + + assert failed(result, msg_has=['unique', 'duplicate_name', 'FakeCheck']) + + +def test_action_plugin_skip_non_active_checks(plugin, task_vars, monkeypatch): + checks = [fake_check(is_active=False)] + monkeypatch.setattr('openshift_checks.OpenShiftCheck.subclasses', classmethod(lambda cls: checks)) + + result = plugin.run(tmp=None, task_vars=task_vars) + + assert result['checks']['fake_check'] == {'skipped': True} + assert not failed(result) + assert not changed(result) + assert not skipped(result) + + +def test_action_plugin_run_check_ok(plugin, task_vars, monkeypatch): + check_return_value = {'ok': 'test'} + check_class = fake_check(run_return=check_return_value) + monkeypatch.setattr(plugin, 'load_known_checks', lambda: {'fake_check': check_class()}) + monkeypatch.setattr('openshift_health_check.resolve_checks', lambda *args: ['fake_check']) + + result = plugin.run(tmp=None, task_vars=task_vars) + + assert result['checks']['fake_check'] == check_return_value + assert not failed(result) + assert not changed(result) + assert not skipped(result) + + +def test_action_plugin_run_check_changed(plugin, task_vars, monkeypatch): + check_return_value = {'ok': 'test', 'changed': True} + check_class = fake_check(run_return=check_return_value) + monkeypatch.setattr(plugin, 'load_known_checks', lambda: {'fake_check': check_class()}) + monkeypatch.setattr('openshift_health_check.resolve_checks', lambda *args: ['fake_check']) + + result = plugin.run(tmp=None, task_vars=task_vars) + + assert result['checks']['fake_check'] == check_return_value + assert not failed(result) + assert changed(result) + assert not skipped(result) + + +def test_action_plugin_run_check_fail(plugin, task_vars, monkeypatch): + check_return_value = {'failed': True} + check_class = fake_check(run_return=check_return_value) + monkeypatch.setattr(plugin, 'load_known_checks', lambda: {'fake_check': check_class()}) + monkeypatch.setattr('openshift_health_check.resolve_checks', lambda *args: ['fake_check']) + + result = plugin.run(tmp=None, task_vars=task_vars) + + assert result['checks']['fake_check'] == check_return_value + assert failed(result, msg_has=['failed']) + assert not changed(result) + assert not skipped(result) + + +def test_action_plugin_run_check_exception(plugin, task_vars, monkeypatch): + exception_msg = 'fake check has an exception' + run_exception = OpenShiftCheckException(exception_msg) + check_class = fake_check(run_exception=run_exception) + monkeypatch.setattr(plugin, 'load_known_checks', lambda: {'fake_check': check_class()}) + monkeypatch.setattr('openshift_health_check.resolve_checks', lambda *args: ['fake_check']) + + result = plugin.run(tmp=None, task_vars=task_vars) + + assert failed(result['checks']['fake_check'], msg_has=exception_msg) + assert failed(result, msg_has=['failed']) + assert not changed(result) + assert not skipped(result) @pytest.mark.parametrize('names,all_checks,expected', [ @@ -14,19 +167,19 @@ class FakeCheck(object): ( ['a', 'b'], [ - FakeCheck('a'), - FakeCheck('b'), + fake_check('a'), + fake_check('b'), ], set(['a', 'b']), ), ( ['a', 'b', '@group'], [ - FakeCheck('from_group_1', ['group', 'another_group']), - FakeCheck('not_in_group', ['another_group']), - FakeCheck('from_group_2', ['preflight', 'group']), - FakeCheck('a'), - FakeCheck('b'), + fake_check('from_group_1', ['group', 'another_group']), + fake_check('not_in_group', ['another_group']), + fake_check('from_group_2', ['preflight', 'group']), + fake_check('a'), + fake_check('b'), ], set(['a', 'b', 'from_group_1', 'from_group_2']), ), @@ -57,9 +210,9 @@ def test_resolve_checks_ok(names, all_checks, expected): ( ['testA', 'testB', '@group'], [ - FakeCheck('from_group_1', ['group', 'another_group']), - FakeCheck('not_in_group', ['another_group']), - FakeCheck('from_group_2', ['preflight', 'group']), + fake_check('from_group_1', ['group', 'another_group']), + fake_check('not_in_group', ['another_group']), + fake_check('from_group_2', ['preflight', 'group']), ], ['check', 'name', 'testA', 'testB'], ['tag', 'group', '@'], -- cgit v1.2.3