Fix: NIC child presence no longer forces a directly-detected parent offline (#1736) - #1739
Conversation
…ffline When a parent device has NIC children, update_devPresentLastScan_based_on_nics previously replaced the parent's devPresentLastScan unconditionally with the NIC-derived value. This discarded any genuine direct detection of the parent: if the parent was found by ARP/save_own_device (present=1) but its NIC child was absent (present=0), the NIC step forced the parent back to 0. The next scan re-detected the parent → Connected event → NIC forced it down again, producing an endless one-directional Connected event stream. Fix: use max(original, nic_derived) so NIC children can only raise a parent's presence (bring an undetected parent online), never lower it when the parent itself was directly detected this cycle. Adds test/scan/test_nic_presence.py covering the exact regression scenario and surrounding cases (raise, no-NIC unchanged, req_all modes). Fixes #1736 Co-authored-by: jokob-sk <96159884+jokob-sk@users.noreply.github.com>
jokob-sk
left a comment
There was a problem hiding this comment.
also target next_release branch, not main
| # Helpers | ||
| # --------------------------------------------------------------------------- | ||
|
|
||
| def _make_db(rows): |
There was a problem hiding this comment.
do not mock DB, use main/test/db_test_helpers.py where-ever possible
There was a problem hiding this comment.
Done in the latest commit — the test now uses make_db, make_device_dict, insert_device_from_dict, and DummyDB from db_test_helpers.
| {"mac": "AA:AA:AA:AA:AA:01", "present": 1, | ||
| "parent_mac": "", "rel_type": "", "req_all": 0}, | ||
| {"mac": "BB:BB:BB:BB:BB:01", "present": 0, | ||
| "parent_mac": "AA:AA:AA:AA:AA:01", "rel_type": "nic", "req_all": 0}, |
There was a problem hiding this comment.
macs always lower case every where
There was a problem hiding this comment.
Fixed — all MACs are now lowercase (e.g. aa:aa:aa:aa:aa:01).
| nic_derived = int(any(nic_statuses)) | ||
| # NIC children can only raise a parent's presence, never lower it | ||
| # when the parent itself was directly detected as present this scan. | ||
| new_present = max(original, nic_derived) |
There was a problem hiding this comment.
make it easier to read, suing max() obfuscates logic
There was a problem hiding this comment.
Replaced with explicit if original == 1: pass / else: new_present = 1 if nic_online else 0 — each case is now clearly stated.
- Replace max() with explicit if/else for readability - Use db_test_helpers (make_db, make_device_dict, insert_device_from_dict, DummyDB) instead of local mock DB objects in test_nic_presence.py - Lowercase all MAC addresses in tests Co-authored-by: jokob-sk <96159884+jokob-sk@users.noreply.github.com>
The base branch of a PR can only be changed from the GitHub UI (Edit → Change base). Please retarget it to |
|
@copilot why didn't you follow the ai guidelines - if needed, update them or add/update skills? |
Co-authored-by: jokob-sk <96159884+jokob-sk@users.noreply.github.com>
Two skills were referenced in Fixed in the latest commit: both skills are now created in |
|
@copilot
... will you next time follow these based on available guidelines and skills? if not update those to make this explicit |
| @@ -0,0 +1,146 @@ | |||
| """Tests for update_devPresentLastScan_based_on_nics. | |||
There was a problem hiding this comment.
@copilot
will those skill prevent the issues I had to comment on for you to fix in the last 2 PRs?:
always use existing helpers in tests if available, or extend teh helpers class, follow DRY wherever possible, in this case main/test/db_test_helpers.py
mocked MACs should always be lower case
... will you next time follow these based on available guidelines and skills? if not update those to make this explicit
There was a problem hiding this comment.
The existing code-standards rule mentioned reusing db_test_helpers.py and normalizing MACs, but not explicitly enough to catch test fixture literals. Updated in the latest commit:
code-standards: new dedicated "MAC Literals in Tests — ALWAYS Lowercase" section with explicit wrong/right examples.pr-analysis(Copilot + Gemini): new "Before Writing Any Test Code" checklist placed before any other action — lowercase MAC literals and helpers-first are listed as non-negotiable gates, not just a post-batch reminder.
…analysis skills Co-authored-by: jokob-sk <96159884+jokob-sk@users.noreply.github.com>
... The existing
|
update_devPresentLastScan_based_on_nicsunconditionally replaced the parent'sdevPresentLastScanwith the NIC-derived value, discarding the parent's own direct detection. When a parent was genuinely present (ARP /save_own_device) but had an absent NIC child, the NIC step forced it to0. The next scan re-detected it →Connectedevent → NIC forced it back to0→ endless one-directional event flood.Change
server/scan/device_handling.py—update_devPresentLastScan_based_on_nics:max(original, nic_derived)ensures:original=1) → stays1regardless of NIC child stateoriginal=0) → NIC children can still bring it onlinereq_allmodestest/scan/test_nic_presence.py— new test file covering the exact regression (parentpresent=1+ absent NIC → stays1), NIC raise cases,req_allvariants, and the no-NIC-children no-change path.🔍 Related Issues
Closes #1736
📋 Type of Change
📷 Screenshots or Logs (if applicable)
From the issue — before the fix, every scan cycle produced a spurious
Connectedevent for a device that was continuously present:🧪 Testing Steps
Unit tests in
test/scan/test_nic_presence.pycover the regression and surrounding cases directly without requiring the full stack.✅ Checklist
🙋 Additional Notes
The
max(original, nic_derived)formulation is intentionally minimal — it threads through bothreq_allmodes with no branching onoriginal, and preserves the existing "NIC can raise an absent parent" semantics unchanged.