From 0bd03e64b268a0c4e8612486b09f6a163bd9914e Mon Sep 17 00:00:00 2001 From: Alexandra Bara Date: Mon, 8 Dec 2025 10:19:11 -0600 Subject: [PATCH 1/2] added full dmidecode cmd to dimm collector + save to txt file --- .../plugins/inband/dimm/dimm_collector.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/nodescraper/plugins/inband/dimm/dimm_collector.py b/nodescraper/plugins/inband/dimm/dimm_collector.py index 167913b5..a3ee84ee 100644 --- a/nodescraper/plugins/inband/dimm/dimm_collector.py +++ b/nodescraper/plugins/inband/dimm/dimm_collector.py @@ -26,6 +26,7 @@ from typing import Optional from nodescraper.base import InBandDataCollector +from nodescraper.connection.inband import TextFileArtifact from nodescraper.enums import EventCategory, EventPriority, ExecutionStatus, OSFamily from nodescraper.models import TaskResult @@ -40,6 +41,7 @@ class DimmCollector(InBandDataCollector[DimmDataModel, DimmCollectorArgs]): CMD_WINDOWS = "wmic memorychip get Capacity" CMD = """sh -c 'dmidecode -t 17 | tr -s " " | grep -v "Volatile\\|None\\|Module" | grep Size' 2>/dev/null""" + CMD_DMIDECODE_FULL = "dmidecode" def collect_data( self, @@ -72,6 +74,25 @@ def collect_data( self.result.message = "Skipping sudo plugin" self.result.status = ExecutionStatus.NOT_RAN return self.result, None + + # Collect full dmidecode output as artifact + dmidecode_full_res = self._run_sut_cmd(self.CMD_DMIDECODE_FULL, sudo=True) + if dmidecode_full_res.exit_code == 0 and dmidecode_full_res.stdout: + self.result.artifacts.append( + TextFileArtifact(filename="dmidecode.txt", contents=dmidecode_full_res.stdout) + ) + else: + self._log_event( + category=EventCategory.OS, + description="Could not collect full dmidecode output", + data={ + "command": dmidecode_full_res.command, + "exit_code": dmidecode_full_res.exit_code, + "stderr": dmidecode_full_res.stderr, + }, + priority=EventPriority.WARNING, + ) + res = self._run_sut_cmd(self.CMD, sudo=True) if res.exit_code == 0: total = 0 From 36b990c602a37188387cfe3751c27eb360f903e8 Mon Sep 17 00:00:00 2001 From: Alexandra Bara Date: Mon, 8 Dec 2025 10:53:35 -0600 Subject: [PATCH 2/2] utest update --- test/unit/plugin/test_dimms_collector.py | 34 +++++++++++++++++------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/test/unit/plugin/test_dimms_collector.py b/test/unit/plugin/test_dimms_collector.py index ac7aa98d..eeaa15ff 100644 --- a/test/unit/plugin/test_dimms_collector.py +++ b/test/unit/plugin/test_dimms_collector.py @@ -68,10 +68,16 @@ def test_run_linux(collector, system_info): system_info.os_family = OSFamily.LINUX collector._run_sut_cmd = MagicMock( - return_value=MagicMock( - exit_code=0, - stdout="Size: 64 GB\nSize: 64 GB\nSize: 128 GB\n", - ) + side_effect=[ + MagicMock( + exit_code=0, + stdout="Full dmidecode output...", + ), + MagicMock( + exit_code=0, + stdout="Size: 64 GB\nSize: 64 GB\nSize: 128 GB\n", + ), + ] ) result, data = collector.collect_data() @@ -84,15 +90,23 @@ def test_run_linux_error(collector, system_info): system_info.os_family = OSFamily.LINUX collector._run_sut_cmd = MagicMock( - return_value=MagicMock( - exit_code=1, - stderr="Error occurred", - ) + side_effect=[ + MagicMock( + exit_code=1, + stderr="Error occurred", + command="dmidecode", + ), + MagicMock( + exit_code=1, + stderr="Error occurred", + command="sh -c 'dmidecode -t 17 | ...'", + ), + ] ) result, data = collector.collect_data() assert result.status == ExecutionStatus.ERROR assert data is None - assert result.events[0].category == EventCategory.OS.value - assert result.events[0].description == "Error checking dimms" + assert result.events[1].category == EventCategory.OS.value + assert result.events[1].description == "Error checking dimms"