Most domains declare validation the tests never exercise. Removing one of those tags from a spec would change nothing a test could see.
Corrected method
This issue originally counted test methods named ValidationHTTP and concluded log had none. That was wrong: log tested valid_target and the priority oneof inside a method named TestGetNodeLogHTTP. Counting names measures naming, not coverage.
The right comparison is the validate: tags each spec declares against the rule names the tests assert:
python3 - <<'PY'
import pathlib, re
for d in sorted(pathlib.Path('internal/controller/api/node').iterdir()):
spec = d/'gen'/'api.yaml'
if not spec.is_file(): continue
rules = {p.strip().split('=')[0]
for m in re.findall(r'validate:\s*"?([^"\n]+)"?', spec.read_text())
for p in m.split(',')
if p.strip() and p.strip().split('=')[0] not in ('omitempty','required')}
asserted = {m for t in d.glob('*_test.go')
for m in re.findall(r'Body\.String\(\), "([a-z_]+)"', t.read_text())}
print(f"{d.name:14} {len(rules):5} {len(rules & asserted):6} {' '.join(sorted(rules - asserted)) or '-'}")
PY
What it finds
domain rules tested untested
hostname 3 0 max min valid_target
schedule 7 1 cron_schedule excluded_with max min oneof required_without
file 5 1 file_mode max min oneof
user 4 1 account_name dive min
container 6 3 dive min oneof
network 12 6 dive ipv4 ipv6 max min required_without
process 3 1 min oneof
certificate 2 1 min
command 3 2 min
ntp 2 1 min
package 2 1 min
power 2 1 min
service 2 1 min
sysctl 4 3 min
timezone 2 1 min
log 4 4 -
log is covered as of #578. Everything else has a gap.
Priority
hostname is the worst at 0 of 3, and it is the one the original method-name count missed completely, because it has a method named ValidationHTTP that asserts no rule by name.
After that, by how much a missed rule would cost:
valid_target, oneof, ipv4, ipv6, file_mode, cron_schedule, account_name reject input that would otherwise reach a provider and fail somewhere less legible.
excluded_with and required_without encode a relationship between two fields, which is the kind of rule that quietly stops working when a field is renamed.
min and max are the most commonly untested and the least costly. min=1 beside required is close to redundant; max on a bounded query parameter is not.
The obligation
osapi-io/specs#244 states it: the test asserts 400 and that the body names the rule that rejected it. A test checking only the status code passes when the handler rejects for an unrelated reason, which is the failure it exists to catch.
name: "when lines below the minimum returns 400",
path: "/api/node/server1/log?lines=0",
s.Equal(http.StatusBadRequest, rec.Code)
s.Contains(rec.Body.String(), "min")
Asserting the rule name is also what makes the audit above possible, since it is what the script greps for.
Most domains declare validation the tests never exercise. Removing one of those tags from a spec would change nothing a test could see.
Corrected method
This issue originally counted test methods named
ValidationHTTPand concludedloghad none. That was wrong:logtestedvalid_targetand the priorityoneofinside a method namedTestGetNodeLogHTTP. Counting names measures naming, not coverage.The right comparison is the
validate:tags each spec declares against the rule names the tests assert:What it finds
logis covered as of #578. Everything else has a gap.Priority
hostnameis the worst at 0 of 3, and it is the one the original method-name count missed completely, because it has a method namedValidationHTTPthat asserts no rule by name.After that, by how much a missed rule would cost:
valid_target,oneof,ipv4,ipv6,file_mode,cron_schedule,account_namereject input that would otherwise reach a provider and fail somewhere less legible.excluded_withandrequired_withoutencode a relationship between two fields, which is the kind of rule that quietly stops working when a field is renamed.minandmaxare the most commonly untested and the least costly.min=1besiderequiredis close to redundant;maxon a bounded query parameter is not.The obligation
osapi-io/specs#244 states it: the test asserts 400 and that the body names the rule that rejected it. A test checking only the status code passes when the handler rejects for an unrelated reason, which is the failure it exists to catch.
Asserting the rule name is also what makes the audit above possible, since it is what the script greps for.