summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Meyers <chrismeyersfsu@users.noreply.github.com>2017-10-16 18:52:44 -0400
committerMatt Clay <matt@mystile.com>2017-11-08 10:56:19 -0800
commitf00f2466d47852b2460f8f2efddc6a0f060ecc72 (patch)
tree362dcbe1860e34f58c9f96accb42bea7cf976b47
parent95bd052c4ed97e23e49186a5aeaeb0b0edc1d91e (diff)
downloadansible-f00f2466d47852b2460f8f2efddc6a0f060ecc72.tar.gz
tests for InventoryModule error conditions (#31381)
* tests for InventoryModule error conditions * modified unicode in tests to ahear to Ansible best practices * flake8 fixes (cherry picked from commit cf938e99926a384303c1e291e47770d8f9c74b85)
-rw-r--r--lib/ansible/plugins/inventory/script.py3
-rw-r--r--test/units/plugins/inventory/test_script.py104
2 files changed, 105 insertions, 2 deletions
diff --git a/lib/ansible/plugins/inventory/script.py b/lib/ansible/plugins/inventory/script.py
index cbc271e1ad..bf1d26812c 100644
--- a/lib/ansible/plugins/inventory/script.py
+++ b/lib/ansible/plugins/inventory/script.py
@@ -80,8 +80,7 @@ class InventoryModule(BaseInventoryPlugin):
(stdout, stderr) = sp.communicate()
path = to_native(path)
- if stderr:
- err = to_native(stderr) + "\n"
+ err = to_native(stderr or "") + "\n"
if sp.returncode != 0:
raise AnsibleError("Inventory script (%s) had an execution error: %s " % (path, err))
diff --git a/test/units/plugins/inventory/test_script.py b/test/units/plugins/inventory/test_script.py
new file mode 100644
index 0000000000..28429b3da1
--- /dev/null
+++ b/test/units/plugins/inventory/test_script.py
@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+
+# Copyright 2017 Chris Meyers <cmeyers@ansible.com>
+#
+# 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 pytest
+
+from ansible.errors import AnsibleError
+from ansible.compat.tests import mock
+from ansible.compat.tests import unittest
+from ansible.module_utils._text import to_bytes, to_native
+
+from ansible.plugins.inventory.script import InventoryModule
+
+
+class TestInventoryModule(unittest.TestCase):
+
+ def setUp(self):
+ class Inventory():
+ cache = dict()
+
+ class PopenResult():
+ returncode = 0
+ stdout = b""
+ stderr = b""
+
+ def communicate(self):
+ return (self.stdout, self.stderr)
+
+ self.popen_result = PopenResult()
+ self.inventory = Inventory()
+ self.loader = mock.MagicMock()
+ self.loader.load = mock.MagicMock()
+
+ def register_patch(name):
+ patcher = mock.patch(name)
+ self.addCleanup(patcher.stop)
+ return patcher.start()
+
+ self.popen = register_patch('subprocess.Popen')
+ self.popen.return_value = self.popen_result
+
+ self.BaseInventoryPlugin = register_patch('ansible.plugins.inventory.BaseInventoryPlugin')
+ self.BaseInventoryPlugin.get_cache_prefix.return_value = 'abc123'
+
+ def test_parse_subprocess_path_not_found_fail(self):
+ self.popen.side_effect = OSError("dummy text")
+
+ inventory_module = InventoryModule()
+ with pytest.raises(AnsibleError) as e:
+ inventory_module.parse(self.inventory, self.loader, '/foo/bar/foobar.py')
+ assert e.value.message == "problem running /foo/bar/foobar.py --list (dummy text)"
+
+ def test_parse_subprocess_err_code_fail(self):
+ self.popen_result.stdout = to_bytes(u"fooébar", errors='surrogate_escape')
+ self.popen_result.stderr = to_bytes(u"dummyédata")
+
+ self.popen_result.returncode = 1
+
+ inventory_module = InventoryModule()
+ with pytest.raises(AnsibleError) as e:
+ inventory_module.parse(self.inventory, self.loader, '/foo/bar/foobar.py')
+ assert e.value.message == to_native("Inventory script (/foo/bar/foobar.py) had an execution error: "
+ "dummyédata\n ")
+
+ def test_parse_utf8_fail(self):
+ self.popen_result.returncode = 0
+ self.popen_result.stderr = to_bytes("dummyédata")
+ self.loader.load.side_effect = TypeError('obj must be string')
+
+ inventory_module = InventoryModule()
+ with pytest.raises(AnsibleError) as e:
+ inventory_module.parse(self.inventory, self.loader, '/foo/bar/foobar.py')
+ assert e.value.message == to_native("failed to parse executable inventory script results from "
+ "/foo/bar/foobar.py: obj must be string\ndummyédata\n")
+
+ def test_parse_dict_fail(self):
+ self.popen_result.returncode = 0
+ self.popen_result.stderr = to_bytes("dummyédata")
+ self.loader.load.return_value = 'i am not a dict'
+
+ inventory_module = InventoryModule()
+ with pytest.raises(AnsibleError) as e:
+ inventory_module.parse(self.inventory, self.loader, '/foo/bar/foobar.py')
+ assert e.value.message == to_native("failed to parse executable inventory script results from "
+ "/foo/bar/foobar.py: needs to be a json dict\ndummyédata\n")