Skip to content

tests: Phase-1 NIM e2e coverage (startup/ingest, persistence, LPS, flowlog)#1165

Open
eriknordmark wants to merge 10 commits into
lf-edge:masterfrom
eriknordmark:nim-eden-tests
Open

tests: Phase-1 NIM e2e coverage (startup/ingest, persistence, LPS, flowlog)#1165
eriknordmark wants to merge 10 commits into
lf-edge:masterfrom
eriknordmark:nim-eden-tests

Conversation

@eriknordmark
Copy link
Copy Markdown
Contributor

@eriknordmark eriknordmark commented May 9, 2026

Summary

Phase-1 e2e coverage for NIM, exercising paths that the existing
tests/network suite does not reach: bootstrap/override/USB ingest
priorities, persistent DPCList reload across reboot, LPS multi-port and
mismatch handling, flowlog ACL reconcile, and config-item propagation
to NIM/zedagent.

These tests live under tests/network/testdata/ for now (they reuse the
network suite's harness). A follow-up will split them into a dedicated
tests/nim/ suite with its own eden.nim.test binary.

Highlights:

  • nim_dpcl_reapplied_after_reboot — two-reboot test that isolates
    pubsub persistent-publication reload from re-ingestion (positive
    evidence that NIM's persistent DPCList reload is firing).
  • nim_flowlog_acl_reconcile — drives the EnableFlowlog gate
    end-to-end and asserts iptables CONNMARK rules appear/disappear via
    DpcReconciler's getIntendedMarkingRules; skips on kube EVE.
  • radio_silence_persistence — reboots with RadioSilence imposed via
    LPS and asserts ZedAgentStatus.RadioSilence.Imposed survives the
    reboot through nim's subZedAgentStatus subscription.
  • lps_all_mgmt_ports_overridden / lps_wireless_type_mismatch
    exercise dpcmanager/lps.go merge/guard paths in the multi-port and
    mismatched-wireless cases.
  • nim_diag_remote_endpoints — asserts diag.probe.remote.http.endpoint
    config-item propagation eden→adam→zedagent reaches global.json.
  • Pre-onboard /config scenario tests (nim_bootstrap_only_preonboard,
    nim_bootstrap_supersedes_override_preonboard,
    nim_override_only_preonboard, nim_globalconfig_only_preonboard) —
    bring EVE up with /config overrides (bootstrap-config.pb,
    DevicePortConfig/override.json, GlobalConfig/global.json) baked into
    the live image and never onboard the device. With adam never
    learning the device exists, no controller config is delivered and
    /config-sourced state stays authoritative for the entire
    verification window. SSH availability via embedded
    debug.enable.ssh doubles as a bug-class canary for the #5584/#5775
    cert-chain regression class. Each test owns its own eden lifecycle
    (stop, wipe, setup, start without onboard). The four are grouped in
    eden.network-preonboard.tests.txt and invoked as a suite via
    eden test ./tests/network -s eden.network-preonboard.tests.txt,
    or individually via eden test ./tests/network -e <name>. The
    preonboard suite is kept separate from eden.network.tests.txt
    because each test wipes eden state at exit, so it cannot be
    interleaved with post-onboard tests.
  • Helper: nim-bootstrap-pb-gen — host-side generator for signed
    BootstrapConfig protobufs (same logic as eden setup --eve-bootstrap-file,
    repackaged as a standalone tool). Wired into tests/network/Makefile
    via make helper.
  • Field-fidelity strengthening for nim_override_json_ingest and
    nim_usb_json_ingest: distinctive Logicallabel markers and a
    check-port-fidelity.sh that round-trips Ports[0] fields through
    DoSanitize.
  • Mount portability: switched all five staging/cleanup helpers to
    eve config mount /run/test-config instead of the hardcoded
    /dev/sda4.

Test plan

  • Run each nim_* testdata script against eve-coverage-merge.
  • eden test ./tests/network -s eden.network-preonboard.tests.txt
    — all four preonboard tests pass (~7 min total).
  • Confirm the new helper builds via make -C tests/network helper
    and lands in dist/bin/nim-bootstrap-pb-gen-linux-amd64.
  • CI green on lf-edge/eden.

Bug-detection note

Validated against EVE built from current master (commit 2caf795f0) with lf-edge/eve#5775 reverted in one line (requireECDH=true on the bootstrap path's VerifyLeavesCertChainWithRootPEM call), and against the same master commit unmodified.

  • nim_bootstrap_only reliably catches the bug. On bug-injected EVE, wait-bootstrap-ingested.sh polls /persist/status/nim/DevicePortConfigList/global.json for 12 minutes and never sees a Key="bootstrap" entry — loadBootstrapConfig calls indicateInvalidBootstrapConfig after VerifyLeavesCertChain* returns failed to acquire ECDH cert. Test fails at testdata/nim_bootstrap_only.txt:80, wall time ~1000 s, exit 1. On unmodified master EVE the same test passes in ~180 s.

  • nim_bootstrap_only_preonboard provides a faster, race-free bug-class canary. Same regression class, but the test brings EVE up with /config/bootstrap-config.pb baked into the live image and never onboards; the embedded configItems entry sets debug.enable.ssh. If zedagent rejects the bootstrap pb (the #5584 path), SSHAuthorizedKeys is never set, the iptables INPUT rule for tcp/22 stays REJECT, and wait-ssh-preonboard.sh times out at the 7-minute boundary. Validated against the same buggy master EVE: FAILs in ~460 s (vs ~107 s PASS on unmodified master).

  • nim_bootstrap_supersedes_override_preonboard provides race-free verification of the supersedes rule. The onboarded nim_bootstrap_supersedes_override.txt exercises the NIM-skip-ingest rule under runtime conditions, but the controller takeover after onboarding can overlap the assertion window. The pre-onboard variant brings EVE up with /config/bootstrap-config.pb + /config/DevicePortConfig/override.json baked in and never onboards; with adam never delivering controller config, /config-sourced state stays authoritative indefinitely. Assertions: no override key in DPCList, no override.json in /run/global/DevicePortConfig/, no override-port Logicallabel anywhere — race-free positive proof that NIM honoured the bootstrap-supersedes-override rule. Validated on EVE master (2caf795f0).

eriknordmark added a commit to eriknordmark/eve that referenced this pull request May 10, 2026
Add pkg/pillar/docs/nim-eden-test-plan.md which catalogs existing unit and
eden coverage (including PR lf-edge#5901), enumerates uncovered code paths in
cmd/nim and supporting packages, and proposes a phased set of eden tests
that exercise startup ingestion, DPC verification and fallback against
real SDN-induced connectivity loss, persistence across reboot, LPS
overrides, the resolver cache, PNAC/bond metrics, WLAN with cipher
decryption, cluster static IP, KubeUserServices ACLs, LOC probing and
flowlog reconciliation.

Note in the document that Phase 1 of this plan is being implemented in
lf-edge/eden#1165 (open, draft); script names there may differ from the
names suggested here, so per-test entries should be revisited once that
PR merges.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@eriknordmark eriknordmark requested review from europaul and rene May 10, 2026 08:36
@eriknordmark eriknordmark force-pushed the nim-eden-tests branch 2 times, most recently from 8efafd3 to 6bba2b8 Compare May 15, 2026 07:54
@eriknordmark eriknordmark requested a review from milan-zededa May 16, 2026 20:55
@eriknordmark eriknordmark marked this pull request as ready for review May 16, 2026 20:55
eriknordmark added a commit to eriknordmark/eden that referenced this pull request May 19, 2026
Add two pre-onboard variants of the existing /config ingest tests
(bootstrap_config_item_ingest_preonboard.txt and
global_config_file_ingest_preonboard.txt). Each does its own
eden lifecycle (stop, wipe, eden setup with --eve-bootstrap-file
or --eve-config-dir, eden start; no onboard) and verifies the
distinctive configItem marker reaches
/run/zedagent/ConfigItemValueMap/global.json.

The post-onboard variants of these tests have to work around the
controller-takeover race: parseConfigItems on adam's first config
fetch rebuilds globalConfig from defaults+adam's-items, wiping any
override that came in via the bootstrap pb or the GlobalConfig
file. The bootstrap variant gets away with it because adam echoes
the same configItems back; the GlobalConfig variant cannot, and
falls back to grepping the load notice in the newlog. With adam
never learning the device exists, the configItem-staged values
stay authoritative for the entire verification window and the
pubsub state can be checked directly.

debug.enable.ssh rides inside the staged config and gates sshd's
iptables open via SSHAuthorizedKeys. The SSH-readiness wait
doubles as the bug-class canary: a zedagent that rejects the
bootstrap pb (or fails to apply GlobalConfig) never sets
SSHAuthorizedKeys and the test times out — a loud signal in the
class of lf-edge/eve#5584/#5775.

Tests are not in eden.zedagent.tests.txt; run with
`eden test ./tests/zedagent -e <name>`. The bootstrap variant
reuses preonboard-template.json from
tests/network/testdata/ (added in this PR's parent lf-edge#1165).

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
eriknordmark added a commit to eriknordmark/eden that referenced this pull request May 19, 2026
Add two pre-onboard variants of the existing /config ingest tests
(bootstrap_config_item_ingest_preonboard.txt and
global_config_file_ingest_preonboard.txt). Each does its own
eden lifecycle (stop, wipe, eden setup with --eve-bootstrap-file
or --eve-config-dir, eden start; no onboard) and verifies the
distinctive configItem marker reaches
/run/zedagent/ConfigItemValueMap/global.json.

The post-onboard variants of these tests have to work around the
controller-takeover race: parseConfigItems on adam's first config
fetch rebuilds globalConfig from defaults+adam's-items, wiping any
override that came in via the bootstrap pb or the GlobalConfig
file. The bootstrap variant gets away with it because adam echoes
the same configItems back; the GlobalConfig variant cannot, and
falls back to grepping the load notice in the newlog. With adam
never learning the device exists, the configItem-staged values
stay authoritative for the entire verification window and the
pubsub state can be checked directly.

debug.enable.ssh rides inside the staged config and gates sshd's
iptables open via SSHAuthorizedKeys. The SSH-readiness wait
doubles as the bug-class canary: a zedagent that rejects the
bootstrap pb (or fails to apply GlobalConfig) never sets
SSHAuthorizedKeys and the test times out — a loud signal in the
class of lf-edge/eve#5584/#5775.

Tests are not in eden.zedagent.tests.txt; run with
`eden test ./tests/zedagent -e <name>`. The bootstrap variant
reuses preonboard-template.json from
tests/network/testdata/ (added in this PR's parent lf-edge#1165).

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
eriknordmark added a commit to eriknordmark/eden that referenced this pull request May 19, 2026
Add eden.zedagent-preonboard.tests.txt listing the two
*_preonboard.txt scenarios so they can be invoked as a group via
`eden test ./tests/zedagent -s eden.zedagent-preonboard.tests.txt`
rather than only one-by-one with `-e <name>`. Each preonboard
test manages its own eden lifecycle (stop, wipe, eden setup with
--eve-bootstrap-file or --eve-config-dir, eden start; no onboard)
and leaves eden wiped at exit, so the preonboard scenarios cannot
be interleaved with the post-onboard tests in the main
eden.zedagent.tests.txt — hence a separate manifest rather than
appending. Mirrors PR lf-edge#1165's eden.network-preonboard.tests.txt.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
eriknordmark added a commit to eriknordmark/eden that referenced this pull request May 19, 2026
Add two pre-onboard variants of the existing /config ingest tests
(bootstrap_config_item_ingest_preonboard.txt and
global_config_file_ingest_preonboard.txt). Each does its own
eden lifecycle (stop, wipe, eden setup with --eve-bootstrap-file
or --eve-config-dir, eden start; no onboard) and verifies the
distinctive configItem marker reaches
/run/zedagent/ConfigItemValueMap/global.json.

The post-onboard variants of these tests have to work around the
controller-takeover race: parseConfigItems on adam's first config
fetch rebuilds globalConfig from defaults+adam's-items, wiping any
override that came in via the bootstrap pb or the GlobalConfig
file. The bootstrap variant gets away with it because adam echoes
the same configItems back; the GlobalConfig variant cannot, and
falls back to grepping the load notice in the newlog. With adam
never learning the device exists, the configItem-staged values
stay authoritative for the entire verification window and the
pubsub state can be checked directly.

debug.enable.ssh rides inside the staged config and gates sshd's
iptables open via SSHAuthorizedKeys. The SSH-readiness wait
doubles as the bug-class canary: a zedagent that rejects the
bootstrap pb (or fails to apply GlobalConfig) never sets
SSHAuthorizedKeys and the test times out — a loud signal in the
class of lf-edge/eve#5584/#5775.

Tests are not in eden.zedagent.tests.txt; run with
`eden test ./tests/zedagent -e <name>`. The bootstrap variant
reuses preonboard-template.json from
tests/network/testdata/ (added in this PR's parent lf-edge#1165).

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
eriknordmark added a commit to eriknordmark/eden that referenced this pull request May 19, 2026
Add eden.zedagent-preonboard.tests.txt listing the two
*_preonboard.txt scenarios so they can be invoked as a group via
`eden test ./tests/zedagent -s eden.zedagent-preonboard.tests.txt`
rather than only one-by-one with `-e <name>`. Each preonboard
test manages its own eden lifecycle (stop, wipe, eden setup with
--eve-bootstrap-file or --eve-config-dir, eden start; no onboard)
and leaves eden wiped at exit, so the preonboard scenarios cannot
be interleaved with the post-onboard tests in the main
eden.zedagent.tests.txt — hence a separate manifest rather than
appending. Mirrors PR lf-edge#1165's eden.network-preonboard.tests.txt.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
eriknordmark added a commit to eriknordmark/eden that referenced this pull request May 19, 2026
Adds an Eden testscript suite under tests/zedagent/ that exercises the
zedagent microservice end-to-end against a live EVE instance: device
info, metrics, app/NI info, attestation FSM, and the /config/-ingest
paths consulted at boot. Ten scenarios in two manifests.

eden.zedagent.tests.txt (eight tests, run against an onboarded EVE):
device_info_completeness, config_items_and_status, maintenance_mode,
app_metrics_detail, network_instance_info_metrics, attest_flow (skips
without eve.tpm), bootstrap_config_item_ingest,
global_config_file_ingest. The two /config-ingest scenarios stage a
bootstrap-config.pb or GlobalConfig/global.json after the device is
onboarded, freeze /persist/checkpoint so zedagent cannot recreate
lastconfig, and reboot. bootstrap_config_item_ingest polls
/run/zedagent/ConfigItemValueMap/global.json for its marker (which
survives because adam echoes the same configItems back).
global_config_file_ingest greps the newlog for the
"/config/GlobalConfig contains:" notice instead, because
parseConfigItems on adam's first fetch rebuilds globalConfig from
defaults+adam's-items and wipes any item adam doesn't push — the log
line is the only persistent signal.

eden.zedagent-preonboard.tests.txt (two tests, each owns its full eden
lifecycle — stop, wipe, eden setup with --eve-bootstrap-file or
--eve-config-dir, eden start, no onboard):
bootstrap_config_item_ingest_preonboard,
global_config_file_ingest_preonboard. With adam never learning the
device exists, /config-sourced ConfigItemValueMap stays authoritative
throughout the verification window — no controller-takeover race, no
log-grep fallback needed.

debug.enable.ssh rides inside the staged config in both preonboard
tests and gates sshd's iptables open via SSHAuthorizedKeys. SSH
readiness doubles as the bug-class canary for the
lf-edge/eve#5584/#5775 cert-chain regression class: a zedagent that
rejects the bootstrap pb (or fails to apply GlobalConfig) leaves
SSHAuthorizedKeys unset and the test times out — a loud, race-free
signal.

zedagent_test.go provides TestInfo, TestMetric, and TestFlowLog
helpers that the testscripts invoke via the `test` command. The
preonboard scenarios use preonboard-template.json from PR lf-edge#1165's
tests/network/testdata/. The post-onboard suite was validated against
a QEMU-based coverage-instrumented EVE; the six baseline scenarios
plus the two /config-ingest tests achieve substantially higher
cmd/zedagent coverage than the unit tests alone.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
eriknordmark added a commit to eriknordmark/eden that referenced this pull request May 19, 2026
Adds an Eden testscript suite under tests/zedagent/ that exercises the
zedagent microservice end-to-end against a live EVE instance: device
info, metrics, app/NI info, attestation FSM, and the /config/-ingest
paths consulted at boot. Ten scenarios in two manifests.

eden.zedagent.tests.txt (eight tests, run against an onboarded EVE):
device_info_completeness, config_items_and_status, maintenance_mode,
app_metrics_detail, network_instance_info_metrics, attest_flow (skips
without eve.tpm), bootstrap_config_item_ingest,
global_config_file_ingest. The two /config-ingest scenarios stage a
bootstrap-config.pb or GlobalConfig/global.json after the device is
onboarded, freeze /persist/checkpoint so zedagent cannot recreate
lastconfig, and reboot. bootstrap_config_item_ingest polls
/run/zedagent/ConfigItemValueMap/global.json for its marker (which
survives because adam echoes the same configItems back).
global_config_file_ingest greps the newlog for the
"/config/GlobalConfig contains:" notice instead, because
parseConfigItems on adam's first fetch rebuilds globalConfig from
defaults+adam's-items and wipes any item adam doesn't push — the log
line is the only persistent signal.

eden.zedagent-preonboard.tests.txt (two tests, each owns its full eden
lifecycle — stop, wipe, eden setup with --eve-bootstrap-file or
--eve-config-dir, eden start, no onboard):
bootstrap_config_item_ingest_preonboard,
global_config_file_ingest_preonboard. With adam never learning the
device exists, /config-sourced ConfigItemValueMap stays authoritative
throughout the verification window — no controller-takeover race, no
log-grep fallback needed.

debug.enable.ssh rides inside the staged config in both preonboard
tests and gates sshd's iptables open via SSHAuthorizedKeys. SSH
readiness doubles as the bug-class canary for the
lf-edge/eve#5584/#5775 cert-chain regression class: a zedagent that
rejects the bootstrap pb (or fails to apply GlobalConfig) leaves
SSHAuthorizedKeys unset and the test times out — a loud, race-free
signal.

zedagent_test.go provides TestInfo, TestMetric, and TestFlowLog
helpers that the testscripts invoke via the `test` command. The
preonboard scenarios use preonboard-template.json from PR lf-edge#1165's
tests/network/testdata/. The post-onboard suite was validated against
a QEMU-based coverage-instrumented EVE; the six baseline scenarios
plus the two /config-ingest tests achieve substantially higher
cmd/zedagent coverage than the unit tests alone.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
eriknordmark and others added 8 commits May 20, 2026 11:42
Add two escript scenarios covering the NIM startup file-ingest path that
no Go unit test reaches: cmd/nim/nim.go ingestDevicePortConfig() and
ingestDevicePortConfigFile(), plus the hasPersistLastconfig() short-circuit.

nim_lastconfig_blocks_ingest verifies that with /persist/checkpoint/lastconfig
present NIM emits the explicit suppression log line, leaves
/run/global/DevicePortConfig/ empty, and adds no "override" entry to
DevicePortConfigList.

nim_override_json_ingest verifies that with lastconfig deleted and the
/persist/checkpoint directory chattr +i'd to defeat zedagent's race to
recreate it, NIM picks up an override.json under /config/DevicePortConfig/,
copies it to /run/global/DevicePortConfig/, registers the "override" key
in DevicePortConfigList, and stamps ConfigSource.Origin = OVERRIDE (=3).

Both scripts mount /dev/sda4 (vfat CONFIG partition) at runtime to inject
the override file, since /config is a read-only tmpfs at runtime in the
QEMU/LinuxKit EVE image. They also document a non-obvious eden CLI gotcha:
`eden eve ssh '<multi-line>'` collapses newlines to spaces, so all
multi-command shell snippets must be joined with `;` or `&&` on a single
line.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extend the NIM startup-matrix coverage from 2 to 6 of the 6 rows in the
matrix documented in pkg/pillar/docs/nim-eden-test-plan.md.

nim_usb_json_ingest (R1, sibling of override case) — verifies that
ingestDevicePortConfigFile() derives DPC.Key from the file basename
when the JSON has no explicit Key field, so a usb.json results in
DPCList["usb"] not DPCList["override"].

nim_bootstrap_supersedes_override (R3) — verifies cmd/nim's bootstrap-
skip branch: when /config/bootstrap-config.pb is present, legacy
*.json files under /config/DevicePortConfig/ are NOT copied into
/run/global/. The test deliberately uses a 1-byte placeholder pb
because cmd/nim only checks file existence, not content.

nim_lastconfig_blocks_bootstrap (R6) — verifies the
expectBootstrapDPCs reset branch at nim.go:214: with lastconfig
present, NIM does not wait for an installer DPC even if
bootstrap-config.pb exists. Asserts steady-state (DPCList has
zedagent entry) and that the pb file is not consumed/deleted.

nim_bootstrap_only (R2) — exercises the full bootstrap-pb decode path
end-to-end: signed pb on /config, lastconfig deleted, NIM ingests via
zedagent's republish. Currently `skip`'d via [!exec:nim-bootstrap-pb-gen]
until that host-side helper is added; the binary's specification is
documented in the file's header.

All four reuse the patterns established by nim_lastconfig_blocks_ingest
and nim_override_json_ingest: /dev/sda4 mount for /config writes,
chattr +i on /persist/checkpoint to defeat zedagent's lastconfig-
recreate race, semicolon-joined ssh commands (multi-line single-quoted
ssh strings collapse newlines to spaces), and DPCList polling (durable)
rather than /run/global/ polling (tmpfs-wiped).

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds tests/network/cmd/nim-bootstrap-pb-gen, a host-side helper that
signs an EdgeDevConfig JSON into a /config/bootstrap-config.pb using
the eden controller signing key. The nim_bootstrap_*.txt testdata
invokes it at runtime to stage controllable bootstrap configs and
verify content-level round-trip behavior — a distinctive
Logicallabel baked into the bootstrap pb reappears in the device's
DevicePortConfigList, confirming end-to-end propagation from
/config to NIM's pubsub state.

The testdata writes to the CONFIG partition via
`eve config mount /run/<path>`, a device-agnostic interface that
exposes the persistent partition read/write regardless of which
block device backs it.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
nim_dpcl_reapplied_after_reboot — two-reboot test that isolates the
pubsub persistent-publication reload path from any re-ingestion.
First reboot stages and ingests an override.json under a distinctive
Logicallabel "reapply-test" with TimePriority=1990-01-01 (the entry
stays in DPCList without becoming the active DPC, so eth0's
effective Logicallabel is unchanged for subsequent tests). Second
reboot removes the file and clears the chattr +i directory flag so
the override CANNOT be re-ingested. The DPCList entry surviving the
second reboot is positive evidence that NIM's pubDevicePortConfigList
(Persistent:true) is being reloaded on agent startup. Without this
isolation, every other test re-ingests the file it observes, masking
a regression in the persistent reload path.

nim_flowlog_acl_reconcile — toggle test that drives the flowlog
gate end to end: NetworkInstanceConfig with EnableFlowlog=false
produces no CONNMARK marking rules in iptables mangle table; with
EnableFlowlog=true the "SSH and Guacamole mark" multiport rule
(matching tcp dports 22,4822) appears via DpcReconciler's
getIntendedMarkingRules; deleting the NI removes the rules again.
Skips itself on kube EVE because r.HVTypeKube unconditionally
installs the marking rules regardless of EnableFlowlog, which
makes the iptables witness incapable of distinguishing the two
states.

Both tests use the established test idioms (eve config mount,
eve exec pillar jq, single-line ssh, defensive pre-cleanup,
3-consecutive-success ssh stabilization).

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
LPS multi-port + wireless mismatch, diag-endpoint GCP propagation)

radio_silence_persistence (eclient) — extends radio_silence.txt by
toggling radio silence ON via the local-manager LPS server, then
rebooting EVE and asserting that
/run/zedagent/ZedAgentStatus/zedagent.json on the device still
carries RadioSilence.Imposed=true after the reboot (the pubsub
topic file is keyed by agent name, so the path is zedagent.json,
not global.json). The assertion reads EVE-side pubsub directly so
it does not depend on the LPS app having reconnected. Exercises
zedagent's lastradioconfig persistence on disk and NIM's
subZedAgentStatus subscription delivering the restored
ZedAgentStatus on a fresh boot through cmd/nim.handleZedAgentStatusImpl.

A reset-radio-state.sh helper wipes /persist/checkpoint/lastradioconfig
and reboots before the test starts, so the precondition
wait-radio-status=false converges even if a prior test or a prior
failed run left lastradioconfig with Imposed=true. The substantive
test claim is the post-reboot Imposed=true read; the test does not
depend on a post-reboot toggle-OFF round-trip, which can hang on
the EVE write path.

lps_all_mgmt_ports_overridden (eclient) — applies an LPS local
network config that overrides BOTH eth0 (DNS) and eth1 (MTU) on the
QEMU device model where both adapters are management uplinks. After
both ports flip to configApplied=true via the local-manager API, the
test asserts the behavioural witnesses on the device — resolv.conf
shows the LPS-supplied DNS, ifconfig shows the LPS-supplied MTU.
Exercises dpcmanager/lps.go loadLpsConfig and mergeWithLpsConfig in
the multi-port case — the structural precondition of
areAllMgmtPortUsingLpsConfig() suppression. (The actual fallback
suppression behaviour requires SDN-driven controller-failure
injection and is out of scope.)

lps_wireless_type_mismatch (eclient) — sends an LPS config for eth0
with WirelessDeviceType=WIRELESS_TYPE_WIFI on the QEMU model where
eth0 has WirelessType=None. The pre-merge guard in
mergeWithLpsConfig rejects the LPS port. Test asserts the
distinctive "wireless type mismatch" error string in the
local-manager network-info, configApplied=false on the LPS side,
and configApplied=true on the controller side. Cleanly skips on
the QEMU device model since both adapters are Ethernet — any LPS
DPC with WIRELESS_TYPE_WIFI is rejected upstream with "missing
WiFi configuration" rather than reaching the branch under test;
activating this test requires a custom devmodel.json with a
wireless port.

nim_diag_remote_endpoints (network) — sets
diag.probe.remote.http.endpoint via eden controller update and
asserts the new value reaches
/run/zedagent/ConfigItemValueMap/global.json under
.GlobalSettings["diag.probe.remote.http.endpoint"].StrValue.
Tests the upstream propagation (eden→adam→zedagent) only; the
downstream NIM consumption (in-memory connTester.DiagRemoteEndpoints
and the actual probes on controller failure) needs SDN-driven
failure injection and is documented as out of scope.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds four pre-onboard variants of the NIM /config-ingest tests:

- nim_bootstrap_only_preonboard
- nim_bootstrap_supersedes_override_preonboard
- nim_override_only_preonboard
- nim_globalconfig_only_preonboard

Each test owns its full eden lifecycle (stop, wipe, eden setup with
--eve-bootstrap-file or --eve-config-dir, eden start; no onboard).
With adam never learning the device exists, /config-sourced state
stays authoritative for the entire verification window, closing the
controller-takeover race that makes the onboarded
nim_bootstrap_supersedes_override test a known false negative.

debug.enable.ssh rides inside the staged config in every variant
and gates sshd's iptables open via SSHAuthorizedKeys. SSH readiness
doubles as the bug-class canary for the lf-edge/eve#5584/#5775
cert-chain regression class: when zedagent rejects the bootstrap pb
(or fails to apply GlobalConfig), SSHAuthorizedKeys is never set,
the iptables INPUT rule for tcp/22 stays REJECT, and the test
times out — a race-free signal.

The four tests share preonboard-template.json (a sanitized
EdgeDevConfig template) and are grouped in
eden.network-preonboard.tests.txt for invocation via
`eden test ./tests/network -s eden.network-preonboard.tests.txt`.
tests/network/Makefile's setup target globs *.tests.txt so any
additional manifest in the directory stages alongside the default
eden.network.tests.txt automatically.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Yetus's detsecrets (detect-secrets v1.2.0) plugin flags the
literal password value as Secret Keyword. The value is
meaningless -- the test rejects the port on wireless-type
mismatch before any credentials are inspected -- but the keyword
detector pattern-matches "password": "<any-string>" and trips.
detect_secrets/filters/heuristic.py is_templated_secret exempts
values shaped like <foo>, so use "<redacted>" as the sentinel.
Test still exercises the same code path with no behavioural
change.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Go's -test.run is a regex. Unanchored, "TestEdenScripts/radio_silence"
prefix-matches both the existing radio_silence test and the
radio_silence_persistence test added earlier in this branch. They
end up running in parallel within one eden.escript.test process
against the same EVE instance, and radio_silence_persistence's
reboot disrupts radio_silence's assertions on the live device --
seen on the latest CI as radio_silence FAIL alongside
radio_silence_persistence PASS in the LPS/LOC job. Anchor the
existing scenario regex with $ so it matches only the original
test name; quote the argument to keep the shell happy with $.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
eriknordmark and others added 2 commits May 20, 2026 13:17
The effective ConfigItemValueMap pubsub topic location depends on
the topic's Persistent flag at publication time, which is not stable
across EVE releases. On current master/HEAD it lives at
/run/zedagent/ConfigItemValueMap/global.json (transient). On 16.6.0
release it lives at /persist/status/zedagent/ConfigItemValueMap/global.json
(persistent). The marker assertion now probes /run first and falls
back to /persist, so the same testscript validates on both.

Wrapped the fallback as a single-line, semicolon-joined remote
command -- `eden eve ssh '<multi-line>'` collapses newlines into
spaces, which mangled an earlier multi-line form. Validated end-to-end
against eve tag 16.6.0 (test passes in ~103s).

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
nim_diag_remote_endpoints hardcoded
/run/zedagent/ConfigItemValueMap/global.json for its
diag.probe.remote.http.endpoint marker check. That path exists on
master/HEAD but on 16.6.0 the topic is /persist-resident at
/persist/status/zedagent/ConfigItemValueMap/global.json -- the same
asymmetry that bit nim_globalconfig_only_preonboard. Probe /run
first and fall back to /persist via a single-line ssh command
(eden eve ssh collapses newlines), then parse locally with jq to
avoid shell-quoting trouble with the bracket-quoted jq path.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant