Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions nodescraper/plugins/inband/dmesg/collector_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ class DmesgCollectorArgs(CollectorArgs):

collect_rotated_logs: bool = False
skip_sudo: bool = False
log_dmesg_data: bool = True
4 changes: 3 additions & 1 deletion nodescraper/plugins/inband/dmesg/dmesg_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ def collect_data(
self._collect_dmesg_rotations()

if dmesg_content:
dmesg_data = DmesgData(dmesg_content=dmesg_content)
dmesg_data = DmesgData(
dmesg_content=dmesg_content, skip_log_file=not args.log_dmesg_data
)
self.result.message = "Dmesg data collected"
return self.result, dmesg_data

Expand Down
3 changes: 3 additions & 0 deletions nodescraper/plugins/inband/dmesg/dmesgdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class DmesgData(DataModel):
"""Data model for in band dmesg log"""

dmesg_content: str
skip_log_file: bool = False

@classmethod
def get_new_dmesg_lines(cls, current_dmesg: str, new_dmesg: str) -> str:
Expand Down Expand Up @@ -83,6 +84,8 @@ def log_model(self, log_path: str):
Args:
log_path (str): log path
"""
if self.skip_log_file:
return
log_name = os.path.join(log_path, get_unique_filename(log_path, "dmesg.log"))
with open(log_name, "w", encoding="utf-8") as log_file:
log_file.write(self.dmesg_content)
Expand Down
51 changes: 51 additions & 0 deletions test/functional/test_plugin_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,54 @@ def test_all_plugin_config_files_exist(plugin_config_files):
config = json.load(f)
assert "plugins" in config
assert plugin_name in config["plugins"]


def test_dmesg_plugin_log_dmesg_data_false(run_cli_command, tmp_path):
"""Test DmesgPlugin with log_dmesg_data=false doesn't write dmesg.log."""
config = {
"name": "DmesgNoLogConfig",
"desc": "DmesgPlugin config with log_dmesg_data disabled",
"global_args": {},
"plugins": {"DmesgPlugin": {"collection_args": {"log_dmesg_data": False}}},
"result_collators": {},
}
config_file = tmp_path / "dmesg_no_log_config.json"
config_file.write_text(json.dumps(config, indent=2))

log_path = str(tmp_path / "logs_dmesg_no_log")
result = run_cli_command(
["--log-path", log_path, "--plugin-configs", str(config_file)], check=False
)

assert result.returncode in [0, 1, 2]

dmesg_plugin_dir = Path(log_path) / "dmesg_plugin" / "dmesg_collector"
if dmesg_plugin_dir.exists():
dmesg_log_files = list(dmesg_plugin_dir.glob("dmesg*.log"))
assert (
len(dmesg_log_files) == 0
), f"Found dmesg log files when log_dmesg_data=False: {dmesg_log_files}"


def test_dmesg_plugin_log_dmesg_data_true(run_cli_command, tmp_path):
"""Test DmesgPlugin with log_dmesg_data=true writes dmesg.log."""
config = {
"name": "DmesgWithLogConfig",
"desc": "DmesgPlugin config with log_dmesg_data enabled",
"global_args": {},
"plugins": {"DmesgPlugin": {"collection_args": {"log_dmesg_data": True}}},
"result_collators": {},
}
config_file = tmp_path / "dmesg_with_log_config.json"
config_file.write_text(json.dumps(config, indent=2))

log_path = str(tmp_path / "logs_dmesg_with_log")
result = run_cli_command(
["--log-path", log_path, "--plugin-configs", str(config_file)], check=False
)

if result.returncode in [0, 1]:
dmesg_plugin_dir = Path(log_path) / "dmesg_plugin" / "dmesg_collector"
if dmesg_plugin_dir.exists():
dmesg_log_files = list(dmesg_plugin_dir.glob("dmesg*.log"))
assert len(dmesg_log_files) > 0, "Expected dmesg.log file when log_dmesg_data=True"
25 changes: 25 additions & 0 deletions test/unit/plugin/test_dmesg_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from nodescraper.enums.systeminteraction import SystemInteractionLevel
from nodescraper.interfaces.task import SystemCompatibilityError
from nodescraper.models.systeminfo import OSFamily
from nodescraper.plugins.inband.dmesg.collector_args import DmesgCollectorArgs
from nodescraper.plugins.inband.dmesg.dmesg_collector import DmesgCollector
from nodescraper.plugins.inband.dmesg.dmesgdata import DmesgData

Expand Down Expand Up @@ -276,3 +277,27 @@ def run_map(cmd, **kwargs):

assert isinstance(data, DmesgData)
assert data.dmesg_content == "DMESG OUTPUT\n"


def test_collect_data_with_args(conn_mock, system_info):
"""Test collect_data accepts DmesgCollectorArgs"""
dmesg = "2023-06-01T01:00:00,685236-05:00 test message1\n"
conn_mock.run_command.return_value = CommandArtifact(
exit_code=0,
stdout=dmesg,
stderr="",
command="dmesg --time-format iso",
)

collector = DmesgCollector(
system_info=system_info,
system_interaction_level=SystemInteractionLevel.INTERACTIVE,
connection=conn_mock,
)

args = DmesgCollectorArgs(log_dmesg_data=False)
res, data = collector.collect_data(args=args)

assert res.status == ExecutionStatus.OK
assert data is not None
assert data.dmesg_content == dmesg