From e02f0849e45116514eabf1d856d36b9ab811d87f Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Thu, 30 Jul 2020 11:38:08 +0200 Subject: [PATCH] Add an explicit system test for processes on unix systems (#20320) Some fields are only available on some operating systems, and for processes Metricbeat has permissions to read. Check these fields only on these operating systems and on processes owned by the same user running the test. Fix also check on current working directory. (cherry picked from commit 6106a0eb595e27ca3ac9d0bb79b2705f21e5ea15) --- metricbeat/module/system/test_system.py | 82 +++++++++++++++++++------ 1 file changed, 63 insertions(+), 19 deletions(-) diff --git a/metricbeat/module/system/test_system.py b/metricbeat/module/system/test_system.py index cc6b731b113..82e59e71af4 100644 --- a/metricbeat/module/system/test_system.py +++ b/metricbeat/module/system/test_system.py @@ -392,41 +392,85 @@ def test_process(self): self.assertGreater(len(output), 0) found_cmdline = False - found_env = False + for evt in output: + process = evt["system"]["process"] + found_cmdline |= "cmdline" in process + + # Remove 'env' prior to checking documented fields because its keys are dynamic. + process.pop("env", None) + self.assert_fields_are_documented(evt) + + # Remove optional keys. + process.pop("cgroup", None) + process.pop("fd", None) + process.pop("cmdline", None) + + self.assertCountEqual(SYSTEM_PROCESS_FIELDS, process.keys()) + + self.assertTrue(found_cmdline, "cmdline not found in any process events") + + @unittest.skipUnless(re.match("(?i)linux|darwin|freebsd", sys.platform), "os") + def test_process_unix(self): + """ + Test system/process output for fields specific of unix systems. + """ + import getpass + + self.render_config_template( + modules=[{ + "name": "system", + "metricsets": ["process"], + "period": "5s", + "extras": { + "process.env.whitelist": ["PATH"], + "process.include_cpu_ticks": True, + + # Remove 'percpu' prior to checking documented fields because its keys are dynamic. + "process.include_per_cpu": False, + }, + }], + # Some info is only guaranteed in processes with permissions, check + # only on own processes. + processors=[{ + "drop_event": { + "when": "not.equals.user.name: " + getpass.getuser(), + }, + }], + ) + proc = self.start_beat() + self.wait_until(lambda: self.output_lines() > 0) + proc.check_kill_and_wait() + self.assert_no_logged_warnings() + + output = self.read_output_json() + self.assertGreater(len(output), 0) + found_fd = False + found_env = False found_cwd = not sys.platform.startswith("linux") for evt in output: + found_cwd |= "working_directory" in evt["process"] + process = evt["system"]["process"] + found_fd |= "fd" in process + found_env |= "env" in process # Remove 'env' prior to checking documented fields because its keys are dynamic. env = process.pop("env", None) - if env is not None: - found_env = True - self.assert_fields_are_documented(evt) # Remove optional keys. process.pop("cgroup", None) - cmdline = process.pop("cmdline", None) - if cmdline is not None: - found_cmdline = True - fd = process.pop("fd", None) - if fd is not None: - found_fd = True - cwd = process.pop("cwd", None) - if cwd is not None: - found_cwd = True + process.pop("cmdline", None) + process.pop("fd", None) self.assertCountEqual(SYSTEM_PROCESS_FIELDS, process.keys()) - self.assertTrue(found_cmdline, "cmdline not found in any process events") - - if sys.platform.startswith("linux") or sys.platform.startswith("freebsd"): + if not sys.platform.startswith("darwin"): self.assertTrue(found_fd, "fd not found in any process events") - if sys.platform.startswith("linux") or sys.platform.startswith("freebsd")\ - or sys.platform.startswith("darwin"): - self.assertTrue(found_env, "env not found in any process events") + self.assertTrue(found_env, "env not found in any process events") + self.assertTrue(found_cwd, "working_directory not found in any process events") @unittest.skipUnless(re.match("(?i)win|linux|darwin|freebsd", sys.platform), "os") def test_process_metricbeat(self):