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
42 changes: 29 additions & 13 deletions nodescraper/plugins/inband/nic/nic_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,9 @@ class NicCollector(InBandDataCollector[NicDataModel, NicCollectorArgs]):
CMD_NICCLI_QOS_TEMPLATE_LEGACY,
]
# New (> v233): double-dash options and qos --ets --show
CMD_NICCLI_SUPPORT_RDMA_TEMPLATE_NEW = "niccli --dev {device_num} nvm --getoption support_rdma"
CMD_NICCLI_SUPPORT_RDMA_TEMPLATE_NEW = (
"niccli --dev {device_num} nvm --getoption support_rdma --scope 0"
)
CMD_NICCLI_PERFORMANCE_PROFILE_TEMPLATE_NEW = (
"niccli --dev {device_num} nvm --getoption performance_profile"
)
Expand Down Expand Up @@ -471,6 +473,19 @@ def collect_data(
card_ids = [c.id for c in legacy_cards]
card_list_from_text = [c.model_dump() for c in legacy_cards]

if custom_commands is None and not device_nums and not card_ids:
self._log_event(
category=EventCategory.NETWORK,
description="No Broadcom (niccli) or Pensando (nicctl) NIC hardware detected",
priority=EventPriority.INFO,
)
self.result.status = ExecutionStatus.NOT_RAN
self.result.message = (
"No Broadcom (niccli) or Pensando (nicctl) NIC hardware detected; "
"NIC collection skipped"
)
return self.result, None

# Build full command list (expand placeholders)
if custom_commands is not None:
commands_to_run: List[str] = []
Expand All @@ -486,18 +501,19 @@ def collect_data(
else:
commands_to_run = []
# niccli list already stored
per_device_templates = _get_niccli_per_device_templates(niccli_version)
for tpl in per_device_templates:
for d in device_nums:
commands_to_run.append(tpl.format(device_num=d))
# nicctl global (card discovery already done via CMD_NICCTL_CARD_TEXT)
for c in NicCollector.CMD_NICCTL_GLOBAL:
commands_to_run.append(c)
for tpl in NicCollector.CMD_NICCTL_PER_CARD:
for cid in card_ids:
commands_to_run.append(tpl.format(card_id=cid))
for cmd in NicCollector.CMD_NICCTL_LEGACY_TEXT:
commands_to_run.append(cmd)
if device_nums:
per_device_templates = _get_niccli_per_device_templates(niccli_version)
for tpl in per_device_templates:
for d in device_nums:
commands_to_run.append(tpl.format(device_num=d))
if card_ids:
for c in NicCollector.CMD_NICCTL_GLOBAL:
commands_to_run.append(c)
for tpl in NicCollector.CMD_NICCTL_PER_CARD:
for cid in card_ids:
commands_to_run.append(tpl.format(card_id=cid))
for cmd in NicCollector.CMD_NICCTL_LEGACY_TEXT:
commands_to_run.append(cmd)

# Run each command and store (artifact-only commands are not added to results / data model).
for cmd in commands_to_run:
Expand Down
38 changes: 38 additions & 0 deletions test/unit/plugin/test_niccli_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,44 @@ def test_nic_data_model_with_pensando_nic(collector):
assert data.pensando_nic_cards[1].serial_number == "FPL253710E5"


def test_collect_data_not_ran_when_no_nic_hardware(collector, conn_mock):
"""Skip collection when discovery finds no Broadcom or Pensando NICs."""
collector.system_info.os_family = OSFamily.LINUX
collector._run_sut_cmd = MagicMock(
return_value=MagicMock(exit_code=1, stdout="", stderr="not found", command="")
)

result, data = collector.collect_data()

assert result.status == ExecutionStatus.NOT_RAN
assert data is None
assert "skipped" in result.message.lower()
assert collector._run_sut_cmd.call_count <= 4


def test_collect_data_skips_nicctl_commands_when_no_pensando_cards(collector, conn_mock):
"""Do not run nicctl global/legacy commands when nicctl show card finds no cards."""
collector.system_info.os_family = OSFamily.LINUX
commands_run: list[str] = []

def run_sut_cmd_side_effect(cmd, **kwargs):
commands_run.append(cmd)
if "niccli" in cmd and ("--list" in cmd or "--list_devices" in cmd or "--listdev" in cmd):
return MagicMock(exit_code=0, stdout=NICCLI_LISTDEV_OUTPUT, stderr="", command=cmd)
if cmd.strip() == "nicctl show card":
return MagicMock(exit_code=1, stdout="", stderr="no card", command=cmd)
return MagicMock(exit_code=0, stdout="", stderr="", command=cmd)

collector._run_sut_cmd = MagicMock(side_effect=run_sut_cmd_side_effect)

result, data = collector.collect_data()

assert result.status == ExecutionStatus.OK
assert data is not None
assert not any(c.startswith("nicctl show card flash") for c in commands_run)
assert not any(c == "nicctl --version" for c in commands_run)


def test_collect_data_success(collector, conn_mock):
"""Test successful collection of niccli/nicctl data."""
collector.system_info.os_family = OSFamily.LINUX
Expand Down
Loading