Closes netork#117. A Yealink is a desk phone. It inherited AccessPointDriver because nothing better existed, and netOrk reads that role to populate its wireless page, its AP profile pickers and its SSID drift view — so a phone appeared in all three. napalm-device-types now has PhoneDriver. TYPE_LABEL comes from it, so the local override is gone. The two failing fingerprint tests were asserting the opposite of a deliberate decision. HTTP_FINGERPRINT carries "yealink" as a heavy but *not* mandatory rule, with the reason written next to it: some models answer / with a redirect to their API page, whose body says "yealink" nowhere, and a mandatory rule disqualifies the driver whenever its pattern is absent. Making it mandatory would rule out a real phone. The tests demanded it be mandatory, and the Cisco test then asserted `not all(...)` over an empty list, which is False. Both now check the property that actually protects against a false match: none of this driver's patterns appear on a Cisco page, so it contributes no score and never wins.
61 lines
2.2 KiB
Python
61 lines
2.2 KiB
Python
"""Fingerprint tests for YealinkDriver."""
|
|
|
|
from napalm_device_types import DeviceTypeDriver, PhoneDriver, role_keys_of
|
|
from napalm_yealink import YealinkDriver
|
|
|
|
|
|
def test_yealink_is_device_type_driver():
|
|
assert issubclass(YealinkDriver, DeviceTypeDriver)
|
|
|
|
|
|
def test_type_label():
|
|
assert YealinkDriver.TYPE_LABEL == "Phone"
|
|
|
|
|
|
def test_vendor():
|
|
assert YealinkDriver.VENDOR == "Yealink"
|
|
|
|
|
|
def test_driver_name():
|
|
assert YealinkDriver.DRIVER_NAME == "yealink"
|
|
|
|
|
|
def test_snmp_oid_prefix():
|
|
assert YealinkDriver.SNMP_OBJECT_ID_PREFIX == "1.3.6.1.4.1.37403"
|
|
|
|
|
|
def test_yealink_pattern_is_decisive_but_not_mandatory():
|
|
"""A mandatory rule disqualifies the driver whenever the pattern is absent.
|
|
|
|
Some Yealink models answer / with a redirect to their API page, whose body
|
|
carries no "yealink" anywhere — making the rule mandatory would rule out a
|
|
real Yealink phone. It carries decisive weight instead, so a page that does
|
|
say "yealink" still wins by a wide margin.
|
|
"""
|
|
yealink_rules = [r for r in YealinkDriver.HTTP_FINGERPRINT if r.pattern == "yealink"]
|
|
assert yealink_rules, "the vendor pattern must be present at all"
|
|
assert all(not r.mandatory for r in yealink_rules)
|
|
assert max(r.weight for r in yealink_rules) >= 10.0
|
|
|
|
|
|
def test_fingerprint_matches_t58_title():
|
|
"""'Yealink T58 Phone' im Titel → mandatory 'yealink' trifft zu."""
|
|
combined = "yealink t58 phone nginx "
|
|
mandatory = [r for r in YealinkDriver.HTTP_FINGERPRINT if r.mandatory]
|
|
assert all(r.pattern in combined for r in mandatory)
|
|
|
|
|
|
def test_fingerprint_scores_nothing_on_a_cisco_page():
|
|
"""Without a mandatory rule, what keeps a Cisco phone out is that none of
|
|
Yealink's patterns match it at all — so the driver contributes zero score
|
|
and never wins."""
|
|
combined = "cisco ip phone cp-8841 "
|
|
assert not any(r.pattern in combined for r in YealinkDriver.HTTP_FINGERPRINT)
|
|
|
|
|
|
def test_declares_the_phone_role_not_access_point():
|
|
"""A desk phone used to inherit AccessPointDriver for want of anywhere
|
|
better, which put it in netOrk's wireless page and AP profile pickers."""
|
|
assert issubclass(YealinkDriver, PhoneDriver)
|
|
assert role_keys_of(YealinkDriver) == ["phone"]
|