[ {"name": "a minimal IPv4 entry is valid and passed through", "args": [{"name": "router", "host": "192.168.1.1", "ports": [22, 80]}], "expect": {"valid": true, "errors": [], "name": "router", "host": "192.168.1.1", "hostKind": "ipv4", "ports": [22, 80], "mac": null, "subnet": null}}, {"name": "name is trimmed, MAC made canonical, subnet host bits cleared", "args": [{"name": " core switch ", "host": "10.0.0.2", "ports": [22], "mac": "AA-BB-CC-DD-EE-FF", "subnet": "10.0.0.77/24"}], "expect": {"valid": true, "errors": [], "name": "core switch", "host": "10.0.0.2", "hostKind": "ipv4", "ports": [22], "mac": "aa:bb:cc:dd:ee:ff", "subnet": "10.0.0.0/24"}}, {"name": "an IPv6 host and subnet are written in RFC 5952 form", "args": [{"name": "v6", "host": "2001:DB8:0:0:0:0:0:1", "ports": [443], "subnet": "2001:db8::ffff/32"}], "expect": {"valid": true, "errors": [], "name": "v6", "host": "2001:db8::1", "hostKind": "ipv6", "ports": [443], "mac": null, "subnet": "2001:db8::/32"}}, {"name": "a host name is lower-cased and loses its trailing dot", "args": [{"name": "nas", "host": "NAS.Example.COM.", "ports": [445], "mac": "aabb.ccdd.eeff"}], "expect": {"valid": true, "errors": [], "name": "nas", "host": "nas.example.com", "hostKind": "hostname", "ports": [445], "mac": "aa:bb:cc:dd:ee:ff", "subnet": null}}, {"name": "null optional fields are the same as leaving them out", "args": [{"name": "x", "host": "x", "ports": [1], "mac": null, "subnet": null}], "expect": {"valid": true, "errors": [], "name": "x", "host": "x", "hostKind": "hostname", "ports": [1], "mac": null, "subnet": null}}, {"name": "an empty entry lists every required field", "args": [{}], "expect": {"valid": false, "errors": ["name is required", "host is required", "ports is required"], "name": null, "host": null, "hostKind": null, "ports": [], "mac": null, "subnet": null}}, {"name": "wrong types are named field by field", "args": [{"name": 5, "host": ["x"], "ports": "22", "mac": 1, "subnet": true}], "expect": {"valid": false, "errors": ["name must be text", "host must be text", "ports must be a list", "mac must be text", "subnet must be text"], "name": null, "host": null, "hostKind": null, "ports": [], "mac": null, "subnet": null}}, {"name": "every bad port is reported with its index; 8080.0 is port 8080", "args": [{"name": "a", "host": "a.example", "ports": [0, 22.5, "80", 443, 443, 65536, 8080.0, true]}], "expect": {"valid": false, "errors": ["ports[0] 0 is not a port (1-65535)", "ports[1] must be a whole number", "ports[2] must be a whole number", "ports[4] 443 is listed twice", "ports[5] 65536 is not a port (1-65535)", "ports[7] must be a whole number"], "name": "a", "host": "a.example", "hostKind": "hostname", "ports": [443, 8080], "mac": null, "subnet": null}}, {"name": "an empty port list is refused", "args": [{"name": "a", "host": "10.0.0.1", "ports": []}], "expect": {"valid": false, "errors": ["ports must not be empty"], "name": "a", "host": "10.0.0.1", "hostKind": "ipv4", "ports": [], "mac": null, "subnet": null}}, {"name": "192.168.1.256 is neither an address nor a host name (numeric top-level label)", "args": [{"name": "bad", "host": "192.168.1.256", "ports": [80]}], "expect": {"valid": false, "errors": ["host \"192.168.1.256\" is not an IPv4 address, IPv6 address or host name: top-level label is all numeric"], "name": "bad", "host": null, "hostKind": null, "ports": [80], "mac": null, "subnet": null}}, {"name": "a leading-zero quad is refused rather than read as octal or as a name", "args": [{"name": "octal", "host": "010.0.0.1", "ports": [80]}], "expect": {"valid": false, "errors": ["host \"010.0.0.1\" is not an IPv4 address, IPv6 address or host name: top-level label is all numeric"], "name": "octal", "host": null, "hostKind": null, "ports": [80], "mac": null, "subnet": null}}, {"name": "a doubled dot is an empty label", "args": [{"name": "p", "host": "printer..office", "ports": [631]}], "expect": {"valid": false, "errors": ["host \"printer..office\" is not an IPv4 address, IPv6 address or host name: empty label"], "name": "p", "host": null, "hostKind": null, "ports": [631], "mac": null, "subnet": null}}, {"name": "a blank name and an empty host", "args": [{"name": " ", "host": "", "ports": [22]}], "expect": {"valid": false, "errors": ["name must not be empty", "host \"\" is not an IPv4 address, IPv6 address or host name: empty"], "name": null, "host": null, "hostKind": null, "ports": [22], "mac": null, "subnet": null}}, {"name": "a trailing newline makes the host invalid", "args": [{"name": "nl", "host": "10.0.0.1\n", "ports": [22]}], "expect": {"valid": false, "errors": ["host \"10.0.0.1\n\" is not an IPv4 address, IPv6 address or host name: character other than a letter, digit, hyphen or dot"], "name": "nl", "host": null, "hostKind": null, "ports": [22], "mac": null, "subnet": null}}, {"name": "a bad MAC and a bad subnet are both reported", "args": [{"name": "m", "host": "10.1.1.1", "ports": [22], "mac": "aa:bb:cc:dd:ee:gg", "subnet": "10.0.0.0/33"}], "expect": {"valid": false, "errors": ["mac \"aa:bb:cc:dd:ee:gg\" is not valid: not a hex digit", "subnet \"10.0.0.0/33\" is not a CIDR block"], "name": "m", "host": "10.1.1.1", "hostKind": "ipv4", "ports": [22], "mac": null, "subnet": null}}, {"name": "a subnet without a prefix is not a CIDR block", "args": [{"name": "s", "host": "10.1.1.1", "ports": [22], "subnet": "10.0.0.0"}], "expect": {"valid": false, "errors": ["subnet \"10.0.0.0\" is not a CIDR block"], "name": "s", "host": "10.1.1.1", "hostKind": "ipv4", "ports": [22], "mac": null, "subnet": null}}, {"name": "unknown fields are reported in sorted order after everything else", "args": [{"zone": "a", "name": "x", "host": "x", "ports": [1], "colour": "b"}], "expect": {"valid": false, "errors": ["unknown field \"colour\"", "unknown field \"zone\""], "name": "x", "host": "x", "hostKind": "hostname", "ports": [1], "mac": null, "subnet": null}} ]