diff options
Diffstat (limited to 'tests/unit/modules')
24 files changed, 1152 insertions, 0 deletions
diff --git a/tests/unit/modules/__init__.py b/tests/unit/modules/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/unit/modules/__init__.py diff --git a/tests/unit/modules/conftest.py b/tests/unit/modules/conftest.py new file mode 100644 index 0000000..ac56c9c --- /dev/null +++ b/tests/unit/modules/conftest.py @@ -0,0 +1,37 @@ +# Copyright (c) 2017 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +import json + +import pytest + +from ansible.module_utils.six import string_types +from ansible.module_utils._text import to_bytes +from ansible.module_utils.common._collections_compat import MutableMapping + + +@pytest.fixture +def patch_ansible_module(request, mocker): + if isinstance(request.param, string_types): + args = request.param + elif isinstance(request.param, MutableMapping): + if "ANSIBLE_MODULE_ARGS" not in request.param: + request.param = {"ANSIBLE_MODULE_ARGS": request.param} + if "_ansible_remote_tmp" not in request.param["ANSIBLE_MODULE_ARGS"]: + request.param["ANSIBLE_MODULE_ARGS"][ + "_ansible_remote_tmp" + ] = "/tmp" + if ( + "_ansible_keep_remote_files" + not in request.param["ANSIBLE_MODULE_ARGS"] + ): + request.param["ANSIBLE_MODULE_ARGS"][ + "_ansible_keep_remote_files" + ] = False + args = json.dumps(request.param) + else: + raise Exception( + "Malformed data to the patch_ansible_module pytest fixture" + ) + + mocker.patch("ansible.module_utils.basic._ANSIBLE_ARGS", to_bytes(args)) diff --git a/tests/unit/modules/network/__init__.py b/tests/unit/modules/network/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/unit/modules/network/__init__.py diff --git a/tests/unit/modules/network/vyos/__init__.py b/tests/unit/modules/network/vyos/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/unit/modules/network/vyos/__init__.py diff --git a/tests/unit/modules/network/vyos/fixtures/__init__.py b/tests/unit/modules/network/vyos/fixtures/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/__init__.py diff --git a/tests/unit/modules/network/vyos/fixtures/show_host_name b/tests/unit/modules/network/vyos/fixtures/show_host_name new file mode 100644 index 0000000..e89bc06 --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/show_host_name @@ -0,0 +1 @@ +vyos01 diff --git a/tests/unit/modules/network/vyos/fixtures/show_version b/tests/unit/modules/network/vyos/fixtures/show_version new file mode 100644 index 0000000..a015d55 --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/show_version @@ -0,0 +1,14 @@ +Version: VyOS 1.1.7 +Description: VyOS 1.1.7 (helium) +Copyright: 2016 VyOS maintainers and contributors +Built by: maintainers@vyos.net +Built on: Wed Feb 17 09:57:31 UTC 2016 +Build ID: 1602170957-4459750 +System type: x86 64-bit +Boot via: image +Hypervisor: VMware +HW model: VMware Virtual Platform +HW S/N: VMware-42 3c 26 25 44 c5 0a 91-cf 2c 97 2b fe 9b 25 be +HW UUID: 423C2625-44C5-0A91-CF2C-972BFE9B25BE +Uptime: 01:08:20 up 52 days, 2:13, 1 user, load average: 0.00, 0.01, 0.05 + diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_config_config.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_config_config.cfg new file mode 100644 index 0000000..fcef8eb --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_config_config.cfg @@ -0,0 +1,10 @@ +set system host-name 'router' +set system domain-name 'example.com' +set system domain-search domain 'example.com' +set system name-server '8.8.8.8' +set system name-server '8.8.4.4' +set interfaces ethernet eth0 address '1.2.3.4/24' +set interfaces ethernet eth0 description 'test string' +set interfaces ethernet eth1 address '6.7.8.9/24' +set interfaces ethernet eth1 description 'test string' +set interfaces ethernet eth1 disable diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_config_src.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_config_src.cfg new file mode 100644 index 0000000..410f611 --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_config_src.cfg @@ -0,0 +1,6 @@ +set system host-name foo + +delete interfaces ethernet eth0 address +set interfaces ethernet eth1 address '6.7.8.9/24' + set interfaces ethernet eth1 description 'test string' +set interfaces ethernet eth1 disable diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_config_src_brackets.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_config_src_brackets.cfg new file mode 100644 index 0000000..468b32c --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_config_src_brackets.cfg @@ -0,0 +1,13 @@ +interfaces { + ethernet eth0 { + address 10.10.10.10/24 + } + ethernet eth1 { + address 6.7.8.9/24 + description test string + disable + } +} +system { + host-name foo +} diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.10_count_2 b/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.10_count_2 new file mode 100644 index 0000000..c28fba1 --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.10_count_2 @@ -0,0 +1,7 @@ +PING 10.10.10.10 (10.10.10.10) 56(84) bytes of data. +64 bytes from 10.10.10.10: icmp_req=1 ttl=255 time=1.27 ms +64 bytes from 10.10.10.10: icmp_req=2 ttl=255 time=2.28 ms + +--- 10.8.38.66 ping statistics --- +2 packets transmitted, 2 received, 0% packet loss, time 1001ms +rtt min/avg/max/mdev = 12.1222/17.124/22.225/10.143 ms diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.11_count_10_ttl_128_size_512 b/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.11_count_10_ttl_128_size_512 new file mode 100644 index 0000000..54e026c --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.11_count_10_ttl_128_size_512 @@ -0,0 +1,15 @@ +PING 10.10.10.11 (10.8.38.65) 512(540) bytes of data. +520 bytes from 10.10.10.11: icmp_req=1 ttl=255 time=1.17 ms +520 bytes from 10.10.10.11: icmp_req=2 ttl=255 time=1.32 ms +520 bytes from 10.10.10.11: icmp_req=3 ttl=255 time=1.21 ms +520 bytes from 10.10.10.11: icmp_req=4 ttl=255 time=1.46 ms +520 bytes from 10.10.10.11: icmp_req=5 ttl=255 time=1.32 ms +520 bytes from 10.10.10.11: icmp_req=6 ttl=255 time=1.28 ms +520 bytes from 10.10.10.11: icmp_req=7 ttl=255 time=1.25 ms +520 bytes from 10.10.10.11: icmp_req=8 ttl=255 time=1.23 ms +520 bytes from 10.10.10.11: icmp_req=9 ttl=255 time=1.34 ms +520 bytes from 10.10.10.11: icmp_req=10 ttl=255 time=21.0 ms + +--- 10.10.10.11 ping statistics --- +10 packets transmitted, 10 received, 0% packet loss, time 9012ms +rtt min/avg/max/mdev = 1.170/3.262/21.002/5.913 ms diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.20_count_4 b/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.20_count_4 new file mode 100644 index 0000000..08e6181 --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.20_count_4 @@ -0,0 +1,9 @@ +PING 10.10.10.20 (10.10.10.20) 56(84) bytes of data. +From 10.10.10.20 icmp_seq=1 Destination Host Unreachable +From 10.10.10.20 icmp_seq=2 Destination Host Unreachable +From 10.10.10.20 icmp_seq=3 Destination Host Unreachable +From 10.10.10.20 icmp_seq=4 Destination Host Unreachable + +--- 10.10.10.20 ping statistics --- +4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3053ms +pipe 3 diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_user_config.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_user_config.cfg new file mode 100644 index 0000000..81cd1a4 --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_user_config.cfg @@ -0,0 +1,2 @@ +set system login user admin level operator authentication encrypted-password '$6$V5oWW3JM9NFAwOG$P2L4raFvIrZjjs3g0qmH4Ns5ti7flRpSs6aEqy4TrGZYXGeBiYzwi2A6jy' +set system login user ansible level operator authentication encrypted-password '$6$ZfvSv6A50W6yNPYX$4HP5eg2sywcXYxTqhApQ7zvUvx0HsQHrI9xuJoFLy2gM/' diff --git a/tests/unit/modules/network/vyos/test_vyos_banner.py b/tests/unit/modules/network/vyos/test_vyos_banner.py new file mode 100644 index 0000000..c575409 --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_banner.py @@ -0,0 +1,63 @@ +# 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 <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +from ansible_collections.vyos.vyos.tests.unit.compat.mock import patch +from ansible_collections.vyos.vyos.plugins.modules import vyos_banner +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule + + +class TestVyosBannerModule(TestVyosModule): + + module = vyos_banner + + def setUp(self): + super(TestVyosBannerModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_banner.get_config" + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_banner.load_config" + ) + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestVyosBannerModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None): + self.load_config.return_value = dict(diff=None, session="session") + + def test_vyos_banner_create(self): + set_module_args(dict(banner="pre-login", text="test\nbanner\nstring")) + commands = [ + "set system login banner pre-login 'test\\nbanner\\nstring'" + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_banner_remove(self): + set_module_args(dict(banner="pre-login", state="absent")) + self.execute_module(changed=False, commands=[]) diff --git a/tests/unit/modules/network/vyos/test_vyos_command.py b/tests/unit/modules/network/vyos/test_vyos_command.py new file mode 100644 index 0000000..820c6c4 --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_command.py @@ -0,0 +1,122 @@ +# (c) 2016 Red Hat Inc. +# +# 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 <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +from ansible_collections.vyos.vyos.tests.unit.compat.mock import patch +from ansible_collections.vyos.vyos.plugins.modules import vyos_command +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule, load_fixture + + +class TestVyosCommandModule(TestVyosModule): + + module = vyos_command + + def setUp(self): + super(TestVyosCommandModule, self).setUp() + self.mock_run_commands = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_command.run_commands" + ) + self.run_commands = self.mock_run_commands.start() + + def tearDown(self): + super(TestVyosCommandModule, self).tearDown() + self.mock_run_commands.stop() + + def load_fixtures(self, commands=None): + def load_from_file(*args, **kwargs): + module, commands = args + output = list() + + for item in commands: + try: + command = item["command"] + except ValueError: + command = item + filename = str(command).replace(" ", "_") + output.append(load_fixture(filename)) + return output + + self.run_commands.side_effect = load_from_file + + def test_vyos_command_simple(self): + set_module_args(dict(commands=["show version"])) + result = self.execute_module() + self.assertEqual(len(result["stdout"]), 1) + self.assertTrue(result["stdout"][0].startswith("Version: VyOS")) + + def test_vyos_command_multiple(self): + set_module_args(dict(commands=["show version", "show version"])) + result = self.execute_module() + self.assertEqual(len(result["stdout"]), 2) + self.assertTrue(result["stdout"][0].startswith("Version: VyOS")) + + def test_vyos_command_wait_for(self): + wait_for = 'result[0] contains "VyOS maintainers"' + set_module_args(dict(commands=["show version"], wait_for=wait_for)) + self.execute_module() + + def test_vyos_command_wait_for_fails(self): + wait_for = 'result[0] contains "test string"' + set_module_args(dict(commands=["show version"], wait_for=wait_for)) + self.execute_module(failed=True) + self.assertEqual(self.run_commands.call_count, 10) + + def test_vyos_command_retries(self): + wait_for = 'result[0] contains "test string"' + set_module_args( + dict(commands=["show version"], wait_for=wait_for, retries=2) + ) + self.execute_module(failed=True) + self.assertEqual(self.run_commands.call_count, 2) + + def test_vyos_command_match_any(self): + wait_for = [ + 'result[0] contains "VyOS maintainers"', + 'result[0] contains "test string"', + ] + set_module_args( + dict(commands=["show version"], wait_for=wait_for, match="any") + ) + self.execute_module() + + def test_vyos_command_match_all(self): + wait_for = [ + 'result[0] contains "VyOS maintainers"', + 'result[0] contains "maintainers@vyos.net"', + ] + set_module_args( + dict(commands=["show version"], wait_for=wait_for, match="all") + ) + self.execute_module() + + def test_vyos_command_match_all_failure(self): + wait_for = [ + 'result[0] contains "VyOS maintainers"', + 'result[0] contains "test string"', + ] + commands = ["show version", "show version"] + set_module_args( + dict(commands=commands, wait_for=wait_for, match="all") + ) + self.execute_module(failed=True) diff --git a/tests/unit/modules/network/vyos/test_vyos_config.py b/tests/unit/modules/network/vyos/test_vyos_config.py new file mode 100644 index 0000000..a471edd --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_config.py @@ -0,0 +1,159 @@ +# +# (c) 2016 Red Hat Inc. +# +# 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 <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +from ansible_collections.vyos.vyos.tests.unit.compat.mock import ( + patch, + MagicMock, +) +from ansible_collections.vyos.vyos.plugins.modules import vyos_config +from ansible_collections.vyos.vyos.plugins.cliconf.vyos import Cliconf +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule, load_fixture + + +class TestVyosConfigModule(TestVyosModule): + + module = vyos_config + + def setUp(self): + super(TestVyosConfigModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_config.get_config" + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_config.load_config" + ) + self.load_config = self.mock_load_config.start() + + self.mock_run_commands = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_config.run_commands" + ) + self.run_commands = self.mock_run_commands.start() + + self.mock_get_connection = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_config.get_connection" + ) + self.get_connection = self.mock_get_connection.start() + + self.cliconf_obj = Cliconf(MagicMock()) + self.running_config = load_fixture("vyos_config_config.cfg") + + self.conn = self.get_connection() + self.conn.edit_config = MagicMock() + self.running_config = load_fixture("vyos_config_config.cfg") + + def tearDown(self): + super(TestVyosConfigModule, self).tearDown() + + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_run_commands.stop() + self.mock_get_connection.stop() + + def load_fixtures(self, commands=None): + config_file = "vyos_config_config.cfg" + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_vyos_config_unchanged(self): + src = load_fixture("vyos_config_config.cfg") + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff(src, src) + ) + set_module_args(dict(src=src)) + self.execute_module() + + def test_vyos_config_src(self): + src = load_fixture("vyos_config_src.cfg") + set_module_args(dict(src=src)) + candidate = "\n".join(self.module.format_commands(src.splitlines())) + commands = [ + "set system host-name foo", + "delete interfaces ethernet eth0 address", + ] + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff( + candidate, self.running_config + ) + ) + self.execute_module(changed=True, commands=commands) + + def test_vyos_config_src_brackets(self): + src = load_fixture("vyos_config_src_brackets.cfg") + set_module_args(dict(src=src)) + candidate = "\n".join(self.module.format_commands(src.splitlines())) + commands = [ + "set interfaces ethernet eth0 address 10.10.10.10/24", + "set system host-name foo", + ] + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff( + candidate, self.running_config + ) + ) + self.execute_module(changed=True, commands=commands) + + def test_vyos_config_backup(self): + set_module_args(dict(backup=True)) + result = self.execute_module() + self.assertIn("__backup__", result) + + def test_vyos_config_lines(self): + commands = ["set system host-name foo"] + set_module_args(dict(lines=commands)) + candidate = "\n".join(commands) + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff( + candidate, self.running_config + ) + ) + self.execute_module(changed=True, commands=commands) + + def test_vyos_config_config(self): + config = "set system host-name localhost" + new_config = ["set system host-name router"] + set_module_args(dict(lines=new_config, config=config)) + candidate = "\n".join(new_config) + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff(candidate, config) + ) + self.execute_module(changed=True, commands=new_config) + + def test_vyos_config_match_none(self): + lines = [ + "set system interfaces ethernet eth0 address 1.2.3.4/24", + "set system interfaces ethernet eth0 description test string", + ] + set_module_args(dict(lines=lines, match="none")) + candidate = "\n".join(lines) + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff( + candidate, None, diff_match="none" + ) + ) + self.execute_module(changed=True, commands=lines, sort=False) diff --git a/tests/unit/modules/network/vyos/test_vyos_facts.py b/tests/unit/modules/network/vyos/test_vyos_facts.py new file mode 100644 index 0000000..b22a523 --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_facts.py @@ -0,0 +1,109 @@ +# (c) 2016 Red Hat Inc. +# +# 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 <http://www.gnu.org/licenses/>. +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + +__metaclass__ = type +import json +from ansible_collections.vyos.vyos.tests.unit.compat.mock import patch +from ansible_collections.vyos.vyos.plugins.modules import vyos_facts +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule, load_fixture + + +class TestVyosFactsModule(TestVyosModule): + module = vyos_facts + + def setUp(self): + super(TestVyosFactsModule, self).setUp() + self.mock_run_commands = patch( + "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.legacy.base.run_commands" + ) + self.run_commands = self.mock_run_commands.start() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection" + ) + self.get_resource_connection = ( + self.mock_get_resource_connection.start() + ) + + self.mock_get_capabilities = patch( + "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.legacy.base.get_capabilities" + ) + self.get_capabilities = self.mock_get_capabilities.start() + self.get_capabilities.return_value = { + "device_info": { + "network_os": "vyos", + "network_os_hostname": "vyos01", + "network_os_model": "VMware", + "network_os_version": "VyOS 1.1.7", + }, + "network_api": "cliconf", + } + + def tearDown(self): + super(TestVyosFactsModule, self).tearDown() + self.mock_run_commands.stop() + self.mock_get_capabilities.stop() + self.mock_get_resource_connection.stop() + + def load_fixtures(self, commands=None): + def load_from_file(*args, **kwargs): + module, commands = args + output = list() + for item in commands: + try: + obj = json.loads(item) + command = obj["command"] + except ValueError: + command = item + filename = str(command).replace(" ", "_") + output.append(load_fixture(filename)) + return output + + self.run_commands.side_effect = load_from_file + + def test_vyos_facts_default(self): + set_module_args(dict(gather_subset="default")) + result = self.execute_module() + facts = result.get("ansible_facts") + self.assertEqual(len(facts), 10) + self.assertEqual(facts["ansible_net_hostname"].strip(), "vyos01") + self.assertEqual(facts["ansible_net_version"], "VyOS 1.1.7") + + def test_vyos_facts_not_all(self): + set_module_args(dict(gather_subset="!all")) + result = self.execute_module() + facts = result.get("ansible_facts") + self.assertEqual(len(facts), 10) + self.assertEqual(facts["ansible_net_hostname"].strip(), "vyos01") + self.assertEqual(facts["ansible_net_version"], "VyOS 1.1.7") + + def test_vyos_facts_exclude_most(self): + set_module_args(dict(gather_subset=["!neighbors", "!config"])) + result = self.execute_module() + facts = result.get("ansible_facts") + self.assertEqual(len(facts), 10) + self.assertEqual(facts["ansible_net_hostname"].strip(), "vyos01") + self.assertEqual(facts["ansible_net_version"], "VyOS 1.1.7") + + def test_vyos_facts_invalid_subset(self): + set_module_args(dict(gather_subset="cereal")) + self.execute_module(failed=True) diff --git a/tests/unit/modules/network/vyos/test_vyos_ping.py b/tests/unit/modules/network/vyos/test_vyos_ping.py new file mode 100644 index 0000000..e307610 --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_ping.py @@ -0,0 +1,107 @@ +# (c) 2016 Red Hat Inc. +# +# 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 <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +from ansible_collections.vyos.vyos.tests.unit.compat.mock import patch +from ansible_collections.vyos.vyos.plugins.modules import vyos_ping +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule, load_fixture + + +class TestVyosPingModule(TestVyosModule): + + module = vyos_ping + + def setUp(self): + super(TestVyosPingModule, self).setUp() + self.mock_run_commands = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_ping.run_commands" + ) + self.run_commands = self.mock_run_commands.start() + + def tearDown(self): + super(TestVyosPingModule, self).tearDown() + self.mock_run_commands.stop() + + def load_fixtures(self, commands=None): + def load_from_file(*args, **kwargs): + commands = kwargs["commands"] + output = list() + + for command in commands: + filename = str(command).split(" | ")[0].replace(" ", "_") + output.append(load_fixture("vyos_ping_%s" % filename)) + return output + + self.run_commands.side_effect = load_from_file + + def test_vyos_ping_expected_success(self): + """ Test for successful pings when destination should be reachable """ + set_module_args(dict(count=2, dest="10.10.10.10")) + self.execute_module() + + def test_vyos_ping_expected_failure(self): + """ Test for unsuccessful pings when destination should not be reachable """ + set_module_args(dict(count=4, dest="10.10.10.20", state="absent")) + self.execute_module() + + def test_vyos_ping_unexpected_success(self): + """ Test for successful pings when destination should not be reachable - FAIL. """ + set_module_args(dict(count=2, dest="10.10.10.10", state="absent")) + self.execute_module(failed=True) + + def test_vyos_ping_unexpected_failure(self): + """ Test for unsuccessful pings when destination should be reachable - FAIL. """ + set_module_args(dict(count=4, dest="10.10.10.20")) + self.execute_module(failed=True) + + def test_vyos_ping_failure_stats(self): + """Test for asserting stats when ping fails""" + set_module_args(dict(count=4, dest="10.10.10.20")) + result = self.execute_module(failed=True) + self.assertEqual(result["packet_loss"], "100%") + self.assertEqual(result["packets_rx"], 0) + self.assertEqual(result["packets_tx"], 4) + + def test_vyos_ping_success_stats(self): + """Test for asserting stats when ping passes""" + set_module_args(dict(count=2, dest="10.10.10.10")) + result = self.execute_module() + self.assertEqual(result["packet_loss"], "0%") + self.assertEqual(result["packets_rx"], 2) + self.assertEqual(result["packets_tx"], 2) + self.assertEqual(result["rtt"]["min"], 12) + self.assertEqual(result["rtt"]["avg"], 17) + self.assertEqual(result["rtt"]["max"], 22) + self.assertEqual(result["rtt"]["mdev"], 10) + + def test_vyos_ping_success_stats_with_options(self): + set_module_args(dict(count=10, ttl=128, size=512, dest="10.10.10.11")) + result = self.execute_module() + self.assertEqual(result["packet_loss"], "0%") + self.assertEqual(result["packets_rx"], 10) + self.assertEqual(result["packets_tx"], 10) + self.assertEqual(result["rtt"]["min"], 1) + self.assertEqual(result["rtt"]["avg"], 3) + self.assertEqual(result["rtt"]["max"], 21) + self.assertEqual(result["rtt"]["mdev"], 5) diff --git a/tests/unit/modules/network/vyos/test_vyos_static_route.py b/tests/unit/modules/network/vyos/test_vyos_static_route.py new file mode 100644 index 0000000..e020ca5 --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_static_route.py @@ -0,0 +1,71 @@ +# (c) 2016 Red Hat Inc. +# +# 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 <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +from ansible_collections.vyos.vyos.tests.unit.compat.mock import patch +from ansible_collections.vyos.vyos.plugins.modules import vyos_static_route +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule + + +class TestVyosStaticRouteModule(TestVyosModule): + + module = vyos_static_route + + def setUp(self): + super(TestVyosStaticRouteModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_static_route.get_config" + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_static_route.load_config" + ) + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestVyosStaticRouteModule, self).tearDown() + + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport="cli"): + self.load_config.return_value = dict(diff=None, session="session") + + def test_vyos_static_route_present(self): + set_module_args( + dict( + prefix="172.26.0.0/16", + next_hop="172.26.4.1", + admin_distance="1", + ) + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "set protocols static route 172.26.0.0/16 next-hop 172.26.4.1 distance 1" + ], + ) diff --git a/tests/unit/modules/network/vyos/test_vyos_system.py b/tests/unit/modules/network/vyos/test_vyos_system.py new file mode 100644 index 0000000..c22f7c1 --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_system.py @@ -0,0 +1,116 @@ +# (c) 2016 Red Hat Inc. +# +# 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 <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +from ansible_collections.vyos.vyos.tests.unit.compat.mock import patch +from ansible_collections.vyos.vyos.plugins.modules import vyos_system +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule, load_fixture + + +class TestVyosSystemModule(TestVyosModule): + + module = vyos_system + + def setUp(self): + super(TestVyosSystemModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_system.get_config" + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_system.load_config" + ) + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestVyosSystemModule, self).tearDown() + + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None): + self.get_config.return_value = load_fixture("vyos_config_config.cfg") + + def test_vyos_system_hostname(self): + set_module_args(dict(host_name="foo")) + commands = ["set system host-name 'foo'"] + self.execute_module(changed=True, commands=commands) + + def test_vyos_system_clear_hostname(self): + set_module_args(dict(host_name="foo", state="absent")) + commands = ["delete system host-name"] + self.execute_module(changed=True, commands=commands) + + def test_vyos_remove_single_name_server(self): + set_module_args(dict(name_server=["8.8.4.4"], state="absent")) + commands = ["delete system name-server '8.8.4.4'"] + self.execute_module(changed=True, commands=commands) + + def test_vyos_system_domain_name(self): + set_module_args(dict(domain_name="example2.com")) + commands = ["set system domain-name 'example2.com'"] + self.execute_module(changed=True, commands=commands) + + def test_vyos_system_clear_domain_name(self): + set_module_args(dict(domain_name="example.com", state="absent")) + commands = ["delete system domain-name"] + self.execute_module(changed=True, commands=commands) + + def test_vyos_system_domain_search(self): + set_module_args( + dict(domain_search=["foo.example.com", "bar.example.com"]) + ) + commands = [ + "set system domain-search domain 'foo.example.com'", + "set system domain-search domain 'bar.example.com'", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_system_clear_domain_search(self): + set_module_args(dict(domain_search=[])) + commands = ["delete system domain-search domain"] + self.execute_module(changed=True, commands=commands) + + def test_vyos_system_no_change(self): + set_module_args( + dict( + host_name="router", + domain_name="example.com", + name_server=["8.8.8.8", "8.8.4.4"], + ) + ) + result = self.execute_module() + self.assertEqual([], result["commands"]) + + def test_vyos_system_clear_all(self): + set_module_args(dict(state="absent")) + commands = [ + "delete system host-name", + "delete system domain-search domain", + "delete system domain-name", + "delete system name-server", + ] + self.execute_module(changed=True, commands=commands) diff --git a/tests/unit/modules/network/vyos/test_vyos_user.py b/tests/unit/modules/network/vyos/test_vyos_user.py new file mode 100644 index 0000000..d4c2dbe --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_user.py @@ -0,0 +1,139 @@ +# (c) 2016 Red Hat Inc. +# +# 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 <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +from ansible_collections.vyos.vyos.tests.unit.compat.mock import patch +from ansible_collections.vyos.vyos.plugins.modules import vyos_user +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule, load_fixture + + +class TestVyosUserModule(TestVyosModule): + + module = vyos_user + + def setUp(self): + super(TestVyosUserModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_user.get_config" + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_user.load_config" + ) + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestVyosUserModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport="cli"): + self.get_config.return_value = load_fixture("vyos_user_config.cfg") + self.load_config.return_value = dict(diff=None, session="session") + + def test_vyos_user_password(self): + set_module_args(dict(name="ansible", configured_password="test")) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "set system login user ansible authentication plaintext-password test" + ], + ) + + def test_vyos_user_delete(self): + set_module_args(dict(name="ansible", state="absent")) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], ["delete system login user ansible"] + ) + + def test_vyos_user_level(self): + set_module_args(dict(name="ansible", level="operator")) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + ["set system login user ansible level operator"], + ) + + def test_vyos_user_level_invalid(self): + set_module_args(dict(name="ansible", level="sysadmin")) + self.execute_module(failed=True) + + def test_vyos_user_purge(self): + set_module_args(dict(purge=True)) + result = self.execute_module(changed=True) + self.assertEqual( + sorted(result["commands"]), + sorted( + [ + "delete system login user ansible", + "delete system login user admin", + ] + ), + ) + + def test_vyos_user_update_password_changed(self): + set_module_args( + dict( + name="test", + configured_password="test", + update_password="on_create", + ) + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "set system login user test authentication plaintext-password test" + ], + ) + + def test_vyos_user_update_password_on_create_ok(self): + set_module_args( + dict( + name="ansible", + configured_password="test", + update_password="on_create", + ) + ) + self.execute_module() + + def test_vyos_user_update_password_always(self): + set_module_args( + dict( + name="ansible", + configured_password="test", + update_password="always", + ) + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "set system login user ansible authentication plaintext-password test" + ], + ) diff --git a/tests/unit/modules/network/vyos/vyos_module.py b/tests/unit/modules/network/vyos/vyos_module.py new file mode 100644 index 0000000..fb15c71 --- /dev/null +++ b/tests/unit/modules/network/vyos/vyos_module.py @@ -0,0 +1,104 @@ +# (c) 2016 Red Hat Inc. +# +# 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 <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +import os +import json + +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + AnsibleExitJson, + AnsibleFailJson, + ModuleTestCase, +) + + +fixture_path = os.path.join(os.path.dirname(__file__), "fixtures") +fixture_data = {} + + +def load_fixture(name): + path = os.path.join(fixture_path, name) + + if path in fixture_data: + return fixture_data[path] + + with open(path) as f: + data = f.read() + + try: + data = json.loads(data) + except Exception: + pass + + fixture_data[path] = data + return data + + +class TestVyosModule(ModuleTestCase): + def execute_module( + self, + failed=False, + changed=False, + commands=None, + sort=True, + defaults=False, + ): + self.load_fixtures(commands) + + if failed: + result = self.failed() + self.assertTrue(result["failed"], result) + else: + result = self.changed(changed) + self.assertEqual(result["changed"], changed, result) + + if commands is not None: + if sort: + self.assertEqual( + sorted(commands), + sorted(result["commands"]), + result["commands"], + ) + else: + self.assertEqual( + commands, result["commands"], result["commands"] + ) + + return result + + def failed(self): + with self.assertRaises(AnsibleFailJson) as exc: + self.module.main() + + result = exc.exception.args[0] + self.assertTrue(result["failed"], result) + return result + + def changed(self, changed=False): + with self.assertRaises(AnsibleExitJson) as exc: + self.module.main() + + result = exc.exception.args[0] + self.assertEqual(result["changed"], changed, result) + return result + + def load_fixtures(self, commands=None): + pass diff --git a/tests/unit/modules/utils.py b/tests/unit/modules/utils.py new file mode 100644 index 0000000..2c9c602 --- /dev/null +++ b/tests/unit/modules/utils.py @@ -0,0 +1,48 @@ +import json + +from ansible_collections.vyos.vyos.tests.unit.compat import unittest +from ansible_collections.vyos.vyos.tests.unit.compat.mock import patch +from ansible.module_utils import basic +from ansible.module_utils._text import to_bytes + + +def set_module_args(args): + if "_ansible_remote_tmp" not in args: + args["_ansible_remote_tmp"] = "/tmp" + if "_ansible_keep_remote_files" not in args: + args["_ansible_keep_remote_files"] = False + + args = json.dumps({"ANSIBLE_MODULE_ARGS": args}) + basic._ANSIBLE_ARGS = to_bytes(args) + + +class AnsibleExitJson(Exception): + pass + + +class AnsibleFailJson(Exception): + pass + + +def exit_json(*args, **kwargs): + if "changed" not in kwargs: + kwargs["changed"] = False + raise AnsibleExitJson(kwargs) + + +def fail_json(*args, **kwargs): + kwargs["failed"] = True + raise AnsibleFailJson(kwargs) + + +class ModuleTestCase(unittest.TestCase): + def setUp(self): + self.mock_module = patch.multiple( + basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json + ) + self.mock_module.start() + self.mock_sleep = patch("time.sleep") + self.mock_sleep.start() + set_module_args({}) + self.addCleanup(self.mock_module.stop) + self.addCleanup(self.mock_sleep.stop) |