From 10a8fde5bb336936f203f6fdab035d5c91bcb649 Mon Sep 17 00:00:00 2001 From: Alexandra Bara Date: Thu, 4 Dec 2025 10:17:34 -0600 Subject: [PATCH 1/6] added lshw and lscpu cmds --- .../device_enumeration_collector.py | 42 +++++++++++++++++-- .../device_enumeration/deviceenumdata.py | 2 + .../test_device_enumeration_collector.py | 35 +++++++++++++++- 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py b/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py index 88506f6e..a0430a34 100644 --- a/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py +++ b/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py @@ -26,7 +26,7 @@ from typing import Optional from nodescraper.base import InBandDataCollector -from nodescraper.connection.inband.inband import CommandArtifact +from nodescraper.connection.inband.inband import CommandArtifact, TextFileArtifact from nodescraper.enums import EventCategory, EventPriority, ExecutionStatus, OSFamily from nodescraper.models import TaskResult @@ -41,6 +41,8 @@ class DeviceEnumerationCollector(InBandDataCollector[DeviceEnumerationDataModel, CMD_CPU_COUNT_LINUX = "lscpu | grep Socket | awk '{ print $2 }'" CMD_GPU_COUNT_LINUX = "lspci -d {vendorid_ep}: | grep -i 'VGA\\|Display\\|3D' | wc -l" CMD_VF_COUNT_LINUX = "lspci -d {vendorid_ep}: | grep -i 'Virtual Function' | wc -l" + CMD_LSCPU_LINUX = "/usr/bin/lscpu" + CMD_LSHW_LINUX = "lshw" CMD_CPU_COUNT_WINDOWS = ( 'powershell -Command "(Get-WmiObject -Class Win32_Processor | Measure-Object).Count"' @@ -86,6 +88,12 @@ def collect_data(self, args=None) -> tuple[TaskResult, Optional[DeviceEnumeratio # Count AMD Virtual Functions vf_count_res = self._run_sut_cmd(self.CMD_VF_COUNT_LINUX.format(vendorid_ep=vendor_id)) + + # Collect lscpu output + lscpu_res = self._run_sut_cmd(self.CMD_LSCPU_LINUX, log_artifact=False) + + # Collect lshw output + lshw_res = self._run_sut_cmd(self.CMD_LSHW_LINUX, sudo=True, log_artifact=False) else: cpu_count_res = self._run_sut_cmd(self.CMD_CPU_COUNT_WINDOWS) gpu_count_res = self._run_sut_cmd(self.CMD_GPU_COUNT_WINDOWS) @@ -112,14 +120,42 @@ def collect_data(self, args=None) -> tuple[TaskResult, Optional[DeviceEnumeratio category=EventCategory.SW_DRIVER, ) + if self.system_info.os_family == OSFamily.LINUX: + if lscpu_res.exit_code == 0 and lscpu_res.stdout: + device_enum.lscpu_output = lscpu_res.stdout + self._log_event( + category=EventCategory.PLATFORM, + description="Collected lscpu output", + priority=EventPriority.INFO, + ) + else: + self._warning(description="Cannot collect lscpu output", command=lscpu_res) + + if lshw_res.exit_code == 0 and lshw_res.stdout: + device_enum.lshw_output = lshw_res.stdout + self.result.artifacts.append( + TextFileArtifact(filename="lshw.txt", contents=lshw_res.stdout) + ) + self._log_event( + category=EventCategory.PLATFORM, + description="Collected lshw output", + priority=EventPriority.INFO, + ) + else: + self._warning(description="Cannot collect lshw output", command=lshw_res) + if device_enum.cpu_count or device_enum.gpu_count or device_enum.vf_count: + log_data = device_enum.model_dump( + exclude_none=True, + exclude={"lscpu_output", "lshw_output", "task_name", "task_type", "parent"}, + ) self._log_event( category=EventCategory.PLATFORM, description=f"Counted {device_enum.cpu_count} CPUs, {device_enum.gpu_count} GPUs, {device_enum.vf_count} VFs", - data=device_enum.model_dump(exclude_none=True), + data=log_data, priority=EventPriority.INFO, ) - self.result.message = f"Device Enumeration: {device_enum.model_dump(exclude_none=True)}" + self.result.message = f"Device Enumeration: {log_data}" self.result.status = ExecutionStatus.OK return self.result, device_enum else: diff --git a/nodescraper/plugins/inband/device_enumeration/deviceenumdata.py b/nodescraper/plugins/inband/device_enumeration/deviceenumdata.py index 74939209..bef13492 100644 --- a/nodescraper/plugins/inband/device_enumeration/deviceenumdata.py +++ b/nodescraper/plugins/inband/device_enumeration/deviceenumdata.py @@ -32,3 +32,5 @@ class DeviceEnumerationDataModel(DataModel): cpu_count: Optional[int] = None gpu_count: Optional[int] = None vf_count: Optional[int] = None + lscpu_output: Optional[str] = None + lshw_output: Optional[str] = None diff --git a/test/unit/plugin/test_device_enumeration_collector.py b/test/unit/plugin/test_device_enumeration_collector.py index a5a1ef30..fd78b9d4 100644 --- a/test/unit/plugin/test_device_enumeration_collector.py +++ b/test/unit/plugin/test_device_enumeration_collector.py @@ -51,6 +51,9 @@ def test_collect_linux(system_info, device_enumeration_collector): """Test linux typical output""" system_info.os_family = OSFamily.LINUX + lscpu_output = "Architecture: x86_64\nCPU(s): 64\nSocket(s): 2" + lshw_output = "*-cpu\n product: AMD EPYC 1234 64-Core Processor" + device_enumeration_collector._run_sut_cmd = MagicMock( side_effect=[ MagicMock( @@ -71,12 +74,30 @@ def test_collect_linux(system_info, device_enumeration_collector): stderr="", command="lspci -d 1002: | grep -i 'Virtual Function' | wc -l", ), + MagicMock( + exit_code=0, + stdout=lscpu_output, + stderr="", + command="/usr/bin/lscpu", + ), + MagicMock( + exit_code=0, + stdout=lshw_output, + stderr="", + command="lshw", + ), ] ) result, data = device_enumeration_collector.collect_data() assert result.status == ExecutionStatus.OK - assert data == DeviceEnumerationDataModel(cpu_count=2, gpu_count=8, vf_count=0) + assert data == DeviceEnumerationDataModel( + cpu_count=2, gpu_count=8, vf_count=0, lscpu_output=lscpu_output, lshw_output=lshw_output + ) + assert ( + len([a for a in result.artifacts if hasattr(a, "filename") and a.filename == "lshw.txt"]) + == 1 + ) def test_collect_windows(system_info, device_enumeration_collector): @@ -135,6 +156,18 @@ def test_collect_error(system_info, device_enumeration_collector): stderr="command failed", command="lspci -d 1002: | grep -i 'Virtual Function' | wc -l", ), + MagicMock( + exit_code=1, + stdout="", + stderr="command failed", + command="/usr/bin/lscpu", + ), + MagicMock( + exit_code=1, + stdout="", + stderr="command failed", + command="lshw", + ), ] ) From 1dd4bdccaf6ded8e9e7fe1ceac18e78a2d71183f Mon Sep 17 00:00:00 2001 From: Alexandra Bara Date: Thu, 4 Dec 2025 11:00:15 -0600 Subject: [PATCH 2/6] removed duplicate cmd call --- .../device_enumeration_collector.py | 123 ++++++++++++------ .../test_device_enumeration_collector.py | 20 +-- 2 files changed, 84 insertions(+), 59 deletions(-) diff --git a/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py b/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py index a0430a34..3afecac8 100644 --- a/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py +++ b/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py @@ -26,7 +26,7 @@ from typing import Optional from nodescraper.base import InBandDataCollector -from nodescraper.connection.inband.inband import CommandArtifact, TextFileArtifact +from nodescraper.connection.inband.inband import TextFileArtifact from nodescraper.enums import EventCategory, EventPriority, ExecutionStatus, OSFamily from nodescraper.models import TaskResult @@ -38,7 +38,6 @@ class DeviceEnumerationCollector(InBandDataCollector[DeviceEnumerationDataModel, DATA_MODEL = DeviceEnumerationDataModel - CMD_CPU_COUNT_LINUX = "lscpu | grep Socket | awk '{ print $2 }'" CMD_GPU_COUNT_LINUX = "lspci -d {vendorid_ep}: | grep -i 'VGA\\|Display\\|3D' | wc -l" CMD_VF_COUNT_LINUX = "lspci -d {vendorid_ep}: | grep -i 'Virtual Function' | wc -l" CMD_LSCPU_LINUX = "/usr/bin/lscpu" @@ -52,24 +51,6 @@ class DeviceEnumerationCollector(InBandDataCollector[DeviceEnumerationDataModel, 'powershell -Command "(Get-VMHostPartitionableGpu | Measure-Object).Count"' ) - def _warning( - self, - description: str, - command: CommandArtifact, - category: EventCategory = EventCategory.PLATFORM, - ): - self._log_event( - category=category, - description=description, - data={ - "command": command.command, - "stdout": command.stdout, - "stderr": command.stderr, - "exit_code": command.exit_code, - }, - priority=EventPriority.WARNING, - ) - def collect_data(self, args=None) -> tuple[TaskResult, Optional[DeviceEnumerationDataModel]]: """ Read CPU and GPU count @@ -77,8 +58,7 @@ def collect_data(self, args=None) -> tuple[TaskResult, Optional[DeviceEnumeratio On Windows, use WMI and hyper-v cmdlets """ if self.system_info.os_family == OSFamily.LINUX: - # Count CPU sockets - cpu_count_res = self._run_sut_cmd(self.CMD_CPU_COUNT_LINUX) + lscpu_res = self._run_sut_cmd(self.CMD_LSCPU_LINUX, log_artifact=False) # Count all AMD GPUs vendor_id = format(self.system_info.vendorid_ep, "x") @@ -89,9 +69,6 @@ def collect_data(self, args=None) -> tuple[TaskResult, Optional[DeviceEnumeratio # Count AMD Virtual Functions vf_count_res = self._run_sut_cmd(self.CMD_VF_COUNT_LINUX.format(vendorid_ep=vendor_id)) - # Collect lscpu output - lscpu_res = self._run_sut_cmd(self.CMD_LSCPU_LINUX, log_artifact=False) - # Collect lshw output lshw_res = self._run_sut_cmd(self.CMD_LSHW_LINUX, sudo=True, log_artifact=False) else: @@ -101,36 +78,87 @@ def collect_data(self, args=None) -> tuple[TaskResult, Optional[DeviceEnumeratio device_enum = DeviceEnumerationDataModel() - if cpu_count_res.exit_code == 0: - device_enum.cpu_count = int(cpu_count_res.stdout) + if self.system_info.os_family == OSFamily.LINUX: + if lscpu_res.exit_code == 0 and lscpu_res.stdout: + # Extract socket count from lscpu output + for line in lscpu_res.stdout.splitlines(): + if line.startswith("Socket(s):"): + try: + device_enum.cpu_count = int(line.split(":")[1].strip()) + break + except (ValueError, IndexError): + self._log_event( + category=EventCategory.PLATFORM, + description="Cannot parse CPU count from lscpu output", + data={ + "command": lscpu_res.command, + "exit_code": lscpu_res.exit_code, + "stderr": lscpu_res.stderr, + }, + priority=EventPriority.WARNING, + ) + device_enum.lscpu_output = lscpu_res.stdout + self._log_event( + category=EventCategory.PLATFORM, + description="Collected lscpu output", + priority=EventPriority.INFO, + ) + else: + self._log_event( + category=EventCategory.PLATFORM, + description="Cannot collect lscpu output", + data={ + "command": lscpu_res.command, + "exit_code": lscpu_res.exit_code, + "stderr": lscpu_res.stderr, + }, + priority=EventPriority.WARNING, + ) else: - self._warning(description="Cannot determine CPU count", command=cpu_count_res) + if cpu_count_res.exit_code == 0: + device_enum.cpu_count = int(cpu_count_res.stdout) + else: + self._log_event( + category=EventCategory.PLATFORM, + description="Cannot determine CPU count", + data={ + "command": cpu_count_res.command, + "exit_code": cpu_count_res.exit_code, + "stderr": cpu_count_res.stderr, + }, + priority=EventPriority.WARNING, + ) if gpu_count_res.exit_code == 0: device_enum.gpu_count = int(gpu_count_res.stdout) else: - self._warning(description="Cannot determine GPU count", command=gpu_count_res) + self._log_event( + category=EventCategory.PLATFORM, + description="Cannot determine GPU count", + data={ + "command": gpu_count_res.command, + "exit_code": gpu_count_res.exit_code, + "stderr": gpu_count_res.stderr, + }, + priority=EventPriority.WARNING, + ) if vf_count_res.exit_code == 0: device_enum.vf_count = int(vf_count_res.stdout) else: - self._warning( - description="Cannot determine VF count", - command=vf_count_res, + self._log_event( category=EventCategory.SW_DRIVER, + description="Cannot determine VF count", + data={ + "command": vf_count_res.command, + "exit_code": vf_count_res.exit_code, + "stderr": vf_count_res.stderr, + }, + priority=EventPriority.WARNING, ) + # Collect lshw output on Linux if self.system_info.os_family == OSFamily.LINUX: - if lscpu_res.exit_code == 0 and lscpu_res.stdout: - device_enum.lscpu_output = lscpu_res.stdout - self._log_event( - category=EventCategory.PLATFORM, - description="Collected lscpu output", - priority=EventPriority.INFO, - ) - else: - self._warning(description="Cannot collect lscpu output", command=lscpu_res) - if lshw_res.exit_code == 0 and lshw_res.stdout: device_enum.lshw_output = lshw_res.stdout self.result.artifacts.append( @@ -142,7 +170,16 @@ def collect_data(self, args=None) -> tuple[TaskResult, Optional[DeviceEnumeratio priority=EventPriority.INFO, ) else: - self._warning(description="Cannot collect lshw output", command=lshw_res) + self._log_event( + category=EventCategory.PLATFORM, + description="Cannot collect lshw output", + data={ + "command": lshw_res.command, + "exit_code": lshw_res.exit_code, + "stderr": lshw_res.stderr, + }, + priority=EventPriority.WARNING, + ) if device_enum.cpu_count or device_enum.gpu_count or device_enum.vf_count: log_data = device_enum.model_dump( diff --git a/test/unit/plugin/test_device_enumeration_collector.py b/test/unit/plugin/test_device_enumeration_collector.py index fd78b9d4..7abb2766 100644 --- a/test/unit/plugin/test_device_enumeration_collector.py +++ b/test/unit/plugin/test_device_enumeration_collector.py @@ -58,9 +58,9 @@ def test_collect_linux(system_info, device_enumeration_collector): side_effect=[ MagicMock( exit_code=0, - stdout="2", + stdout=lscpu_output, stderr="", - command="lscpu | grep Socket | awk '{ print $2 }'", + command="/usr/bin/lscpu", ), MagicMock( exit_code=0, @@ -74,12 +74,6 @@ def test_collect_linux(system_info, device_enumeration_collector): stderr="", command="lspci -d 1002: | grep -i 'Virtual Function' | wc -l", ), - MagicMock( - exit_code=0, - stdout=lscpu_output, - stderr="", - command="/usr/bin/lscpu", - ), MagicMock( exit_code=0, stdout=lshw_output, @@ -140,9 +134,9 @@ def test_collect_error(system_info, device_enumeration_collector): side_effect=[ MagicMock( exit_code=1, - stdout="some output", + stdout="", stderr="command failed", - command="lscpu | grep Socket | awk '{ print $2 }'", + command="/usr/bin/lscpu", ), MagicMock( exit_code=1, @@ -156,12 +150,6 @@ def test_collect_error(system_info, device_enumeration_collector): stderr="command failed", command="lspci -d 1002: | grep -i 'Virtual Function' | wc -l", ), - MagicMock( - exit_code=1, - stdout="", - stderr="command failed", - command="/usr/bin/lscpu", - ), MagicMock( exit_code=1, stdout="", From a7eea9ef208786d4fe14d33187f43b7322922cda Mon Sep 17 00:00:00 2001 From: Alexandra Bara Date: Thu, 4 Dec 2025 11:04:11 -0600 Subject: [PATCH 3/6] readded local _warning function to shorten code --- .../device_enumeration_collector.py | 84 ++++++------------- 1 file changed, 27 insertions(+), 57 deletions(-) diff --git a/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py b/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py index 3afecac8..e2fecf0b 100644 --- a/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py +++ b/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py @@ -26,7 +26,7 @@ from typing import Optional from nodescraper.base import InBandDataCollector -from nodescraper.connection.inband.inband import TextFileArtifact +from nodescraper.connection.inband.inband import CommandArtifact, TextFileArtifact from nodescraper.enums import EventCategory, EventPriority, ExecutionStatus, OSFamily from nodescraper.models import TaskResult @@ -51,6 +51,23 @@ class DeviceEnumerationCollector(InBandDataCollector[DeviceEnumerationDataModel, 'powershell -Command "(Get-VMHostPartitionableGpu | Measure-Object).Count"' ) + def _warning( + self, + description: str, + command: CommandArtifact, + category: EventCategory = EventCategory.PLATFORM, + ): + self._log_event( + category=category, + description=description, + data={ + "command": command.command, + "exit_code": command.exit_code, + "stderr": command.stderr, + }, + priority=EventPriority.WARNING, + ) + def collect_data(self, args=None) -> tuple[TaskResult, Optional[DeviceEnumerationDataModel]]: """ Read CPU and GPU count @@ -87,15 +104,9 @@ def collect_data(self, args=None) -> tuple[TaskResult, Optional[DeviceEnumeratio device_enum.cpu_count = int(line.split(":")[1].strip()) break except (ValueError, IndexError): - self._log_event( - category=EventCategory.PLATFORM, + self._warning( description="Cannot parse CPU count from lscpu output", - data={ - "command": lscpu_res.command, - "exit_code": lscpu_res.exit_code, - "stderr": lscpu_res.stderr, - }, - priority=EventPriority.WARNING, + command=lscpu_res, ) device_enum.lscpu_output = lscpu_res.stdout self._log_event( @@ -104,57 +115,25 @@ def collect_data(self, args=None) -> tuple[TaskResult, Optional[DeviceEnumeratio priority=EventPriority.INFO, ) else: - self._log_event( - category=EventCategory.PLATFORM, - description="Cannot collect lscpu output", - data={ - "command": lscpu_res.command, - "exit_code": lscpu_res.exit_code, - "stderr": lscpu_res.stderr, - }, - priority=EventPriority.WARNING, - ) + self._warning(description="Cannot collect lscpu output", command=lscpu_res) else: if cpu_count_res.exit_code == 0: device_enum.cpu_count = int(cpu_count_res.stdout) else: - self._log_event( - category=EventCategory.PLATFORM, - description="Cannot determine CPU count", - data={ - "command": cpu_count_res.command, - "exit_code": cpu_count_res.exit_code, - "stderr": cpu_count_res.stderr, - }, - priority=EventPriority.WARNING, - ) + self._warning(description="Cannot determine CPU count", command=cpu_count_res) if gpu_count_res.exit_code == 0: device_enum.gpu_count = int(gpu_count_res.stdout) else: - self._log_event( - category=EventCategory.PLATFORM, - description="Cannot determine GPU count", - data={ - "command": gpu_count_res.command, - "exit_code": gpu_count_res.exit_code, - "stderr": gpu_count_res.stderr, - }, - priority=EventPriority.WARNING, - ) + self._warning(description="Cannot determine GPU count", command=gpu_count_res) if vf_count_res.exit_code == 0: device_enum.vf_count = int(vf_count_res.stdout) else: - self._log_event( - category=EventCategory.SW_DRIVER, + self._warning( description="Cannot determine VF count", - data={ - "command": vf_count_res.command, - "exit_code": vf_count_res.exit_code, - "stderr": vf_count_res.stderr, - }, - priority=EventPriority.WARNING, + command=vf_count_res, + category=EventCategory.SW_DRIVER, ) # Collect lshw output on Linux @@ -170,16 +149,7 @@ def collect_data(self, args=None) -> tuple[TaskResult, Optional[DeviceEnumeratio priority=EventPriority.INFO, ) else: - self._log_event( - category=EventCategory.PLATFORM, - description="Cannot collect lshw output", - data={ - "command": lshw_res.command, - "exit_code": lshw_res.exit_code, - "stderr": lshw_res.stderr, - }, - priority=EventPriority.WARNING, - ) + self._warning(description="Cannot collect lshw output", command=lshw_res) if device_enum.cpu_count or device_enum.gpu_count or device_enum.vf_count: log_data = device_enum.model_dump( From 099b58d9439ff5f7caf484e5111a0f5424c416b9 Mon Sep 17 00:00:00 2001 From: Alexandra Bara Date: Thu, 4 Dec 2025 11:09:05 -0600 Subject: [PATCH 4/6] remove leading /usr/bin from cmd call --- .../inband/device_enumeration/device_enumeration_collector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py b/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py index e2fecf0b..82a82f91 100644 --- a/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py +++ b/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py @@ -40,7 +40,7 @@ class DeviceEnumerationCollector(InBandDataCollector[DeviceEnumerationDataModel, CMD_GPU_COUNT_LINUX = "lspci -d {vendorid_ep}: | grep -i 'VGA\\|Display\\|3D' | wc -l" CMD_VF_COUNT_LINUX = "lspci -d {vendorid_ep}: | grep -i 'Virtual Function' | wc -l" - CMD_LSCPU_LINUX = "/usr/bin/lscpu" + CMD_LSCPU_LINUX = "lscpu" CMD_LSHW_LINUX = "lshw" CMD_CPU_COUNT_WINDOWS = ( From 35194f1c0e8b91ac9346804ce26991ac7c4879a2 Mon Sep 17 00:00:00 2001 From: Alexandra Bara Date: Mon, 8 Dec 2025 10:07:40 -0600 Subject: [PATCH 5/6] removed /usr/bin from test cmd --- test/unit/plugin/test_device_enumeration_collector.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/plugin/test_device_enumeration_collector.py b/test/unit/plugin/test_device_enumeration_collector.py index 7abb2766..795611a6 100644 --- a/test/unit/plugin/test_device_enumeration_collector.py +++ b/test/unit/plugin/test_device_enumeration_collector.py @@ -60,7 +60,7 @@ def test_collect_linux(system_info, device_enumeration_collector): exit_code=0, stdout=lscpu_output, stderr="", - command="/usr/bin/lscpu", + command="lscpu", ), MagicMock( exit_code=0, @@ -136,7 +136,7 @@ def test_collect_error(system_info, device_enumeration_collector): exit_code=1, stdout="", stderr="command failed", - command="/usr/bin/lscpu", + command="lscpu", ), MagicMock( exit_code=1, From baa75a5ba344a25125cc17def6b4648d750098b6 Mon Sep 17 00:00:00 2001 From: Alexandra Bara Date: Wed, 10 Dec 2025 10:07:28 -0600 Subject: [PATCH 6/6] fix for printing inherited vars --- nodescraper/interfaces/task.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nodescraper/interfaces/task.py b/nodescraper/interfaces/task.py index effd3029..16d1a70b 100644 --- a/nodescraper/interfaces/task.py +++ b/nodescraper/interfaces/task.py @@ -107,6 +107,8 @@ def _build_event( data = {"task_name": self.__class__.__name__, "task_type": self.TASK_TYPE} else: + # Copy to avoid mutating the caller's dict + data = copy.copy(data) data["task_name"] = self.__class__.__name__ data["task_type"] = self.TASK_TYPE