From 9337ef8d06f4e0a65e3e6062f24a3148f5794466 Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Wed, 18 Feb 2026 00:58:22 +0900 Subject: [PATCH] Find cat command externally ... to attempt potential command name and path for multiple operating systems. This allows us to keep the test robust for any update in underlying operating systems. Change-Id: I44e7cd57e8cefa54b0284a8be067d87d725fa4e1 Signed-off-by: Takashi Kajinami --- oslo_rootwrap/tests/test_rootwrap.py | 56 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/oslo_rootwrap/tests/test_rootwrap.py b/oslo_rootwrap/tests/test_rootwrap.py index 6ba8dfb..67bc9ce 100644 --- a/oslo_rootwrap/tests/test_rootwrap.py +++ b/oslo_rootwrap/tests/test_rootwrap.py @@ -16,6 +16,7 @@ import configparser import logging import logging.handlers import os +import shutil import tempfile from unittest import mock import uuid @@ -220,64 +221,63 @@ class RootwrapTestCase(testtools.TestCase): def test_KillFilter(self): if not os.path.exists(f"/proc/{os.getpid()}"): self.skipTest("Test requires /proc filesystem (procfs)") + + cat_cmd = "cat" + cat_path = shutil.which(cat_cmd) + if cat_path is None: + self.skipTest("Test requires cat command") + + assert cat_path is not None + # NOTE(tkajinam): In RHEL9 containers the cat command is a symlink + # See bug 2037383 for details. + if os.path.islink(cat_path): + cat_path = os.path.realpath(cat_path) + cat_cmd = os.path.basename(cat_path) + p = subprocess.Popen( ["cat"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, ) + try: - filter_list = [ - filters.KillFilter("root", cmd, "-9", "-HUP") - for cmd in ("/bin/cat", "/usr/bin/cat", "/usr/bin/coreutils") - ] + f = filters.KillFilter("root", cat_path, "-9", "-HUP") usercmd = ['kill', '-ALRM', str(p.pid)] # Incorrect signal should fail - for f in filter_list: - self.assertFalse(f.match(usercmd)) + self.assertFalse(f.match(usercmd)) usercmd = ['kill', str(p.pid)] # Providing no signal should fail - for f in filter_list: - self.assertFalse(f.match(usercmd)) + self.assertFalse(f.match(usercmd)) # Providing matching signal should be allowed usercmd = ['kill', '-9', str(p.pid)] - self.assertTrue(any([f.match(usercmd) for f in filter_list])) + self.assertTrue(f.match(usercmd)) - filter_list = [ - filters.KillFilter("root", cmd) - for cmd in ("/bin/cat", "/usr/bin/cat", "/usr/bin/coreutils") - ] + f = filters.KillFilter("root", cat_path) usercmd = ['kill', str(os.getpid())] # Our own PID does not match /bin/sleep, so it should fail - for f in filter_list: - self.assertFalse(f.match(usercmd)) + self.assertFalse(f.match(usercmd)) usercmd = ['kill', '999999'] # Nonexistent PID should fail - for f in filter_list: - self.assertFalse(f.match(usercmd)) + self.assertFalse(f.match(usercmd)) usercmd = ['kill', str(p.pid)] # Providing no signal should work - self.assertTrue(any([f.match(usercmd) for f in filter_list])) + self.assertTrue(f.match(usercmd)) # verify that relative paths are matched against $PATH - filter_list = [ - filters.KillFilter("root", cmd) for cmd in ("cat", "coreutils") - ] + f = filters.KillFilter("root", cat_cmd) # Our own PID does not match so it should fail usercmd = ['kill', str(os.getpid())] - for f in filter_list: - self.assertFalse(f.match(usercmd)) + self.assertFalse(f.match(usercmd)) # Filter should find cat in /bin or /usr/bin usercmd = ['kill', str(p.pid)] - self.assertTrue(any([f.match(usercmd) for f in filter_list])) + self.assertTrue(f.match(usercmd)) # Filter shouldn't be able to find binary in $PATH, so fail with fixtures.EnvironmentVariable("PATH", "/foo:/bar"): - for f in filter_list: - self.assertFalse(f.match(usercmd)) + self.assertFalse(f.match(usercmd)) # ensure that unset $PATH is not causing an exception with fixtures.EnvironmentVariable("PATH"): - for f in filter_list: - self.assertFalse(f.match(usercmd)) + self.assertFalse(f.match(usercmd)) finally: # Terminate the "cat" process and wait for it to finish p.terminate()