1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00
community.general/tests/unit/plugins/lookup/test_merge_variables.py
patchback[bot] 3e235f78d1
[PR #7999/0ded1109 backport][stable-8] feat(lookup/merge_variables): Add all hosts mode to collect configuration across multiple hosts (#8069)
feat(lookup/merge_variables): Add all hosts mode to collect configuration across multiple hosts (#7999)

* Add Feature to collect variables accross different hosts

* fix merging lists

* adjust unit tests

* lint fixes

* adjusting integration tests

* remove white spaces

* Update plugins/lookup/merge_variables.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/lookup/merge_variables.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/lookup/merge_variables.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* apply suggested changes to correctly handling the initial_value parameter, incl. additional test

* whitespace

---------

Co-authored-by: Alexander Petrenz <alexander.petrenz@posteo.de>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 0ded1109fe)

Co-authored-by: Alexander Petrenz <petrenz.a@gmail.com>
2024-03-09 12:42:22 +00:00

282 lines
12 KiB
Python

# -*- coding: utf-8 -*-
# Copyright (c) 2020, Thales Netherlands
# Copyright (c) 2021, Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible_collections.community.general.tests.unit.compat import unittest
from ansible_collections.community.general.tests.unit.compat.mock import patch
from ansible_collections.community.general.tests.unit.mock.loader import DictDataLoader
from ansible.plugins import AnsiblePlugin
from ansible.template import Templar
from ansible.errors import AnsibleError
from ansible.utils.display import Display
from ansible_collections.community.general.plugins.lookup import merge_variables
class TestMergeVariablesLookup(unittest.TestCase):
def setUp(self):
self.loader = DictDataLoader({})
self.templar = Templar(loader=self.loader, variables={})
self.merge_vars_lookup = merge_variables.LookupModule(loader=self.loader, templar=self.templar)
@patch.object(AnsiblePlugin, 'set_options')
@patch.object(AnsiblePlugin, 'get_option', side_effect=[None, 'ignore', 'suffix', None])
@patch.object(Templar, 'template', side_effect=[['item1'], ['item3']])
def test_merge_list(self, mock_set_options, mock_get_option, mock_template):
results = self.merge_vars_lookup.run(['__merge_list'], {
'testlist1__merge_list': ['item1'],
'testlist2': ['item2'],
'testlist3__merge_list': ['item3']
})
self.assertEqual(results, [['item1', 'item3']])
@patch.object(AnsiblePlugin, 'set_options')
@patch.object(AnsiblePlugin, 'get_option', side_effect=[['initial_item'], 'ignore', 'suffix', None])
@patch.object(Templar, 'template', side_effect=[['item1'], ['item3']])
def test_merge_list_with_initial_value(self, mock_set_options, mock_get_option, mock_template):
results = self.merge_vars_lookup.run(['__merge_list'], {
'testlist1__merge_list': ['item1'],
'testlist2': ['item2'],
'testlist3__merge_list': ['item3']
})
self.assertEqual(results, [['initial_item', 'item1', 'item3']])
@patch.object(AnsiblePlugin, 'set_options')
@patch.object(AnsiblePlugin, 'get_option', side_effect=[None, 'ignore', 'suffix', None])
@patch.object(Templar, 'template', side_effect=[{'item1': 'test', 'list_item': ['test1']},
{'item2': 'test', 'list_item': ['test2']}])
def test_merge_dict(self, mock_set_options, mock_get_option, mock_template):
results = self.merge_vars_lookup.run(['__merge_dict'], {
'testdict1__merge_dict': {
'item1': 'test',
'list_item': ['test1']
},
'testdict2__merge_dict': {
'item2': 'test',
'list_item': ['test2']
}
})
self.assertEqual(results, [
{
'item1': 'test',
'item2': 'test',
'list_item': ['test1', 'test2']
}
])
@patch.object(AnsiblePlugin, 'set_options')
@patch.object(AnsiblePlugin, 'get_option', side_effect=[{'initial_item': 'random value', 'list_item': ['test0']},
'ignore', 'suffix', None])
@patch.object(Templar, 'template', side_effect=[{'item1': 'test', 'list_item': ['test1']},
{'item2': 'test', 'list_item': ['test2']}])
def test_merge_dict_with_initial_value(self, mock_set_options, mock_get_option, mock_template):
results = self.merge_vars_lookup.run(['__merge_dict'], {
'testdict1__merge_dict': {
'item1': 'test',
'list_item': ['test1']
},
'testdict2__merge_dict': {
'item2': 'test',
'list_item': ['test2']
}
})
self.assertEqual(results, [
{
'initial_item': 'random value',
'item1': 'test',
'item2': 'test',
'list_item': ['test0', 'test1', 'test2']
}
])
@patch.object(AnsiblePlugin, 'set_options')
@patch.object(AnsiblePlugin, 'get_option', side_effect=[None, 'warn', 'suffix', None])
@patch.object(Templar, 'template', side_effect=[{'item': 'value1'}, {'item': 'value2'}])
@patch.object(Display, 'warning')
def test_merge_dict_non_unique_warning(self, mock_set_options, mock_get_option, mock_template, mock_display):
results = self.merge_vars_lookup.run(['__merge_non_unique'], {
'testdict1__merge_non_unique': {'item': 'value1'},
'testdict2__merge_non_unique': {'item': 'value2'}
})
self.assertTrue(mock_display.called)
self.assertEqual(results, [{'item': 'value2'}])
@patch.object(AnsiblePlugin, 'set_options')
@patch.object(AnsiblePlugin, 'get_option', side_effect=[None, 'error', 'suffix', None])
@patch.object(Templar, 'template', side_effect=[{'item': 'value1'}, {'item': 'value2'}])
def test_merge_dict_non_unique_error(self, mock_set_options, mock_get_option, mock_template):
with self.assertRaises(AnsibleError):
self.merge_vars_lookup.run(['__merge_non_unique'], {
'testdict1__merge_non_unique': {'item': 'value1'},
'testdict2__merge_non_unique': {'item': 'value2'}
})
@patch.object(AnsiblePlugin, 'set_options')
@patch.object(AnsiblePlugin, 'get_option', side_effect=[None, 'ignore', 'suffix', None])
@patch.object(Templar, 'template', side_effect=[{'item1': 'test', 'list_item': ['test1']},
['item2', 'item3']])
def test_merge_list_and_dict(self, mock_set_options, mock_get_option, mock_template):
with self.assertRaises(AnsibleError):
self.merge_vars_lookup.run(['__merge_var'], {
'testlist__merge_var': {
'item1': 'test',
'list_item': ['test1']
},
'testdict__merge_var': ['item2', 'item3']
})
@patch.object(AnsiblePlugin, 'set_options')
@patch.object(AnsiblePlugin, 'get_option', side_effect=[None, 'ignore', 'suffix', ['all']])
@patch.object(Templar, 'template', side_effect=[
{'var': [{'item1': 'value1', 'item2': 'value2'}]},
{'var': [{'item5': 'value5', 'item6': 'value6'}]},
])
def test_merge_dict_group_all(self, mock_set_options, mock_get_option, mock_template):
results = self.merge_vars_lookup.run(['__merge_var'], {
'inventory_hostname': 'host1',
'hostvars': {
'host1': {
'group_names': ['dummy1'],
'inventory_hostname': 'host1',
'1testlist__merge_var': {
'var': [{'item1': 'value1', 'item2': 'value2'}]
}
},
'host2': {
'group_names': ['dummy1'],
'inventory_hostname': 'host2',
'2otherlist__merge_var': {
'var': [{'item5': 'value5', 'item6': 'value6'}]
}
}
}
})
self.assertEqual(results, [
{'var': [
{'item1': 'value1', 'item2': 'value2'},
{'item5': 'value5', 'item6': 'value6'}
]}
])
@patch.object(AnsiblePlugin, 'set_options')
@patch.object(AnsiblePlugin, 'get_option', side_effect=[None, 'ignore', 'suffix', ['dummy1']])
@patch.object(Templar, 'template', side_effect=[
{'var': [{'item1': 'value1', 'item2': 'value2'}]},
{'var': [{'item5': 'value5', 'item6': 'value6'}]},
])
def test_merge_dict_group_single(self, mock_set_options, mock_get_option, mock_template):
results = self.merge_vars_lookup.run(['__merge_var'], {
'inventory_hostname': 'host1',
'hostvars': {
'host1': {
'group_names': ['dummy1'],
'inventory_hostname': 'host1',
'1testlist__merge_var': {
'var': [{'item1': 'value1', 'item2': 'value2'}]
}
},
'host2': {
'group_names': ['dummy1'],
'inventory_hostname': 'host2',
'2otherlist__merge_var': {
'var': [{'item5': 'value5', 'item6': 'value6'}]
}
},
'host3': {
'group_names': ['dummy2'],
'inventory_hostname': 'host3',
'3otherlist__merge_var': {
'var': [{'item3': 'value3', 'item4': 'value4'}]
}
}
}
})
self.assertEqual(results, [
{'var': [
{'item1': 'value1', 'item2': 'value2'},
{'item5': 'value5', 'item6': 'value6'}
]}
])
@patch.object(AnsiblePlugin, 'set_options')
@patch.object(AnsiblePlugin, 'get_option', side_effect=[None, 'ignore', 'suffix', ['dummy1', 'dummy2']])
@patch.object(Templar, 'template', side_effect=[
{'var': [{'item1': 'value1', 'item2': 'value2'}]},
{'var': [{'item5': 'value5', 'item6': 'value6'}]},
])
def test_merge_dict_group_multiple(self, mock_set_options, mock_get_option, mock_template):
results = self.merge_vars_lookup.run(['__merge_var'], {
'inventory_hostname': 'host1',
'hostvars': {
'host1': {
'group_names': ['dummy1'],
'inventory_hostname': 'host1',
'1testlist__merge_var': {
'var': [{'item1': 'value1', 'item2': 'value2'}]
}
},
'host2': {
'group_names': ['dummy2'],
'inventory_hostname': 'host2',
'2otherlist__merge_var': {
'var': [{'item5': 'value5', 'item6': 'value6'}]
}
},
'host3': {
'group_names': ['dummy3'],
'inventory_hostname': 'host3',
'3otherlist__merge_var': {
'var': [{'item3': 'value3', 'item4': 'value4'}]
}
}
}
})
self.assertEqual(results, [
{'var': [
{'item1': 'value1', 'item2': 'value2'},
{'item5': 'value5', 'item6': 'value6'}
]}
])
@patch.object(AnsiblePlugin, 'set_options')
@patch.object(AnsiblePlugin, 'get_option', side_effect=[None, 'ignore', 'suffix', ['dummy1', 'dummy2']])
@patch.object(Templar, 'template', side_effect=[
['item1'],
['item5'],
])
def test_merge_list_group_multiple(self, mock_set_options, mock_get_option, mock_template):
print()
results = self.merge_vars_lookup.run(['__merge_var'], {
'inventory_hostname': 'host1',
'hostvars': {
'host1': {
'group_names': ['dummy1'],
'inventory_hostname': 'host1',
'1testlist__merge_var': ['item1']
},
'host2': {
'group_names': ['dummy2'],
'inventory_hostname': 'host2',
'2otherlist__merge_var': ['item5']
},
'host3': {
'group_names': ['dummy3'],
'inventory_hostname': 'host3',
'3otherlist__merge_var': ['item3']
}
}
})
self.assertEqual(results, [['item1', 'item5']])