From 472028c869669dc05abd110ba8a335326c13ba8c Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Tue, 7 Dec 2021 09:11:06 -0500 Subject: [PATCH] catch the case that cowsay is broken (#76326) * catch the case that cowsay is broken fixes https://github.com/ansible/ansible/issues/72582 add changelog raise Exception for broken cowsay add test for broken cowsay Co-authored-by: Matthias Bernt --- .../fragments/72592-catch-broken-cowsay.yaml | 2 ++ lib/ansible/utils/display.py | 4 ++- .../units/utils/display/test_broken_cowsay.py | 27 +++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/72592-catch-broken-cowsay.yaml create mode 100644 test/units/utils/display/test_broken_cowsay.py diff --git a/changelogs/fragments/72592-catch-broken-cowsay.yaml b/changelogs/fragments/72592-catch-broken-cowsay.yaml new file mode 100644 index 00000000000..0fd5507c384 --- /dev/null +++ b/changelogs/fragments/72592-catch-broken-cowsay.yaml @@ -0,0 +1,2 @@ +bugfixes: + - catch the case that cowsay is broken which would lead to missing output \ No newline at end of file diff --git a/lib/ansible/utils/display.py b/lib/ansible/utils/display.py index 86237ef85a6..a1a45b2def8 100644 --- a/lib/ansible/utils/display.py +++ b/lib/ansible/utils/display.py @@ -219,7 +219,9 @@ class Display(metaclass=Singleton): try: cmd = subprocess.Popen([self.b_cowsay, "-l"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (out, err) = cmd.communicate() - self.cows_available = {to_text(c) for c in out.split()} + if cmd.returncode: + raise Exception + self.cows_available = {to_text(c) for c in out.split()} # set comprehension if C.ANSIBLE_COW_ACCEPTLIST and any(C.ANSIBLE_COW_ACCEPTLIST): self.cows_available = set(C.ANSIBLE_COW_ACCEPTLIST).intersection(self.cows_available) except Exception: diff --git a/test/units/utils/display/test_broken_cowsay.py b/test/units/utils/display/test_broken_cowsay.py new file mode 100644 index 00000000000..e93065d8e01 --- /dev/null +++ b/test/units/utils/display/test_broken_cowsay.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2021 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +from ansible.utils.display import Display +from mock import MagicMock + + +def test_display_with_fake_cowsay_binary(capsys, mocker): + mocker.patch("ansible.constants.ANSIBLE_COW_PATH", "./cowsay.sh") + + def mock_communicate(input=None, timeout=None): + return b"", b"" + + mock_popen = MagicMock() + mock_popen.return_value.communicate = mock_communicate + mock_popen.return_value.returncode = 1 + mocker.patch("subprocess.Popen", mock_popen) + + display = Display() + assert not hasattr(display, "cows_available") + assert display.b_cowsay is None