From 1cdfcf0bb9258fab51c6c6396cc4f609a4ce51b7 Mon Sep 17 00:00:00 2001 From: Ganesh Nalawade Date: Fri, 21 Apr 2017 18:23:40 +0530 Subject: [PATCH] Add junos_command module unit test (#23819) * Add junos_command module unit test --- test/units/modules/network/junos/__init__.py | 0 .../junos/fixtures/show_version_json.txt | 42 ++++++ .../junos/fixtures/show_version_text.txt | 8 ++ .../junos/fixtures/show_version_xml.txt | 12 ++ .../modules/network/junos/junos_module.py | 112 ++++++++++++++++ .../network/junos/test_junos_command.py | 123 ++++++++++++++++++ 6 files changed, 297 insertions(+) create mode 100644 test/units/modules/network/junos/__init__.py create mode 100644 test/units/modules/network/junos/fixtures/show_version_json.txt create mode 100644 test/units/modules/network/junos/fixtures/show_version_text.txt create mode 100644 test/units/modules/network/junos/fixtures/show_version_xml.txt create mode 100644 test/units/modules/network/junos/junos_module.py create mode 100644 test/units/modules/network/junos/test_junos_command.py diff --git a/test/units/modules/network/junos/__init__.py b/test/units/modules/network/junos/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/units/modules/network/junos/fixtures/show_version_json.txt b/test/units/modules/network/junos/fixtures/show_version_json.txt new file mode 100644 index 00000000000..eacfd12d988 --- /dev/null +++ b/test/units/modules/network/junos/fixtures/show_version_json.txt @@ -0,0 +1,42 @@ + +{ + "software-information" : [ + { + "host-name" : [ + { + "data" : "vsrx01" + } + ], + "product-model" : [ + { + "data" : "vSRX" + } + ], + "product-name" : [ + { + "data" : "vsrx" + } + ], + "junos-version" : [ + { + "data" : "15.1X49-D15.4" + } + ], + "package-information" : [ + { + "name" : [ + { + "data" : "junos" + } + ], + "comment" : [ + { + "data" : "JUNOS Software Release [15.1X49-D15.4]" + } + ] + } + ] + } + ] + } + \ No newline at end of file diff --git a/test/units/modules/network/junos/fixtures/show_version_text.txt b/test/units/modules/network/junos/fixtures/show_version_text.txt new file mode 100644 index 00000000000..81e0f3a8ba6 --- /dev/null +++ b/test/units/modules/network/junos/fixtures/show_version_text.txt @@ -0,0 +1,8 @@ + + + Hostname: vsrx01 + Model: vSRX + Junos: 15.1X49-D15.4 + JUNOS Software Release [15.1X49-D15.4] + + \ No newline at end of file diff --git a/test/units/modules/network/junos/fixtures/show_version_xml.txt b/test/units/modules/network/junos/fixtures/show_version_xml.txt new file mode 100644 index 00000000000..996c2a35953 --- /dev/null +++ b/test/units/modules/network/junos/fixtures/show_version_xml.txt @@ -0,0 +1,12 @@ + + + vsrx01 + vSRX + vsrx + 15.1X49-D15.4 + + junos + JUNOS Software Release [15.1X49-D15.4] + + + \ No newline at end of file diff --git a/test/units/modules/network/junos/junos_module.py b/test/units/modules/network/junos/junos_module.py new file mode 100644 index 00000000000..0bf12f68602 --- /dev/null +++ b/test/units/modules/network/junos/junos_module.py @@ -0,0 +1,112 @@ +# (c) 2017 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 . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import json + +import xml.etree.ElementTree as ET + +from ansible.compat.tests import unittest +from ansible.compat.tests.mock import patch +from ansible.module_utils import basic +from ansible.module_utils._text import to_bytes + + +def set_module_args(args): + args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) + basic._ANSIBLE_ARGS = to_bytes(args) + +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] + + try: + data = ET.parse(path).getroot() + except: + pass + + fixture_data[path] = data + return data + + +class AnsibleExitJson(Exception): + pass + + +class AnsibleFailJson(Exception): + pass + + +class TestJunosModule(unittest.TestCase): + + def execute_module(self, failed=False, changed=False, commands=None, sort=True, defaults=False, format='text'): + + self.load_fixtures(commands, format) + + if failed: + result = self.failed() + self.assertTrue(result['failed'], result) + else: + result = self.changed(changed) + self.assertEqual(result['changed'], changed, result) + + if commands: + if sort: + self.assertEqual(sorted(commands), sorted(result['commands']), result['commands']) + else: + self.assertEqual(commands, result['commands'], result['commands']) + + return result + + def failed(self): + def fail_json(*args, **kwargs): + kwargs['failed'] = True + raise AnsibleFailJson(kwargs) + + with patch.object(basic.AnsibleModule, 'fail_json', fail_json): + 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): + def exit_json(*args, **kwargs): + if 'changed' not in kwargs: + kwargs['changed'] = False + raise AnsibleExitJson(kwargs) + + with patch.object(basic.AnsibleModule, 'exit_json', exit_json): + 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/test/units/modules/network/junos/test_junos_command.py b/test/units/modules/network/junos/test_junos_command.py new file mode 100644 index 00000000000..707c47a6d25 --- /dev/null +++ b/test/units/modules/network/junos/test_junos_command.py @@ -0,0 +1,123 @@ +# (c) 2017 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 . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json + +from ansible.compat.tests.mock import patch, MagicMock +from ansible.modules.network.junos import junos_command +from .junos_module import TestJunosModule, load_fixture, set_module_args + +RPC_CLI_MAP = { + 'get-software-information': 'show version' +} + + +class TestJunosCommandModule(TestJunosModule): + + module = junos_command + + def setUp(self): + self.mock_send_request = patch('ansible.modules.network.junos.junos_command.send_request') + self.send_request = self.mock_send_request.start() + + def tearDown(self): + self.mock_send_request.stop() + + def load_fixtures(self, commands=None, format='text'): + def load_from_file(*args, **kwargs): + module, element = args + + if element.text: + path = str(element.text) + else: + path = RPC_CLI_MAP[str(element.tag)] + + filename = path.replace(' ', '_') + filename = '%s_%s.txt' % (filename, format) + return load_fixture(filename) + + self.send_request.side_effect = load_from_file + + def test_junos_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('Hostname:')) + + def test_junos_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('Hostname:')) + + def test_junos_command_wait_for(self): + wait_for = 'result[0] contains "Junos:"' + set_module_args(dict(commands=['show version'], wait_for=wait_for)) + self.execute_module() + + def test_junos_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.send_request.call_count, 10) + + def test_junos_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.send_request.call_count, 2) + + def test_junos_command_match_any(self): + wait_for = ['result[0] contains "Junos:"', + 'result[0] contains "test string"'] + set_module_args(dict(commands=['show version'], wait_for=wait_for, match='any')) + self.execute_module() + + def test_junos_command_match_all(self): + wait_for = ['result[0] contains "Junos:"', + 'result[0] contains "JUNOS Software Release"'] + set_module_args(dict(commands=['show version'], wait_for=wait_for, match='all')) + self.execute_module() + + def test_junos_command_match_all_failure(self): + wait_for = ['result[0] contains "Junos:"', + '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) + + def test_junos_command_simple_json(self): + set_module_args(dict(commands=['show version'], display='json')) + result = self.execute_module(format='json') + self.assertEqual(len(result['stdout']), 1) + self.assertTrue("software-information" in result['stdout'][0]) + + def test_junos_command_simple_rpc_text(self): + set_module_args(dict(rpcs=['get-software-information'], display='text')) + result = self.execute_module(format='text') + self.assertEqual(len(result['stdout']), 1) + self.assertTrue(result['stdout'][0].startswith('Hostname:')) + + def test_junos_command_simple_rpc_json(self): + set_module_args(dict(rpcs=['get-software-information'], display='json')) + result = self.execute_module(format='json') + self.assertEqual(len(result['stdout']), 1) + self.assertTrue("software-information" in result['stdout'][0])