feat: alternative fingerprint rules count once (4.8.0)
Discovery compares drivers by score divided by the most a driver could score, and that maximum summed every positive rule. Rules that never match together, such as one vendor's landing page or another's, made a driver that knows several vendors lose to one that knows none: napalm-redfish's Supermicro landing page scored 6 of 41 and lost to a bare "linux" in the same BMC's SNMP sysDescr, 5 of 18. FingerprintRule gets an optional group. rules_max_weight() sums the positive rules and counts each group once, with its strongest rule. Existing rules have no group and count as before.
This commit is contained in:
1 parent
7afa590c0c
commit
a1da0337e2
5 files changed
+97
-2
No files matched your search
@@ -8,6 +8,7 @@ from napalm_device_types import (
|
||||
DeviceTypeDriver,
|
||||
FingerprintRule,
|
||||
FirewallDriver,
|
||||
rules_max_weight,
|
||||
HypervisorDriver,
|
||||
OSDriver,
|
||||
PortSpec,
|
||||
@@ -90,6 +91,53 @@ def test_fingerprint_rule_negative():
|
||||
assert r.negative is True
|
||||
|
||||
|
||||
def test_fingerprint_rule_has_no_group_by_default():
|
||||
assert FingerprintRule("fritz!box").group is None
|
||||
|
||||
|
||||
def test_fingerprint_rule_group():
|
||||
r = FingerprintRule("idrac", weight=6.0, group="landing_page")
|
||||
assert r.group == "landing_page"
|
||||
|
||||
|
||||
# ── rules_max_weight: the most a set of rules can add ─────────────────────────
|
||||
|
||||
def test_max_weight_sums_rules_that_can_match_together():
|
||||
rules = [FingerprintRule("proxmox virtual environment", 9.0), FingerprintRule("pve", 2.0)]
|
||||
assert rules_max_weight(rules) == 11.0
|
||||
|
||||
|
||||
def test_max_weight_counts_one_rule_per_group():
|
||||
# Alternatives: a page is ATEN's or iDRAC's or iLO's, never all three. Summing
|
||||
# them made a driver that knows three BMC families lose to one that knows none.
|
||||
rules = [
|
||||
FingerprintRule("aten international", 6.0, group="landing_page"),
|
||||
FingerprintRule("idrac", 6.0, group="landing_page"),
|
||||
FingerprintRule("integrated lights-out", 4.0, group="landing_page"),
|
||||
]
|
||||
assert rules_max_weight(rules) == 6.0
|
||||
|
||||
|
||||
def test_max_weight_mixes_groups_and_single_rules():
|
||||
rules = [
|
||||
FingerprintRule("redfishversion", 10.0, group="redfish_answer"),
|
||||
FingerprintRule("@message.extendedinfo", 8.0, group="redfish_answer"),
|
||||
FingerprintRule("#serviceroot.", 5.0),
|
||||
FingerprintRule("aten international", 6.0, group="landing_page"),
|
||||
FingerprintRule("idrac", 6.0, group="landing_page"),
|
||||
]
|
||||
assert rules_max_weight(rules) == 21.0
|
||||
|
||||
|
||||
def test_max_weight_ignores_negative_rules():
|
||||
rules = [FingerprintRule("vcenter", 9.0), FingerprintRule("vmware esxi", 9.0, negative=True)]
|
||||
assert rules_max_weight(rules) == 9.0
|
||||
|
||||
|
||||
def test_max_weight_of_no_rules_is_zero():
|
||||
assert rules_max_weight([]) == 0.0
|
||||
|
||||
|
||||
def test_fingerprint_rule_is_immutable():
|
||||
r = FingerprintRule("test", weight=3.0)
|
||||
with pytest.raises(AttributeError):
|
||||
|
||||
Reference in new issue
Block a user