From 21fa385ce72d337434e462e33b4b9dcaecceda52 Mon Sep 17 00:00:00 2001 From: James Cammarata Date: Mon, 18 May 2015 17:26:59 -0700 Subject: [PATCH] Reorganizing plugin unit tests and adding start of strategy tests (v2) --- lib/ansible/plugins/strategies/__init__.py | 7 +- test/units/plugins/action/__init__.py | 21 +++ test/units/plugins/cache/__init__.py | 21 +++ test/units/plugins/{ => cache}/test_cache.py | 0 test/units/plugins/callback/__init__.py | 21 +++ test/units/plugins/connections/__init__.py | 21 +++ .../{ => connections}/test_connection.py | 0 test/units/plugins/filter/__init__.py | 21 +++ test/units/plugins/inventory/__init__.py | 21 +++ test/units/plugins/lookup/__init__.py | 21 +++ test/units/plugins/shell/__init__.py | 21 +++ test/units/plugins/strategies/__init__.py | 21 +++ .../plugins/strategies/test_strategy_base.py | 127 ++++++++++++++++++ test/units/plugins/vars/__init__.py | 21 +++ 14 files changed, 339 insertions(+), 5 deletions(-) create mode 100644 test/units/plugins/action/__init__.py create mode 100644 test/units/plugins/cache/__init__.py rename test/units/plugins/{ => cache}/test_cache.py (100%) create mode 100644 test/units/plugins/callback/__init__.py create mode 100644 test/units/plugins/connections/__init__.py rename test/units/plugins/{ => connections}/test_connection.py (100%) create mode 100644 test/units/plugins/filter/__init__.py create mode 100644 test/units/plugins/inventory/__init__.py create mode 100644 test/units/plugins/lookup/__init__.py create mode 100644 test/units/plugins/shell/__init__.py create mode 100644 test/units/plugins/strategies/__init__.py create mode 100644 test/units/plugins/strategies/test_strategy_base.py create mode 100644 test/units/plugins/vars/__init__.py diff --git a/lib/ansible/plugins/strategies/__init__.py b/lib/ansible/plugins/strategies/__init__.py index a3668ba089..7cc1709e08 100644 --- a/lib/ansible/plugins/strategies/__init__.py +++ b/lib/ansible/plugins/strategies/__init__.py @@ -61,7 +61,6 @@ class StrategyBase: self._inventory = tqm.get_inventory() self._workers = tqm.get_workers() self._notified_handlers = tqm.get_notified_handlers() - #self._callback = tqm.get_callback() self._variable_manager = tqm.get_variable_manager() self._loader = tqm.get_loader() self._final_q = tqm._final_q @@ -80,8 +79,6 @@ class StrategyBase: num_failed = len(self._tqm._failed_hosts) num_unreachable = len(self._tqm._unreachable_hosts) - #debug("running the cleanup portion of the play") - #result &= self.cleanup(iterator, connection_info) debug("running handlers") result &= self.run_handlers(iterator, connection_info) @@ -99,6 +96,7 @@ class StrategyBase: return 0 def get_hosts_remaining(self, play): + print("inventory get hosts: %s" % self._inventory.get_hosts(play.hosts)) return [host for host in self._inventory.get_hosts(play.hosts) if host.name not in self._tqm._failed_hosts and host.name not in self._tqm._unreachable_hosts] def get_failed_hosts(self, play): @@ -119,13 +117,12 @@ class StrategyBase: if self._cur_worker >= len(self._workers): self._cur_worker = 0 - self._pending_results += 1 - # create a dummy object with plugin loaders set as an easier # way to share them with the forked processes shared_loader_obj = SharedPluginLoaderObj() main_q.put((host, task, self._loader.get_basedir(), task_vars, connection_info, shared_loader_obj), block=False) + self._pending_results += 1 except (EOFError, IOError, AssertionError) as e: # most likely an abort debug("got an error while queuing: %s" % e) diff --git a/test/units/plugins/action/__init__.py b/test/units/plugins/action/__init__.py new file mode 100644 index 0000000000..785fc45992 --- /dev/null +++ b/test/units/plugins/action/__init__.py @@ -0,0 +1,21 @@ +# (c) 2012-2014, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + diff --git a/test/units/plugins/cache/__init__.py b/test/units/plugins/cache/__init__.py new file mode 100644 index 0000000000..785fc45992 --- /dev/null +++ b/test/units/plugins/cache/__init__.py @@ -0,0 +1,21 @@ +# (c) 2012-2014, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + diff --git a/test/units/plugins/test_cache.py b/test/units/plugins/cache/test_cache.py similarity index 100% rename from test/units/plugins/test_cache.py rename to test/units/plugins/cache/test_cache.py diff --git a/test/units/plugins/callback/__init__.py b/test/units/plugins/callback/__init__.py new file mode 100644 index 0000000000..785fc45992 --- /dev/null +++ b/test/units/plugins/callback/__init__.py @@ -0,0 +1,21 @@ +# (c) 2012-2014, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + diff --git a/test/units/plugins/connections/__init__.py b/test/units/plugins/connections/__init__.py new file mode 100644 index 0000000000..785fc45992 --- /dev/null +++ b/test/units/plugins/connections/__init__.py @@ -0,0 +1,21 @@ +# (c) 2012-2014, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + diff --git a/test/units/plugins/test_connection.py b/test/units/plugins/connections/test_connection.py similarity index 100% rename from test/units/plugins/test_connection.py rename to test/units/plugins/connections/test_connection.py diff --git a/test/units/plugins/filter/__init__.py b/test/units/plugins/filter/__init__.py new file mode 100644 index 0000000000..785fc45992 --- /dev/null +++ b/test/units/plugins/filter/__init__.py @@ -0,0 +1,21 @@ +# (c) 2012-2014, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + diff --git a/test/units/plugins/inventory/__init__.py b/test/units/plugins/inventory/__init__.py new file mode 100644 index 0000000000..785fc45992 --- /dev/null +++ b/test/units/plugins/inventory/__init__.py @@ -0,0 +1,21 @@ +# (c) 2012-2014, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + diff --git a/test/units/plugins/lookup/__init__.py b/test/units/plugins/lookup/__init__.py new file mode 100644 index 0000000000..785fc45992 --- /dev/null +++ b/test/units/plugins/lookup/__init__.py @@ -0,0 +1,21 @@ +# (c) 2012-2014, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + diff --git a/test/units/plugins/shell/__init__.py b/test/units/plugins/shell/__init__.py new file mode 100644 index 0000000000..785fc45992 --- /dev/null +++ b/test/units/plugins/shell/__init__.py @@ -0,0 +1,21 @@ +# (c) 2012-2014, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + diff --git a/test/units/plugins/strategies/__init__.py b/test/units/plugins/strategies/__init__.py new file mode 100644 index 0000000000..785fc45992 --- /dev/null +++ b/test/units/plugins/strategies/__init__.py @@ -0,0 +1,21 @@ +# (c) 2012-2014, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + diff --git a/test/units/plugins/strategies/test_strategy_base.py b/test/units/plugins/strategies/test_strategy_base.py new file mode 100644 index 0000000000..36e22a9719 --- /dev/null +++ b/test/units/plugins/strategies/test_strategy_base.py @@ -0,0 +1,127 @@ +# (c) 2012-2014, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.compat.tests import unittest +from ansible.compat.tests.mock import patch, MagicMock + +from ansible.plugins.strategies import StrategyBase +from ansible.executor.task_queue_manager import TaskQueueManager + +from units.mock.loader import DictDataLoader + +class TestVariableManager(unittest.TestCase): + + def setUp(self): + pass + + def tearDown(self): + pass + + def test_strategy_base_init(self): + mock_tqm = MagicMock(TaskQueueManager) + mock_tqm._final_q = MagicMock() + strategy_base = StrategyBase(tqm=mock_tqm) + + def test_strategy_base_run(self): + mock_tqm = MagicMock(TaskQueueManager) + mock_tqm._final_q = MagicMock() + mock_tqm._stats = MagicMock() + mock_tqm.send_callback.return_value = None + + mock_iterator = MagicMock() + mock_iterator._play = MagicMock() + mock_iterator._play.handlers = [] + + mock_conn_info = MagicMock() + + mock_tqm._failed_hosts = [] + mock_tqm._unreachable_hosts = [] + strategy_base = StrategyBase(tqm=mock_tqm) + + self.assertEqual(strategy_base.run(iterator=mock_iterator, connection_info=mock_conn_info), 0) + self.assertEqual(strategy_base.run(iterator=mock_iterator, connection_info=mock_conn_info, result=False), 1) + mock_tqm._failed_hosts = ["host1"] + self.assertEqual(strategy_base.run(iterator=mock_iterator, connection_info=mock_conn_info, result=False), 2) + mock_tqm._unreachable_hosts = ["host1"] + self.assertEqual(strategy_base.run(iterator=mock_iterator, connection_info=mock_conn_info, result=False), 3) + + def test_strategy_base_get_hosts(self): + mock_hosts = [] + for i in range(0, 5): + mock_host = MagicMock() + mock_host.name = "host%02d" % (i+1) + mock_hosts.append(mock_host) + + mock_inventory = MagicMock() + mock_inventory.get_hosts.return_value = mock_hosts + + mock_tqm = MagicMock() + mock_tqm._final_q = MagicMock() + mock_tqm.get_inventory.return_value = mock_inventory + + mock_play = MagicMock() + mock_play.hosts = ["host%02d" % (i+1) for i in range(0, 5)] + + strategy_base = StrategyBase(tqm=mock_tqm) + + mock_tqm._failed_hosts = [] + mock_tqm._unreachable_hosts = [] + self.assertEqual(strategy_base.get_hosts_remaining(play=mock_play), mock_hosts) + + mock_tqm._failed_hosts = ["host01"] + self.assertEqual(strategy_base.get_hosts_remaining(play=mock_play), mock_hosts[1:]) + self.assertEqual(strategy_base.get_failed_hosts(play=mock_play), [mock_hosts[0]]) + + mock_tqm._unreachable_hosts = ["host02"] + self.assertEqual(strategy_base.get_hosts_remaining(play=mock_play), mock_hosts[2:]) + + def test_strategy_base_queue_task(self): + fake_loader = DictDataLoader() + + workers = [] + for i in range(0, 3): + worker_main_q = MagicMock() + worker_main_q.put.return_value = None + worker_result_q = MagicMock() + workers.append([i, worker_main_q, worker_result_q]) + + mock_tqm = MagicMock() + mock_tqm._final_q = MagicMock() + mock_tqm.get_workers.return_value = workers + mock_tqm.get_loader.return_value = fake_loader + + strategy_base = StrategyBase(tqm=mock_tqm) + strategy_base._cur_worker = 0 + strategy_base._pending_results = 0 + strategy_base._queue_task(host=MagicMock(), task=MagicMock(), task_vars=dict(), connection_info=MagicMock()) + self.assertEqual(strategy_base._cur_worker, 1) + self.assertEqual(strategy_base._pending_results, 1) + strategy_base._queue_task(host=MagicMock(), task=MagicMock(), task_vars=dict(), connection_info=MagicMock()) + self.assertEqual(strategy_base._cur_worker, 2) + self.assertEqual(strategy_base._pending_results, 2) + strategy_base._queue_task(host=MagicMock(), task=MagicMock(), task_vars=dict(), connection_info=MagicMock()) + self.assertEqual(strategy_base._cur_worker, 0) + self.assertEqual(strategy_base._pending_results, 3) + workers[0][1].put.side_effect = EOFError + strategy_base._queue_task(host=MagicMock(), task=MagicMock(), task_vars=dict(), connection_info=MagicMock()) + self.assertEqual(strategy_base._cur_worker, 1) + self.assertEqual(strategy_base._pending_results, 3) + diff --git a/test/units/plugins/vars/__init__.py b/test/units/plugins/vars/__init__.py new file mode 100644 index 0000000000..785fc45992 --- /dev/null +++ b/test/units/plugins/vars/__init__.py @@ -0,0 +1,21 @@ +# (c) 2012-2014, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +