From 35d6dec75c10594e22d8ac27007cfa5685ddb657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M?= Date: Mon, 27 May 2024 01:22:07 +0900 Subject: [PATCH] Handle is_installed for rpm package when rpm database is corrupted When rpm database is corrupted `rpm -q $pkg` return exit code 1 and testinfra was reporting the package as not installed. Use --quiet option so the "package $pkg is (not) installed" is not printed and in case of corrupted database error will display to stdout even with --quiet. Closes #758 Co-authored-by: Philippe Pepiot --- test/test_modules.py | 11 +++++++++++ testinfra/modules/package.py | 10 +++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/test/test_modules.py b/test/test_modules.py index 3106479f..23a1f2f2 100644 --- a/test/test_modules.py +++ b/test/test_modules.py @@ -59,6 +59,17 @@ def test_held_package(host): assert python.version.startswith("3.11.") +@pytest.mark.destructive +@pytest.mark.testinfra_hosts("docker://rockylinux9") +def test_rpmdb_corrupted(host): + host.check_output("dd if=/dev/zero of=/var/lib/rpm/rpmdb.sqlite bs=1024 count=1") + with pytest.raises(RuntimeError) as excinfo: + host.package("zsh").is_installed + assert ( + "Could not check if RPM package 'zsh' is installed. error: sqlite failure:" + ) in str(excinfo.value) + + @pytest.mark.testinfra_hosts("docker://rockylinux9") def test_non_default_package_tool(host): # Make non default pkg tool binary present diff --git a/testinfra/modules/package.py b/testinfra/modules/package.py index 39ef248d..f9f93515 100644 --- a/testinfra/modules/package.py +++ b/testinfra/modules/package.py @@ -165,7 +165,15 @@ def version(self): class RpmPackage(Package): @property def is_installed(self): - return self.run_test("rpm -q %s", self.name).rc == 0 + result = self.run_test("rpm -q --quiet %s 2>&1", self.name) + if result.succeeded: + return True + elif result.failed and result.stdout == "": + return False + else: + raise RuntimeError( + f"Could not check if RPM package '{self.name}' is installed. {result.stdout}" + ) @property def version(self):