diff --git a/test/units/modules/network/junos/__init__.py b/test/units/modules/network/junos/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
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 0000000000..eacfd12d98
--- /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 0000000000..81e0f3a8ba
--- /dev/null
+++ b/test/units/modules/network/junos/fixtures/show_version_text.txt
@@ -0,0 +1,8 @@
+
+
+
\ 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 0000000000..996c2a3595
--- /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 0000000000..0bf12f6860
--- /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 0000000000..707c47a6d2
--- /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])