Part of the whole-repo test-suite audit (2026-09-30). Test error paths, not just happy paths: every branch that can fail needs a test.
What to build
Negative tests for every reject path in the three deserialise/parse surfaces, and a test that pins the on-disk state format.
Findings
crates/natmap/src/models.rs and crates/natmap/tests/model.rs contain no unwrap_err or is_err at all. Untested:
- Unknown
"proto":"xyz" deserialising into TransportProtocol (models.rs:30,119,248,268). The rejecting arm lives at crates/lab-lib/src/protocol.rs:34 and has only a doc test.
- Missing required fields:
DnatRequest.ext_ip/int_ip/ports, SnatRequest.ext_if, HairpinRequest.ext_ip, RProxyLocalConfig.template, ForwardRemoteConfig.port.
u16 out of range: ForwardLocalConfig.port, ForwardRemoteConfig.port, ext_ports entries, DockerAddMapRequest.host_port/container_port.
u32 out of range: PolicyRouteConfig.table and its request twin.
DaemonState (models.rs:338) state-file compatibility. policy_routes carries #[serde(default)] at :348; mapping, dnats, snats and hairpins do not. A state file written before policy_routes existed loads; a file missing any other top-level key hard-errors. This is a real on-disk format at /var/lib/natmap/state.json, and the forward path is untested.
crates/auto-discover/src/config.rs: the entire YAML surface is untested. Both existing tests (:458, :485) construct DiscoveryConfig structs directly; neither deserialises YAML. Untested: an unknown type: value, a missing node.name, a missing required type:, a missing template, and a port out of range.
src/cmd/dns_parser.rs:
:52 caps[2].parse().unwrap_or(1): the TTL-parse-failure fallback to 1 is untested.
:146 parts[0][1..].parse().unwrap_or(0): a non-numeric TLSA port label (_abc._tcp.mail) is untested.
:170 TXT.captures_iter on an unterminated quote ("abc, no closing ") is untested. parse_txt_data_no_quotes (:501) covers zero quotes, not a broken one.
Acceptance criteria
Blocked by
None (can start immediately).
Also: docs/dev/testing.md:53 undercounts the suite by roughly 4× (it says 88 inline unit tests; the real figure is 421 tests). Correct it while in this file.
Part of the whole-repo test-suite audit (2026-09-30). Test error paths, not just happy paths: every branch that can fail needs a test.
What to build
Negative tests for every reject path in the three deserialise/parse surfaces, and a test that pins the on-disk state format.
Findings
crates/natmap/src/models.rsandcrates/natmap/tests/model.rscontain nounwrap_erroris_errat all. Untested:"proto":"xyz"deserialising intoTransportProtocol(models.rs:30,119,248,268). The rejecting arm lives atcrates/lab-lib/src/protocol.rs:34and has only a doc test.DnatRequest.ext_ip/int_ip/ports,SnatRequest.ext_if,HairpinRequest.ext_ip,RProxyLocalConfig.template,ForwardRemoteConfig.port.u16out of range:ForwardLocalConfig.port,ForwardRemoteConfig.port,ext_portsentries,DockerAddMapRequest.host_port/container_port.u32out of range:PolicyRouteConfig.tableand its request twin.DaemonState(models.rs:338) state-file compatibility.policy_routescarries#[serde(default)]at:348;mapping,dnats,snatsandhairpinsdo not. A state file written beforepolicy_routesexisted loads; a file missing any other top-level key hard-errors. This is a real on-disk format at/var/lib/natmap/state.json, and the forward path is untested.crates/auto-discover/src/config.rs: the entire YAML surface is untested. Both existing tests (:458,:485) constructDiscoveryConfigstructs directly; neither deserialises YAML. Untested: an unknowntype:value, a missingnode.name, a missing requiredtype:, a missingtemplate, and aportout of range.src/cmd/dns_parser.rs::52caps[2].parse().unwrap_or(1): the TTL-parse-failure fallback to 1 is untested.:146parts[0][1..].parse().unwrap_or(0): a non-numeric TLSA port label (_abc._tcp.mail) is untested.:170TXT.captures_iteron an unterminated quote ("abc, no closing") is untested.parse_txt_data_no_quotes(:501) covers zero quotes, not a broken one.Acceptance criteria
DaemonStatecompatibility is pinned: a state file with and withoutpolicy_routesboth load, and a file missing a required top-level key is rejectedserde_yamlstandards.md§3.6cargo test -p lab-ops_natmap,cargo test -p lab-ops_auto-discover,cargo test -p lab-ops --libpassBlocked by
None (can start immediately).
Also:
docs/dev/testing.md:53undercounts the suite by roughly 4× (it says 88 inline unit tests; the real figure is 421 tests). Correct it while in this file.