def test_process_include_diff_files(mock_iterator, mock_variable_manager): hostname = "testhost1" hostname2 = "testhost2" parent_task_ds = {'debug': 'msg=foo'} parent_task = Task.load(parent_task_ds) parent_task._play = None task_ds = {'include': 'include_test.yml'} loaded_task = TaskInclude.load(task_ds, task_include=parent_task) loaded_task._play = None child_task_ds = {'include': 'other_include_test.yml'} loaded_child_task = TaskInclude.load(child_task_ds, task_include=loaded_task) loaded_child_task._play = None return_data = {'include': 'include_test.yml'} # The task in the TaskResult has to be a TaskInclude so it has a .static attr result1 = task_result.TaskResult(host=hostname, task=loaded_task, return_data=return_data) return_data = {'include': 'other_include_test.yml'} result2 = task_result.TaskResult(host=hostname2, task=loaded_child_task, return_data=return_data) results = [result1, result2] fake_loader = DictDataLoader({'include_test.yml': "", 'other_include_test.yml': ""}) res = IncludedFile.process_include_results(results, mock_iterator, fake_loader, mock_variable_manager) assert isinstance(res, list) assert res[0]._filename == os.path.join(os.getcwd(), 'include_test.yml') assert res[1]._filename == os.path.join(os.getcwd(), 'other_include_test.yml') assert res[0]._hosts == ['testhost1'] assert res[1]._hosts == ['testhost2'] assert res[0]._args == {} assert res[1]._args == {} assert res[0]._vars == {} assert res[1]._vars == {}
def test_task_executor_get_handler_prefix(self): te = TaskExecutor( host=MagicMock(), task=MagicMock(), job_vars={}, play_context=MagicMock(), new_stdin=None, loader=DictDataLoader({}), shared_loader_obj=MagicMock(), final_q=MagicMock(), ) action_loader = te._shared_loader_obj.action_loader action_loader.has_plugin.side_effect = [False, True] action_loader.get.return_value = mock.sentinel.handler action_loader.__contains__.return_value = True mock_connection = MagicMock() mock_templar = MagicMock() action = 'namespace.netconf_sufix' module_prefix = action.split('.')[-1].split('_')[0] te._task.action = action handler = te._get_action_handler(mock_connection, mock_templar) self.assertIs(mock.sentinel.handler, handler) action_loader.has_plugin.assert_has_calls([ mock.call(action, collection_list=te._task.collections), mock.call(module_prefix, collection_list=te._task.collections) ]) action_loader.get.assert_called_once_with( 'netconf', task=te._task, connection=mock_connection, play_context=te._play_context, loader=te._loader, templar=mock_templar, shared_loader_obj=te._shared_loader_obj, collection_list=te._task.collections)
def test_task_executor_run_loop(self): items = ['a', 'b', 'c'] fake_loader = DictDataLoader({}) mock_host = MagicMock() def _copy(exclude_parent=False, exclude_tasks=False): new_item = MagicMock() return new_item mock_task = MagicMock() mock_task.copy.side_effect = _copy mock_play_context = MagicMock() mock_shared_loader = MagicMock() mock_queue = MagicMock() new_stdin = None job_vars = dict() te = TaskExecutor( host=mock_host, task=mock_task, job_vars=job_vars, play_context=mock_play_context, new_stdin=new_stdin, loader=fake_loader, shared_loader_obj=mock_shared_loader, final_q=mock_queue, ) def _execute(variables): return dict(item=variables.get('item')) te._execute = MagicMock(side_effect=_execute) res = te._run_loop(items) self.assertEqual(len(res), 3)
def test_strategy_base_load_included_file(self): fake_loader = DictDataLoader({ "test.yml": """ - debug: msg='foo' """, "bad.yml": """ """, }) mock_tqm = MagicMock() mock_tqm._final_q = MagicMock() strategy_base = StrategyBase(tqm=mock_tqm) strategy_base._loader = fake_loader mock_play = MagicMock() mock_block = MagicMock() mock_block._play = mock_play mock_block.vars = dict() mock_task = MagicMock() mock_task._block = mock_block mock_task._role = None mock_iterator = MagicMock() mock_iterator.mark_host_failed.return_value = None mock_inc_file = MagicMock() mock_inc_file._task = mock_task mock_inc_file._filename = "test.yml" res = strategy_base._load_included_file(included_file=mock_inc_file, iterator=mock_iterator) mock_inc_file._filename = "bad.yml" self.assertRaises(AnsibleParserError, strategy_base._load_included_file, included_file=mock_inc_file, iterator=mock_iterator)
def test_task_executor_squash_items(self): items = ['a', 'b', 'c'] fake_loader = DictDataLoader({}) mock_host = MagicMock() def _evaluate_conditional(templar, variables): item = variables.get('item') if item == 'b': return False return True mock_task = MagicMock() mock_task.evaluate_conditional.side_effect = _evaluate_conditional mock_play_context = MagicMock() mock_shared_loader = None new_stdin = None job_vars = dict() te = TaskExecutor( host=mock_host, task=mock_task, job_vars=job_vars, play_context=mock_play_context, new_stdin=new_stdin, loader=fake_loader, shared_loader_obj=mock_shared_loader, ) mock_task.action = 'foo' new_items = te._squash_items(items=items, variables=job_vars) self.assertEqual(new_items, ['a', 'b', 'c']) mock_task.action = 'yum' new_items = te._squash_items(items=items, variables=job_vars) self.assertEqual(new_items, ['a,c'])
def test_strategy_base_queue_task(self, mock_worker): def fake_run(self): return mock_worker.run.side_effect = fake_run fake_loader = DictDataLoader() mock_var_manager = MagicMock() mock_host = MagicMock() mock_host.get_vars.return_value = dict() mock_host.has_hostkey = True mock_inventory = MagicMock() mock_inventory.get.return_value = mock_host tqm = TaskQueueManager( inventory=mock_inventory, variable_manager=mock_var_manager, loader=fake_loader, passwords=None, forks=5, ) tqm._initialize_processes(3) tqm.hostvars = dict() mock_task = MagicMock() mock_task._uuid = 'abcd' try: strategy_base = StrategyBase(tqm=tqm) strategy_base._queue_task(host=mock_host, task=mock_task, task_vars=dict(), play_context=MagicMock()) self.assertEqual(strategy_base._cur_worker, 1) self.assertEqual(strategy_base._pending_results, 1) strategy_base._queue_task(host=mock_host, task=mock_task, task_vars=dict(), play_context=MagicMock()) self.assertEqual(strategy_base._cur_worker, 2) self.assertEqual(strategy_base._pending_results, 2) strategy_base._queue_task(host=mock_host, task=mock_task, task_vars=dict(), play_context=MagicMock()) self.assertEqual(strategy_base._cur_worker, 0) self.assertEqual(strategy_base._pending_results, 3) finally: tqm.cleanup()
def test_task_executor_run(self): fake_loader = DictDataLoader({}) mock_host = MagicMock() mock_task = MagicMock() mock_task._role._role_path = '/path/to/role/foo' mock_conn_info = MagicMock() mock_shared_loader = MagicMock() new_stdin = None job_vars = dict() te = TaskExecutor( host = mock_host, task = mock_task, job_vars = job_vars, connection_info = mock_conn_info, new_stdin = new_stdin, loader = fake_loader, shared_loader_obj = mock_shared_loader, ) te._get_loop_items = MagicMock(return_value=None) te._execute = MagicMock(return_value=dict()) res = te.run() te._get_loop_items = MagicMock(return_value=[]) res = te.run() te._get_loop_items = MagicMock(return_value=['a','b','c']) te._run_loop = MagicMock(return_value=[dict(item='a', changed=True), dict(item='b', failed=True), dict(item='c')]) res = te.run() te._get_loop_items = MagicMock(side_effect=AnsibleError("")) res = te.run() self.assertIn("failed", res)
def test_task_executor_run_loop(self): items = ['a', 'b', 'c'] fake_loader = DictDataLoader({}) mock_host = MagicMock() def _copy(): new_item = MagicMock() return new_item mock_task = MagicMock() mock_task.copy.side_effect = _copy mock_conn_info = MagicMock() mock_shared_loader = MagicMock() new_stdin = None job_vars = dict() te = TaskExecutor( host = mock_host, task = mock_task, job_vars = job_vars, connection_info = mock_conn_info, new_stdin = new_stdin, loader = fake_loader, shared_loader_obj = mock_shared_loader, ) def _execute(variables): return dict(item=variables.get('item')) te._squash_items = MagicMock(return_value=items) te._execute = MagicMock(side_effect=_execute) res = te._run_loop(items) self.assertEqual(len(res), 3)
def test_load_role_with_vars_nested_dirs_combined(self): fake_loader = DictDataLoader({ "/etc/ansible/roles/foo_vars/defaults/main/foo/bar.yml": """ foo: bar a: 1 """, "/etc/ansible/roles/foo_vars/defaults/main/bar/foo.yml": """ foo: bam b: 2 """, }) mock_play = MagicMock() mock_play.ROLE_CACHE = {} i = RoleInclude.load('foo_vars', play=mock_play, loader=fake_loader) r = Role.load(i, play=mock_play) self.assertEqual(r._default_vars, dict(foo='bar', a=1, b=2))
def setUp(self): self.test_vars = dict( foo="bar", bam="{{foo}}", num=1, var_true=True, var_false=False, var_dict=dict(a="b"), bad_dict="{a='b'", var_list=[1], recursive="{{recursive}}", some_var="blip", some_static_var="static_blip", some_keyword="{{ foo }}", some_unsafe_var=wrap_var("unsafe_blip"), some_static_unsafe_var=wrap_var("static_unsafe_blip"), some_unsafe_keyword=wrap_var("{{ foo }}"), ) self.fake_loader = DictDataLoader({ "/path/to/my_file.txt": "foo\n", }) self.templar = Templar(loader=self.fake_loader, variables=self.test_vars)
def test_play_with_roles(self): fake_loader = DictDataLoader({ '/etc/ansible/roles/foo/tasks.yml': """ - name: role task shell: echo "hello world" """, }) mock_var_manager = MagicMock() mock_var_manager.get_vars.return_value = dict() p = Play.load(dict( name="test play", hosts=['foo'], gather_facts=False, roles=['foo'], ), loader=fake_loader, variable_manager=mock_var_manager) blocks = p.compile()
def test_task_executor_get_action_handler(self): te = TaskExecutor( host=MagicMock(), task=MagicMock(), job_vars={}, play_context=MagicMock(), new_stdin=None, loader=DictDataLoader({}), shared_loader_obj=MagicMock(), final_q=MagicMock(), ) context = MagicMock(resolved=False) te._shared_loader_obj.module_loader.find_plugin_with_context.return_value = context action_loader = te._shared_loader_obj.action_loader action_loader.has_plugin.return_value = True action_loader.get.return_value = mock.sentinel.handler mock_connection = MagicMock() mock_templar = MagicMock() action = 'namespace.prefix_suffix' te._task.action = action handler = te._get_action_handler(mock_connection, mock_templar) self.assertIs(mock.sentinel.handler, handler) action_loader.has_plugin.assert_called_once_with( action, collection_list=te._task.collections) action_loader.get.assert_called_once_with( te._task.action, task=te._task, connection=mock_connection, play_context=te._play_context, loader=te._loader, templar=mock_templar, shared_loader_obj=te._shared_loader_obj, collection_list=te._task.collections)
def test_strategy_base_load_included_file(self): fake_loader = DictDataLoader({ "test.yml": """ - debug: msg='foo' """, "bad.yml": """ """, }) mock_tqm = MagicMock() mock_tqm._final_q = MagicMock() mock_tqm._notified_handlers = {} mock_tqm._listening_handlers = {} strategy_base = StrategyBase(tqm=mock_tqm) strategy_base._loader = fake_loader mock_play = MagicMock() mock_block = MagicMock() mock_block._play = mock_play mock_block.vars = dict() mock_task = MagicMock() mock_task._block = mock_block mock_task._role = None mock_iterator = MagicMock() mock_iterator.mark_host_failed.return_value = None mock_inc_file = MagicMock() mock_inc_file._task = mock_task mock_inc_file._filename = "test.yml" res = strategy_base._load_included_file(included_file=mock_inc_file, iterator=mock_iterator) mock_inc_file._filename = "bad.yml" res = strategy_base._load_included_file(included_file=mock_inc_file, iterator=mock_iterator) self.assertEqual(res, [])
def test_play_with_roles(mocker): mocker.patch('ansible.playbook.role.definition.RoleDefinition._load_role_path', return_value=('foo', '/etc/ansible/roles/foo')) fake_loader = DictDataLoader({ '/etc/ansible/roles/foo/tasks.yml': """ - name: role task shell: echo "hello world" """, }) mock_var_manager = mocker.MagicMock() mock_var_manager.get_vars.return_value = {} p = Play.load(dict( name="test play", hosts=['foo'], gather_facts=False, roles=['foo'], ), loader=fake_loader, variable_manager=mock_var_manager) blocks = p.compile() assert len(blocks) > 1 assert all(isinstance(block, Block) for block in blocks) assert isinstance(p.get_roles()[0], Role)
def test_strategy_base_load_included_file(self): fake_loader = DictDataLoader({ "test.yml": """ - debug: msg='foo' """, "bad.yml": """ """, }) queue_items = [] def _queue_empty(*args, **kwargs): return len(queue_items) == 0 def _queue_get(*args, **kwargs): if len(queue_items) == 0: raise Queue.Empty else: return queue_items.pop() def _queue_put(item, *args, **kwargs): queue_items.append(item) mock_queue = MagicMock() mock_queue.empty.side_effect = _queue_empty mock_queue.get.side_effect = _queue_get mock_queue.put.side_effect = _queue_put mock_tqm = MagicMock() mock_tqm._final_q = mock_queue mock_tqm._notified_handlers = {} mock_tqm._listening_handlers = {} strategy_base = StrategyBase(tqm=mock_tqm) strategy_base._loader = fake_loader strategy_base.cleanup() mock_play = MagicMock() mock_block = MagicMock() mock_block._play = mock_play mock_block.vars = dict() mock_task = MagicMock() mock_task._block = mock_block mock_task._role = None mock_task._parent = None mock_iterator = MagicMock() mock_iterator.mark_host_failed.return_value = None mock_inc_file = MagicMock() mock_inc_file._task = mock_task mock_inc_file._filename = "test.yml" res = strategy_base._load_included_file(included_file=mock_inc_file, iterator=mock_iterator) mock_inc_file._filename = "bad.yml" res = strategy_base._load_included_file(included_file=mock_inc_file, iterator=mock_iterator) self.assertEqual(res, [])
def test_play_iterator(self): # import epdb; epdb.st() fake_loader = DictDataLoader({ "test_play.yml": """ - hosts: all gather_facts: false roles: - test_role pre_tasks: - debug: msg="this is a pre_task" tasks: - debug: msg="this is a regular task" - block: - debug: msg="this is a block task" - block: - debug: msg="this is a sub-block in a block" rescue: - debug: msg="this is a rescue task" - block: - debug: msg="this is a sub-block in a rescue" always: - debug: msg="this is an always task" - block: - debug: msg="this is a sub-block in an always" post_tasks: - debug: msg="this is a post_task" """, '/etc/ansible/roles/test_role/tasks/main.yml': """ - name: role task debug: msg="this is a role task" - block: - name: role block task debug: msg="inside block in role" always: - name: role always task debug: msg="always task in block in role" - include: foo.yml - name: role task after include debug: msg="after include in role" - block: - name: starting role nested block 1 debug: - block: - name: role nested block 1 task 1 debug: - name: role nested block 1 task 2 debug: - name: role nested block 1 task 3 debug: - name: end of role nested block 1 debug: - name: starting role nested block 2 debug: - block: - name: role nested block 2 task 1 debug: - name: role nested block 2 task 2 debug: - name: role nested block 2 task 3 debug: - name: end of role nested block 2 debug: """, '/etc/ansible/roles/test_role/tasks/foo.yml': """ - name: role included task debug: msg="this is task in an include from a role" """ }) mock_var_manager = MagicMock() mock_var_manager._fact_cache = dict() mock_var_manager.get_vars.return_value = dict() p = Playbook.load('test_play.yml', loader=fake_loader, variable_manager=mock_var_manager) hosts = [] for i in range(0, 10): host = MagicMock() host.name = host.get_name.return_value = 'host%02d' % i hosts.append(host) mock_var_manager._fact_cache['host00'] = dict() inventory = MagicMock() inventory.get_hosts.return_value = hosts inventory.filter_hosts.return_value = hosts play_context = PlayContext(play=p._entries[0]) itr = PlayIterator( inventory=inventory, play=p._entries[0], play_context=play_context, variable_manager=mock_var_manager, all_vars=dict(), ) # pre task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') # implicit meta: flush_handlers (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'meta') # role task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.name, "role task") self.assertIsNotNone(task._role) # role block task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.name, "role block task") self.assertIsNotNone(task._role) # role block always task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.name, "role always task") self.assertIsNotNone(task._role) # role include task # (host_state, task) = itr.get_next_task_for_host(hosts[0]) # self.assertIsNotNone(task) # self.assertEqual(task.action, 'debug') # self.assertEqual(task.name, "role included task") # self.assertIsNotNone(task._role) # role task after include (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.name, "role task after include") self.assertIsNotNone(task._role) # role nested block tasks (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.name, "starting role nested block 1") self.assertIsNotNone(task._role) (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.name, "role nested block 1 task 1") self.assertIsNotNone(task._role) (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.name, "role nested block 1 task 2") self.assertIsNotNone(task._role) (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.name, "role nested block 1 task 3") self.assertIsNotNone(task._role) (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.name, "end of role nested block 1") self.assertIsNotNone(task._role) (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.name, "starting role nested block 2") self.assertIsNotNone(task._role) (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.name, "role nested block 2 task 1") self.assertIsNotNone(task._role) (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.name, "role nested block 2 task 2") self.assertIsNotNone(task._role) (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.name, "role nested block 2 task 3") self.assertIsNotNone(task._role) (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.name, "end of role nested block 2") self.assertIsNotNone(task._role) # implicit meta: role_complete (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'meta') self.assertIsNotNone(task._role) # regular play task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertIsNone(task._role) # block task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.args, dict(msg="this is a block task")) # sub-block task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.args, dict(msg="this is a sub-block in a block")) # mark the host failed itr.mark_host_failed(hosts[0]) # block rescue task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.args, dict(msg="this is a rescue task")) # sub-block rescue task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.args, dict(msg="this is a sub-block in a rescue")) # block always task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.args, dict(msg="this is an always task")) # sub-block always task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.args, dict(msg="this is a sub-block in an always")) # implicit meta: flush_handlers (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'meta') # post task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') # implicit meta: flush_handlers (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'meta') # end of iteration (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNone(task) # host 0 shouldn't be in the failed hosts, as the error # was handled by a rescue block failed_hosts = itr.get_failed_hosts() self.assertNotIn(hosts[0], failed_hosts)
def test_play_iterator_add_tasks(self): fake_loader = DictDataLoader({ 'test_play.yml': """ - hosts: all gather_facts: no tasks: - debug: msg="dummy task" """, }) mock_var_manager = MagicMock() mock_var_manager._fact_cache = dict() mock_var_manager.get_vars.return_value = dict() p = Playbook.load('test_play.yml', loader=fake_loader, variable_manager=mock_var_manager) hosts = [] for i in range(0, 10): host = MagicMock() host.name = host.get_name.return_value = 'host%02d' % i hosts.append(host) inventory = MagicMock() inventory.get_hosts.return_value = hosts inventory.filter_hosts.return_value = hosts play_context = PlayContext(play=p._entries[0]) itr = PlayIterator( inventory=inventory, play=p._entries[0], play_context=play_context, variable_manager=mock_var_manager, all_vars=dict(), ) # test the high-level add_tasks() method s = HostState(blocks=[0, 1, 2]) itr._insert_tasks_into_state = MagicMock(return_value=s) itr.add_tasks(hosts[0], [MagicMock(), MagicMock(), MagicMock()]) self.assertEqual(itr._host_states[hosts[0].name], s) # now actually test the lower-level method that does the work itr = PlayIterator( inventory=inventory, play=p._entries[0], play_context=play_context, variable_manager=mock_var_manager, all_vars=dict(), ) # iterate past first task _, task = itr.get_next_task_for_host(hosts[0]) while (task and task.action != 'debug'): _, task = itr.get_next_task_for_host(hosts[0]) if task is None: raise Exception( "iterated past end of play while looking for place to insert tasks" ) # get the current host state and copy it so we can mutate it s = itr.get_host_state(hosts[0]) s_copy = s.copy() # assert with an empty task list, or if we're in a failed state, we simply return the state as-is res_state = itr._insert_tasks_into_state(s_copy, task_list=[]) self.assertEqual(res_state, s_copy) s_copy.fail_state = itr.FAILED_TASKS res_state = itr._insert_tasks_into_state(s_copy, task_list=[MagicMock()]) self.assertEqual(res_state, s_copy) # but if we've failed with a rescue/always block mock_task = MagicMock() s_copy.run_state = itr.ITERATING_RESCUE res_state = itr._insert_tasks_into_state(s_copy, task_list=[mock_task]) self.assertEqual(res_state, s_copy) self.assertIn(mock_task, res_state._blocks[res_state.cur_block].rescue) itr._host_states[hosts[0].name] = res_state (next_state, next_task) = itr.get_next_task_for_host(hosts[0], peek=True) self.assertEqual(next_task, mock_task) itr._host_states[hosts[0].name] = s # test a regular insertion s_copy = s.copy() res_state = itr._insert_tasks_into_state(s_copy, task_list=[MagicMock()])
def test_play_iterator_nested_blocks(self): fake_loader = DictDataLoader({ "test_play.yml": """ - hosts: all gather_facts: false tasks: - block: - block: - block: - block: - block: - debug: msg="this is the first task" - ping: rescue: - block: - block: - block: - block: - debug: msg="this is the rescue task" always: - block: - block: - block: - block: - debug: msg="this is the always task" """, }) mock_var_manager = MagicMock() mock_var_manager._fact_cache = dict() mock_var_manager.get_vars.return_value = dict() p = Playbook.load('test_play.yml', loader=fake_loader, variable_manager=mock_var_manager) hosts = [] for i in range(0, 10): host = MagicMock() host.name = host.get_name.return_value = 'host%02d' % i hosts.append(host) inventory = MagicMock() inventory.get_hosts.return_value = hosts inventory.filter_hosts.return_value = hosts play_context = PlayContext(play=p._entries[0]) itr = PlayIterator( inventory=inventory, play=p._entries[0], play_context=play_context, variable_manager=mock_var_manager, all_vars=dict(), ) # implicit meta: flush_handlers (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'meta') self.assertEqual(task.args, dict(_raw_params='flush_handlers')) # get the first task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.args, dict(msg='this is the first task')) # fail the host itr.mark_host_failed(hosts[0]) # get the resuce task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.args, dict(msg='this is the rescue task')) # get the always task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.args, dict(msg='this is the always task')) # implicit meta: flush_handlers (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'meta') self.assertEqual(task.args, dict(_raw_params='flush_handlers')) # implicit meta: flush_handlers (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'meta') self.assertEqual(task.args, dict(_raw_params='flush_handlers')) # end of iteration (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNone(task)
def test_templar_simple(self): fake_loader = DictDataLoader({ "/path/to/my_file.txt": "foo\n", }) shared_loader = SharedPluginLoaderObj() variables = dict( foo="bar", bam="{{foo}}", num=1, var_true=True, var_false=False, var_dict=dict(a="b"), bad_dict="{a='b'", var_list=[1], recursive="{{recursive}}", ) templar = Templar(loader=fake_loader, variables=variables) # test some basic templating self.assertEqual(templar.template("{{foo}}"), "bar") self.assertEqual(templar.template("{{foo}}\n"), "bar\n") self.assertEqual( templar.template("{{foo}}\n", preserve_trailing_newlines=True), "bar\n") self.assertEqual( templar.template("{{foo}}\n", preserve_trailing_newlines=False), "bar") self.assertEqual(templar.template("foo", convert_bare=True), "bar") self.assertEqual(templar.template("{{bam}}"), "bar") self.assertEqual(templar.template("{{num}}"), 1) self.assertEqual(templar.template("{{var_true}}"), True) self.assertEqual(templar.template("{{var_false}}"), False) self.assertEqual(templar.template("{{var_dict}}"), dict(a="b")) self.assertEqual(templar.template("{{bad_dict}}"), "{a='b'") self.assertEqual(templar.template("{{var_list}}"), [1]) self.assertEqual(templar.template(1, convert_bare=True), 1) #FIXME: lookup ignores fake file and returns error #self.assertEqual(templar.template("{{lookup('file', '/path/to/my_file.txt')}}"), "foo") # force errors self.assertRaises(AnsibleUndefinedVariable, templar.template, "{{bad_var}}") self.assertRaises(AnsibleUndefinedVariable, templar.template, "{{lookup('file', bad_var)}}") self.assertRaises(AnsibleError, templar.template, "{{lookup('bad_lookup')}}") self.assertRaises(AnsibleError, templar.template, "{{recursive}}") self.assertRaises(AnsibleUndefinedVariable, templar.template, "{{foo-bar}}") # test with fail_on_undefined=False self.assertEqual( templar.template("{{bad_var}}", fail_on_undefined=False), "{{bad_var}}") # test set_available_variables() templar.set_available_variables(variables=dict(foo="bam")) self.assertEqual(templar.template("{{foo}}"), "bam") # variables must be a dict() for set_available_variables() self.assertRaises(AssertionError, templar.set_available_variables, "foo=bam")
def test_post_validate_empty(self): fake_loader = DictDataLoader({}) templar = Templar(loader=fake_loader) ret = self.b.post_validate(templar) self.assertIsNone(ret)
def setUp(self): self.loader = DictDataLoader({}) self.cond = conditional.Conditional(loader=self.loader) self.shared_loader = SharedPluginLoaderObj() self.templar = Templar(loader=self.loader, variables={})
def test_action_base__configure_module(self): fake_loader = DictDataLoader({}) # create our fake task mock_task = MagicMock() mock_task.action = "copy" # create a mock connection, so we don't actually try and connect to things mock_connection = MagicMock() # create a mock shared loader object def mock_find_plugin(name, options): if name == 'badmodule': return None elif '.ps1' in options: return '/fake/path/to/%s.ps1' % name else: return '/fake/path/to/%s' % name mock_module_loader = MagicMock() mock_module_loader.find_plugin.side_effect = mock_find_plugin mock_shared_obj_loader = MagicMock() mock_shared_obj_loader.module_loader = mock_module_loader # we're using a real play context here play_context = PlayContext() # our test class action_base = DerivedActionBase( task=mock_task, connection=mock_connection, play_context=play_context, loader=fake_loader, templar=None, shared_loader_obj=mock_shared_obj_loader, ) # test python module formatting with patch.object( builtins, 'open', mock_open(read_data=to_bytes(python_module_replacers.strip(), encoding='utf-8'))) as m: with patch.object(os, 'rename') as m: mock_task.args = dict(a=1, foo='fö〩') mock_connection.module_implementation_preferences = ('', ) (style, shebang, data, path) = action_base._configure_module(mock_task.action, mock_task.args) self.assertEqual(style, "new") self.assertEqual(shebang, u"#!/usr/bin/python") # test module not found self.assertRaises(AnsibleError, action_base._configure_module, 'badmodule', mock_task.args) # test powershell module formatting with patch.object( builtins, 'open', mock_open( read_data=to_bytes(powershell_module_replacers.strip(), encoding='utf-8'))) as m: mock_task.action = 'win_copy' mock_task.args = dict(b=2) mock_connection.module_implementation_preferences = ('.ps1', ) (style, shebang, data, path) = action_base._configure_module('stat', mock_task.args) self.assertEqual(style, "new") self.assertEqual(shebang, u'#!powershell') # test module not found self.assertRaises(AnsibleError, action_base._configure_module, 'badmodule', mock_task.args)
def test_task_executor_poll_async_result(self): fake_loader = DictDataLoader({}) mock_host = MagicMock() mock_task = MagicMock() mock_task. async = 0.1 mock_task.poll = 0.05 mock_play_context = MagicMock() mock_connection = MagicMock() mock_action = MagicMock() mock_queue = MagicMock() shared_loader = MagicMock() shared_loader.action_loader = action_loader new_stdin = None job_vars = dict(omit="XXXXXXXXXXXXXXXXXXX") te = TaskExecutor( host=mock_host, task=mock_task, job_vars=job_vars, play_context=mock_play_context, new_stdin=new_stdin, loader=fake_loader, shared_loader_obj=shared_loader, rslt_q=mock_queue, ) te._connection = MagicMock() def _get(*args, **kwargs): mock_action = MagicMock() mock_action.run.return_value = dict(stdout='') return mock_action # testing with some bad values in the result passed to poll async, # and with a bad value returned from the mock action with patch.object(action_loader, 'get', _get): mock_templar = MagicMock() res = te._poll_async_result(result=dict(), templar=mock_templar) self.assertIn('failed', res) res = te._poll_async_result(result=dict(ansible_job_id=1), templar=mock_templar) self.assertIn('failed', res) def _get(*args, **kwargs): mock_action = MagicMock() mock_action.run.return_value = dict(finished=1) return mock_action # now testing with good values with patch.object(action_loader, 'get', _get): mock_templar = MagicMock() res = te._poll_async_result(result=dict(ansible_job_id=1), templar=mock_templar) self.assertEqual(res, dict(finished=1))
def test_task_executor_squash_items(self): items = ['a', 'b', 'c'] fake_loader = DictDataLoader({}) mock_host = MagicMock() loop_var = 'item' def _evaluate_conditional(templar, variables): item = variables.get(loop_var) if item == 'b': return False return True mock_task = MagicMock() mock_task.evaluate_conditional.side_effect = _evaluate_conditional mock_play_context = MagicMock() mock_shared_loader = None mock_queue = MagicMock() new_stdin = None job_vars = dict(pkg_mgr='yum') te = TaskExecutor( host=mock_host, task=mock_task, job_vars=job_vars, play_context=mock_play_context, new_stdin=new_stdin, loader=fake_loader, shared_loader_obj=mock_shared_loader, rslt_q=mock_queue, ) # No replacement mock_task.action = 'yum' new_items = te._squash_items(items=items, loop_var='item', variables=job_vars) self.assertEqual(new_items, ['a', 'b', 'c']) self.assertIsInstance(mock_task.args, MagicMock) mock_task.action = 'foo' mock_task.args = {'name': '{{item}}'} new_items = te._squash_items(items=items, loop_var='item', variables=job_vars) self.assertEqual(new_items, ['a', 'b', 'c']) self.assertEqual(mock_task.args, {'name': '{{item}}'}) mock_task.action = 'yum' mock_task.args = {'name': 'static'} new_items = te._squash_items(items=items, loop_var='item', variables=job_vars) self.assertEqual(new_items, ['a', 'b', 'c']) self.assertEqual(mock_task.args, {'name': 'static'}) mock_task.action = 'yum' mock_task.args = {'name': '{{pkg_mgr}}'} new_items = te._squash_items(items=items, loop_var='item', variables=job_vars) self.assertEqual(new_items, ['a', 'b', 'c']) self.assertEqual(mock_task.args, {'name': '{{pkg_mgr}}'}) mock_task.action = '{{unknown}}' mock_task.args = {'name': '{{item}}'} new_items = te._squash_items(items=items, loop_var='item', variables=job_vars) self.assertEqual(new_items, ['a', 'b', 'c']) self.assertEqual(mock_task.args, {'name': '{{item}}'}) # Could do something like this to recover from bad deps in a package job_vars = dict(pkg_mgr='yum', packages=['a', 'b']) items = ['absent', 'latest'] mock_task.action = 'yum' mock_task.args = {'name': '{{ packages }}', 'state': '{{ item }}'} new_items = te._squash_items(items=items, loop_var='item', variables=job_vars) self.assertEqual(new_items, items) self.assertEqual(mock_task.args, { 'name': '{{ packages }}', 'state': '{{ item }}' }) # Maybe should raise an error in this case. The user would have to specify: # - yum: name="{{ packages[item] }}" # with_items: # - ['a', 'b'] # - ['foo', 'bar'] # you can't use a list as a dict key so that would probably throw # an error later. If so, we can throw it now instead. # Squashing in this case would not be intuitive as the user is being # explicit in using each list entry as a key. job_vars = dict(pkg_mgr='yum', packages={ "a": "foo", "b": "bar", "foo": "baz", "bar": "quux" }) items = [['a', 'b'], ['foo', 'bar']] mock_task.action = 'yum' mock_task.args = {'name': '{{ packages[item] }}'} new_items = te._squash_items(items=items, loop_var='item', variables=job_vars) self.assertEqual(new_items, items) self.assertEqual(mock_task.args, {'name': '{{ packages[item] }}'}) # Replaces items = ['a', 'b', 'c'] mock_task.action = 'yum' mock_task.args = {'name': '{{item}}'} new_items = te._squash_items(items=items, loop_var='item', variables=job_vars) self.assertEqual(new_items, [['a', 'c']]) self.assertEqual(mock_task.args, {'name': ['a', 'c']}) mock_task.action = '{{pkg_mgr}}' mock_task.args = {'name': '{{item}}'} new_items = te._squash_items(items=items, loop_var='item', variables=job_vars) self.assertEqual(new_items, [['a', 'c']]) self.assertEqual(mock_task.args, {'name': ['a', 'c']}) # New loop_var mock_task.action = 'yum' mock_task.args = {'name': '{{a_loop_var_item}}'} mock_task.loop_control = {'loop_var': 'a_loop_var_item'} loop_var = 'a_loop_var_item' new_items = te._squash_items(items=items, loop_var='a_loop_var_item', variables=job_vars) self.assertEqual(new_items, [['a', 'c']]) self.assertEqual(mock_task.args, {'name': ['a', 'c']}) loop_var = 'item' # # These are presently not optimized but could be in the future. # Expected output if they were optimized is given as a comment # Please move these to a different section if they are optimized # # Squashing lists job_vars = dict(pkg_mgr='yum') items = [['a', 'b'], ['foo', 'bar']] mock_task.action = 'yum' mock_task.args = {'name': '{{ item }}'} new_items = te._squash_items(items=items, loop_var='item', variables=job_vars) # self.assertEqual(new_items, [['a', 'b', 'foo', 'bar']]) # self.assertEqual(mock_task.args, {'name': ['a', 'b', 'foo', 'bar']}) self.assertEqual(new_items, items) self.assertEqual(mock_task.args, {'name': '{{ item }}'}) # Retrieving from a dict items = ['a', 'b', 'foo'] mock_task.action = 'yum' mock_task.args = {'name': '{{ packages[item] }}'} new_items = te._squash_items(items=items, loop_var='item', variables=job_vars) # self.assertEqual(new_items, [['foo', 'baz']]) # self.assertEqual(mock_task.args, {'name': ['foo', 'baz']}) self.assertEqual(new_items, items) self.assertEqual(mock_task.args, {'name': '{{ packages[item] }}'}) # Another way to retrieve from a dict job_vars = dict(pkg_mgr='yum') items = [{'package': 'foo'}, {'package': 'bar'}] mock_task.action = 'yum' mock_task.args = {'name': '{{ item["package"] }}'} new_items = te._squash_items(items=items, loop_var='item', variables=job_vars) # self.assertEqual(new_items, [['foo', 'bar']]) # self.assertEqual(mock_task.args, {'name': ['foo', 'bar']}) self.assertEqual(new_items, items) self.assertEqual(mock_task.args, {'name': '{{ item["package"] }}'}) items = [ dict(name='a', state='present'), dict(name='b', state='present'), dict(name='c', state='present'), ] mock_task.action = 'yum' mock_task.args = {'name': '{{item.name}}', 'state': '{{item.state}}'} new_items = te._squash_items(items=items, loop_var='item', variables=job_vars) # self.assertEqual(new_items, [dict(name=['a', 'b', 'c'], state='present')]) # self.assertEqual(mock_task.args, {'name': ['a', 'b', 'c'], 'state': 'present'}) self.assertEqual(new_items, items) self.assertEqual(mock_task.args, { 'name': '{{item.name}}', 'state': '{{item.state}}' }) items = [ dict(name='a', state='present'), dict(name='b', state='present'), dict(name='c', state='absent'), ] mock_task.action = 'yum' mock_task.args = {'name': '{{item.name}}', 'state': '{{item.state}}'} new_items = te._squash_items(items=items, loop_var='item', variables=job_vars) # self.assertEqual(new_items, [dict(name=['a', 'b'], state='present'), # dict(name='c', state='absent')]) # self.assertEqual(mock_task.args, {'name': '{{item.name}}', 'state': '{{item.state}}'}) self.assertEqual(new_items, items) self.assertEqual(mock_task.args, { 'name': '{{item.name}}', 'state': '{{item.state}}' })
def test_load_role_with_metadata(self): fake_loader = DictDataLoader({ '/etc/ansible/roles/foo_metadata/meta/main.yml': """ allow_duplicates: true dependencies: - bar_metadata galaxy_info: a: 1 b: 2 c: 3 """, '/etc/ansible/roles/bar_metadata/meta/main.yml': """ dependencies: - baz_metadata """, '/etc/ansible/roles/baz_metadata/meta/main.yml': """ dependencies: - bam_metadata """, '/etc/ansible/roles/bam_metadata/meta/main.yml': """ dependencies: [] """, '/etc/ansible/roles/bad1_metadata/meta/main.yml': """ 1 """, '/etc/ansible/roles/bad2_metadata/meta/main.yml': """ foo: bar """, '/etc/ansible/roles/recursive1_metadata/meta/main.yml': """ dependencies: ['recursive2_metadata'] """, '/etc/ansible/roles/recursive2_metadata/meta/main.yml': """ dependencies: ['recursive1_metadata'] """, }) mock_play = MagicMock() mock_play.collections = None mock_play.ROLE_CACHE = {} i = RoleInclude.load('foo_metadata', play=mock_play, loader=fake_loader) r = Role.load(i, play=mock_play) role_deps = r.get_direct_dependencies() self.assertEqual(len(role_deps), 1) self.assertEqual(type(role_deps[0]), Role) self.assertEqual(len(role_deps[0].get_parents()), 1) self.assertEqual(role_deps[0].get_parents()[0], r) self.assertEqual(r._metadata.allow_duplicates, True) self.assertEqual(r._metadata.galaxy_info, dict(a=1, b=2, c=3)) all_deps = r.get_all_dependencies() self.assertEqual(len(all_deps), 3) self.assertEqual(all_deps[0].get_name(), 'bam_metadata') self.assertEqual(all_deps[1].get_name(), 'baz_metadata') self.assertEqual(all_deps[2].get_name(), 'bar_metadata') i = RoleInclude.load('bad1_metadata', play=mock_play, loader=fake_loader) self.assertRaises(AnsibleParserError, Role.load, i, play=mock_play) i = RoleInclude.load('bad2_metadata', play=mock_play, loader=fake_loader) self.assertRaises(AnsibleParserError, Role.load, i, play=mock_play)
def test_playbook_executor__get_serialized_batches(self): fake_loader = DictDataLoader({ 'no_serial.yml': ''' - hosts: all gather_facts: no tasks: - debug: var=inventory_hostname ''', 'serial_int.yml': ''' - hosts: all gather_facts: no serial: 2 tasks: - debug: var=inventory_hostname ''', 'serial_pct.yml': ''' - hosts: all gather_facts: no serial: 20% tasks: - debug: var=inventory_hostname ''', }) mock_inventory = MagicMock() mock_var_manager = MagicMock() # fake out options to use the syntax CLI switch, which will ensure # the PlaybookExecutor doesn't create a TaskQueueManager mock_options = MagicMock() mock_options.syntax.value = True pbe = PlaybookExecutor( playbooks=['no_serial.yml', 'serial_int.yml', 'serial_pct.yml'], inventory=mock_inventory, variable_manager=mock_var_manager, loader=fake_loader, options=mock_options, passwords=[], ) playbook = Playbook.load(pbe._playbooks[0], variable_manager=mock_var_manager, loader=fake_loader) play = playbook.get_plays()[0] mock_inventory.get_hosts.return_value = [ 'host0', 'host1', 'host2', 'host3', 'host4', 'host5', 'host6', 'host7', 'host8', 'host9' ] self.assertEqual(pbe._get_serialized_batches(play), [[ 'host0', 'host1', 'host2', 'host3', 'host4', 'host5', 'host6', 'host7', 'host8', 'host9' ]]) playbook = Playbook.load(pbe._playbooks[1], variable_manager=mock_var_manager, loader=fake_loader) play = playbook.get_plays()[0] mock_inventory.get_hosts.return_value = [ 'host0', 'host1', 'host2', 'host3', 'host4', 'host5', 'host6', 'host7', 'host8', 'host9' ] self.assertEqual( pbe._get_serialized_batches(play), [['host0', 'host1'], ['host2', 'host3'], ['host4', 'host5'], ['host6', 'host7'], ['host8', 'host9']]) playbook = Playbook.load(pbe._playbooks[2], variable_manager=mock_var_manager, loader=fake_loader) play = playbook.get_plays()[0] mock_inventory.get_hosts.return_value = [ 'host0', 'host1', 'host2', 'host3', 'host4', 'host5', 'host6', 'host7', 'host8', 'host9' ] self.assertEqual( pbe._get_serialized_batches(play), [['host0', 'host1'], ['host2', 'host3'], ['host4', 'host5'], ['host6', 'host7'], ['host8', 'host9']]) # Test when serial percent is under 1.0 playbook = Playbook.load(pbe._playbooks[2], variable_manager=mock_var_manager, loader=fake_loader) play = playbook.get_plays()[0] mock_inventory.get_hosts.return_value = ['host0', 'host1', 'host2'] self.assertEqual(pbe._get_serialized_batches(play), [['host0'], ['host1'], ['host2']]) # Test when there is a remainder for serial as a percent playbook = Playbook.load(pbe._playbooks[2], variable_manager=mock_var_manager, loader=fake_loader) play = playbook.get_plays()[0] mock_inventory.get_hosts.return_value = [ 'host0', 'host1', 'host2', 'host3', 'host4', 'host5', 'host6', 'host7', 'host8', 'host9', 'host10' ] self.assertEqual( pbe._get_serialized_batches(play), [['host0', 'host1'], ['host2', 'host3'], ['host4', 'host5'], ['host6', 'host7'], ['host8', 'host9'], ['host10']])
def test_strategy_base_run_handlers(self, mock_worker): def fake_run(*args): return mock_worker.side_effect = fake_run mock_play_context = MagicMock() mock_handler_task = MagicMock(Handler) mock_handler_task.action = 'foo' mock_handler_task.get_name.return_value = "test handler" mock_handler_task.has_triggered.return_value = False mock_handler_task.listen = None mock_handler_task._role = None mock_handler_task._parent = None mock_handler_task._uuid = 'xxxxxxxxxxxxxxxx' mock_handler = MagicMock() mock_handler.block = [mock_handler_task] mock_handler.flag_for_host.return_value = False mock_play = MagicMock() mock_play.handlers = [mock_handler] mock_host = MagicMock(Host) mock_host.name = "test01" mock_host.has_hostkey = True mock_inventory = MagicMock() mock_inventory.get_hosts.return_value = [mock_host] mock_var_mgr = MagicMock() mock_var_mgr.get_vars.return_value = dict() mock_iterator = MagicMock() mock_iterator._play = mock_play mock_iterator.get_original_task.return_value = mock_handler_task fake_loader = DictDataLoader() mock_options = MagicMock() mock_options.module_path = None tqm = TaskQueueManager( inventory=mock_inventory, variable_manager=mock_var_mgr, loader=fake_loader, options=mock_options, passwords=None, ) tqm._initialize_processes(3) tqm._initialize_notified_handlers(mock_play) tqm.hostvars = dict() try: strategy_base = StrategyBase(tqm=tqm) strategy_base._inventory = mock_inventory strategy_base._notified_handlers = { mock_handler_task._uuid: [mock_host] } task_result = TaskResult(Host('host01'), Handler(), dict(changed=False)) tqm._final_q.put(task_result) result = strategy_base.run_handlers(iterator=mock_iterator, play_context=mock_play_context) finally: strategy_base.cleanup() tqm.cleanup()
def test_task_executor_execute(self): fake_loader = DictDataLoader({}) mock_host = MagicMock() mock_task = MagicMock() mock_task.args = dict() mock_task.retries = 0 mock_task.delay = -1 mock_task.register = 'foo' mock_task.until = None mock_task.changed_when = None mock_task.failed_when = None mock_task.post_validate.return_value = None # mock_task.async cannot be left unset, because on Python 3 MagicMock() # > 0 raises a TypeError There are two reasons for using the value 1 # here: on Python 2 comparing MagicMock() > 0 returns True, and the # other reason is that if I specify 0 here, the test fails. ;) mock_task. async = 1 mock_play_context = MagicMock() mock_play_context.post_validate.return_value = None mock_play_context.update_vars.return_value = None mock_connection = MagicMock() mock_connection.set_host_overrides.return_value = None mock_connection._connect.return_value = None mock_action = MagicMock() shared_loader = None new_stdin = None job_vars = dict(omit="XXXXXXXXXXXXXXXXXXX") te = TaskExecutor( host=mock_host, task=mock_task, job_vars=job_vars, play_context=mock_play_context, new_stdin=new_stdin, loader=fake_loader, shared_loader_obj=shared_loader, ) te._get_connection = MagicMock(return_value=mock_connection) te._get_action_handler = MagicMock(return_value=mock_action) mock_action.run.return_value = dict(ansible_facts=dict()) res = te._execute() mock_task.changed_when = "1 == 1" res = te._execute() mock_task.changed_when = None mock_task.failed_when = "1 == 1" res = te._execute() mock_task.failed_when = None mock_task.evaluate_conditional.return_value = False res = te._execute() mock_task.evaluate_conditional.return_value = True mock_task.args = dict(_raw_params='foo.yml', a='foo', b='bar') mock_task.action = 'include' res = te._execute()
def test_empty_playbook(self): fake_loader = DictDataLoader({}) p = Playbook(loader=fake_loader)
def test_play_iterator(self): fake_loader = DictDataLoader({ "test_play.yml": """ - hosts: all gather_facts: false roles: - test_role pre_tasks: - debug: msg="this is a pre_task" tasks: - debug: msg="this is a regular task" - block: - debug: msg="this is a block task" - block: - debug: msg="this is a sub-block in a block" rescue: - debug: msg="this is a rescue task" - block: - debug: msg="this is a sub-block in a rescue" always: - debug: msg="this is an always task" - block: - debug: msg="this is a sub-block in an always" post_tasks: - debug: msg="this is a post_task" """, '/etc/ansible/roles/test_role/tasks/main.yml': """ - debug: msg="this is a role task" """, }) mock_var_manager = MagicMock() mock_var_manager._fact_cache = dict() mock_var_manager.get_vars.return_value = dict() p = Playbook.load('test_play.yml', loader=fake_loader, variable_manager=mock_var_manager) hosts = [] for i in range(0, 10): host = MagicMock() host.name = host.get_name.return_value = 'host%02d' % i hosts.append(host) mock_var_manager._fact_cache['host00'] = dict() inventory = MagicMock() inventory.get_hosts.return_value = hosts inventory.filter_hosts.return_value = hosts play_context = PlayContext(play=p._entries[0]) itr = PlayIterator( inventory=inventory, play=p._entries[0], play_context=play_context, variable_manager=mock_var_manager, all_vars=dict(), ) # lookup up an original task target_task = p._entries[0].tasks[0].block[0] task_copy = target_task.copy(exclude_block=True) found_task = itr.get_original_task(hosts[0], task_copy) self.assertEqual(target_task, found_task) bad_task = Task() found_task = itr.get_original_task(hosts[0], bad_task) self.assertIsNone(found_task) # pre task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') # implicit meta: flush_handlers (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'meta') # role task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertIsNotNone(task._role) # regular play task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertIsNone(task._role) # block task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.args, dict(msg="this is a block task")) # sub-block task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.args, dict(msg="this is a sub-block in a block")) # mark the host failed itr.mark_host_failed(hosts[0]) # block rescue task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.args, dict(msg="this is a rescue task")) # sub-block rescue task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.args, dict(msg="this is a sub-block in a rescue")) # block always task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.args, dict(msg="this is an always task")) # sub-block always task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') self.assertEqual(task.args, dict(msg="this is a sub-block in an always")) # implicit meta: flush_handlers (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'meta') # post task (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'debug') # implicit meta: flush_handlers (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNotNone(task) self.assertEqual(task.action, 'meta') # end of iteration (host_state, task) = itr.get_next_task_for_host(hosts[0]) self.assertIsNone(task) # host 0 shouldn't be in the failed hosts, as the error # was handled by a rescue block failed_hosts = itr.get_failed_hosts() self.assertNotIn(hosts[0], failed_hosts)