Skip to content

Commit 81148d0

Browse files
committed
tests: report the sshd suite's pass count
The summary prints "N run, N passed, N skipped" from a PASSED counter incremented at each success site. TOTAL counts every test reached, skips included, so printing it under the label "passed" overstated the pass count by exactly the number of skips. - pair each orphan SKIPPED bump with a TOTAL bump, and count the local-only tests skipped against an external host by name, so the printed numbers are commensurable and the skip count cannot go stale - count the host key gate's WOLFSSH_NO_HOSTKEY_PERMS exit as a pass: it prints PASSED and returns with TOTAL already charged, so leaving it uncounted would fail the new assertion on every build with that macro - assert that passed plus skipped equals ran and, without --match, that ran equals the known test count, so a miscounting skip site or a name no call site reaches fails the run - verified in the container: a full run reports 32 run, 30 passed, 2 skipped against 30 PASSED lines, and --exclude sshd_forcedcmd_test.sh reports 32 run, 29 passed, 3 skipped against 29
1 parent 11d1b99 commit 81148d0

2 files changed

Lines changed: 90 additions & 29 deletions

File tree

‎apps/wolfsshd/test/README.md‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,13 @@ SSHD running on PID 7979
2727
sshd_exec_test.sh ... PASSED
2828
Shutting down test wolfSSHd
2929
Stopping SSHD, killing pid 7979
30-
All tests ran, 1 passed, 0 skipped
30+
All tests ran, 1 run, 1 passed, 0 skipped
3131
3232
```
3333

34+
"run" counts every test reached, skips included. Passed plus skipped must equal
35+
run; the runner fails if they do not.
36+
3437
To run a specific test do:
3538

3639
startup wolfSSHd
@@ -89,6 +92,11 @@ the shared daemon stopped first -- and keep the `run_test` call where that setup
8992
happens. Both arrays drive `--match` and `--exclude`, so a test that is missing
9093
from them cannot be selected or skipped from the command line.
9194

95+
A test that can only run against a daemon the runner starts itself is skipped
96+
when `--host` and `--port` point at an external one. Pass its name to
97+
`skip_local_only` on that path, or add it to `local_sshd_tests` if it belongs in
98+
that block, so the external run still counts it as skipped.
99+
92100
## Selecting Tests
93101

94102
`--match <name>` runs a single test and `--exclude <name>` drops one from a full

‎apps/wolfsshd/test/run_all_sshd_tests.sh‎

Lines changed: 81 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ run_teardown() {
207207
trap run_teardown EXIT
208208

209209
TOTAL=0
210+
PASSED=0
210211
SKIPPED=0
211212
# Set as the last statement of each branch that runs tests, and checked before
212213
# the summary. A shell expansion error (a bad arithmetic expansion, say) unwinds
@@ -246,6 +247,7 @@ should_skip() {
246247
fi
247248
if [ "$1" == "$EXCLUDE" ]; then
248249
echo "Test '$1' is excluded. Skipping."
250+
TOTAL=$((TOTAL+1))
249251
SKIPPED=$((SKIPPED+1))
250252
return 0
251253
fi
@@ -260,6 +262,19 @@ matches() {
260262
[ -z "$MATCH" ] || [ "$1" == "$MATCH" ]
261263
}
262264

265+
# Counts each named test as skipped, for tests that need a local daemon on a run
266+
# against an external host. Takes the names rather than a number so the count
267+
# cannot drift from the tests it stands in for.
268+
skip_local_only() {
269+
local test
270+
for test in "$@"; do
271+
if matches "$test"; then
272+
TOTAL=$((TOTAL+1))
273+
SKIPPED=$((SKIPPED+1))
274+
fi
275+
done
276+
}
277+
263278
# Collect the directories above $1 that wolfSSHd's StrictModes check will
264279
# reject: a group or world writable directory anywhere above authorized_keys
265280
# makes the daemon refuse to read it, unless the directory is sticky. This
@@ -350,6 +365,7 @@ run_test() {
350365
SKIPPED=$((SKIPPED+1))
351366
elif [ "$RESULT" == 0 ]; then
352367
printf "PASSED\n"
368+
PASSED=$((PASSED+1))
353369
else
354370
printf "FAILED!\n"
355371
cat stdout.txt
@@ -401,6 +417,7 @@ EOF
401417
TOTAL=$((TOTAL+1))
402418
if grep -q "group or world readable" strictmodes_log.txt; then
403419
printf "PASSED\n"
420+
PASSED=$((PASSED+1))
404421
else
405422
printf "FAILED!\n"
406423
cat strictmodes_log.txt
@@ -459,6 +476,7 @@ EOF
459476
grep -q "but this build cannot enforce it" upn_nofpki_log.txt &&
460477
! grep -q "Refusing to load" upn_nofpki_log.txt; then
461478
printf "PASSED\n"
479+
PASSED=$((PASSED+1))
462480
else
463481
printf "FAILED!\n"
464482
cat upn_nofpki_log.txt
@@ -518,6 +536,7 @@ run_strictmodes_authkeys_negative_test() {
518536
after=${after:-0}
519537
if [ "$result" != 0 ] && [ "$after" -gt "$before" ]; then
520538
printf "PASSED\n"
539+
PASSED=$((PASSED+1))
521540
else
522541
printf "FAILED! (expected StrictModes rejection: client exit=%s, new log matches=%s)\n" \
523542
"$result" "$((after - before))"
@@ -654,6 +673,7 @@ EOF
654673
rm -rf "$HK_WORK"
655674
printf "PASSED (mode and owner cases skipped, built with "
656675
printf "WOLFSSH_NO_HOSTKEY_PERMS)\n"
676+
PASSED=$((PASSED+1))
657677
return
658678
fi
659679

@@ -673,6 +693,7 @@ EOF
673693

674694
rm -rf "$HK_WORK"
675695
printf "PASSED\n"
696+
PASSED=$((PASSED+1))
676697
}
677698

678699
# Run the tests. There is one path whether or not --match was given: every test
@@ -711,15 +732,15 @@ run_hostkey_perm_check
711732
# rejected. Reads the local ./log.txt, so only when we own the daemon.
712733
if [ "$USING_LOCAL_HOST" == 1 ]; then
713734
run_test "sshd_pubkey_reject_test.sh"
714-
elif matches "sshd_pubkey_reject_test.sh"; then
715-
SKIPPED=$((SKIPPED+1))
735+
else
736+
skip_local_only "sshd_pubkey_reject_test.sh"
716737
fi
717738

718739
# exercise the authorized_keys StrictModes path against the running sshd
719740
if [ "$USING_LOCAL_HOST" == 1 ]; then
720741
run_strictmodes_authkeys_negative_test
721-
elif matches "strictmodes_authkeys_negative"; then
722-
SKIPPED=$((SKIPPED+1))
742+
else
743+
skip_local_only "strictmodes_authkeys_negative"
723744
fi
724745

725746
if [ "$USING_LOCAL_HOST" == 1 ]; then
@@ -728,27 +749,32 @@ if [ "$USING_LOCAL_HOST" == 1 ]; then
728749
fi
729750

730751
# these tests require setting up an sshd
752+
local_sshd_tests=(
753+
"sshd_forcedcmd_test.sh"
754+
"sshd_match_overlap_test.sh"
755+
"sshd_window_full_test.sh"
756+
"sshd_stderr_eof_test.sh"
757+
"sshd_empty_password_test.sh"
758+
"sshd_permitroot_test.sh"
759+
"sshd_permitroot_prohibit_password.sh"
760+
"sshd_permitroot_forced_cmd.sh"
761+
"strictmodes_hostkey_negative"
762+
"upn_unenforceable_negative"
763+
"sshd_login_grace_test.sh"
764+
"sshd_privdrop_fail_test.sh"
765+
"sshd_chroot_fail_test.sh"
766+
)
731767
if [ "$USING_LOCAL_HOST" == 1 ]; then
732-
run_test "sshd_forcedcmd_test.sh"
733-
run_test "sshd_match_overlap_test.sh"
734-
run_test "sshd_window_full_test.sh"
735-
run_test "sshd_stderr_eof_test.sh"
736-
run_test "sshd_empty_password_test.sh"
737-
run_test "sshd_permitroot_test.sh"
738-
run_test "sshd_permitroot_prohibit_password.sh"
739-
run_test "sshd_permitroot_forced_cmd.sh"
740-
run_strictmodes_negative_test
741-
run_upn_unenforceable_negative_test
742-
run_test "sshd_login_grace_test.sh"
743-
run_test "sshd_privdrop_fail_test.sh"
744-
run_test "sshd_chroot_fail_test.sh"
768+
for test in "${local_sshd_tests[@]}"; do
769+
case "$test" in
770+
strictmodes_hostkey_negative) run_strictmodes_negative_test ;;
771+
upn_unenforceable_negative) run_upn_unenforceable_negative_test ;;
772+
*) run_test "$test" ;;
773+
esac
774+
done
745775
else
746776
printf "Skipping tests that need to setup local SSHD\n"
747-
# the thirteen calls above; with --match at most one of them was going to run,
748-
# and should_skip() has already counted it if it was excluded
749-
if [ -z "$MATCH" ]; then
750-
SKIPPED=$((SKIPPED+13))
751-
fi
777+
skip_local_only "${local_sshd_tests[@]}"
752778
fi
753779

754780
# these tests run with X509 sshd-config loaded. The matches() guard keeps a
@@ -767,7 +793,9 @@ fi
767793
# negative test: a certificate UPN realm outside AuthorizedUPNDomains must
768794
# be rejected. Needs the dedicated bad-domain config, so only runs when we
769795
# control the local daemon.
770-
if [ "$USING_LOCAL_HOST" == 1 ] && matches "sshd_x509_upn_fail.sh"; then
796+
if [ "$USING_LOCAL_HOST" != 1 ]; then
797+
skip_local_only "sshd_x509_upn_fail.sh"
798+
elif matches "sshd_x509_upn_fail.sh"; then
771799
start_wolfsshd "sshd_config_test_x509_upn_bad"
772800
run_test "sshd_x509_upn_fail.sh"
773801
printf "Shutting down test wolfSSHd\n"
@@ -779,7 +807,9 @@ fi
779807
# sshd_config_test_mldsa has no other host key, so an ML-DSA-less build
780808
# cannot start the daemon; check out here, not in the test script. The check
781809
# is the composite, not the umbrella: the ECDSA half can be missing on its own.
782-
if [ "$USING_LOCAL_HOST" == 1 ] && matches "sshd_mldsa_composite_test.sh"; then
810+
if [ "$USING_LOCAL_HOST" != 1 ]; then
811+
skip_local_only "sshd_mldsa_composite_test.sh"
812+
elif matches "sshd_mldsa_composite_test.sh"; then
783813
if wolfssh_has MLDSA87_ES384; then
784814
start_wolfsshd "sshd_config_test_mldsa"
785815
run_test "sshd_mldsa_composite_test.sh"
@@ -798,6 +828,8 @@ fi
798828
# client when present.
799829
if [ "$USING_LOCAL_HOST" == 1 ]; then
800830
run_test "sshd_ossh_cert_test.sh"
831+
else
832+
skip_local_only "sshd_ossh_cert_test.sh"
801833
fi
802834
RUN_COMPLETE=1
803835
}
@@ -808,14 +840,35 @@ if [ "$RUN_COMPLETE" != 1 ]; then
808840
fi
809841

810842
# A --match that reached no call site ran nothing and skipped nothing, which
811-
# would otherwise report a clean run. The local-only tests are unreachable
812-
# against an external host, so a name that is valid on a local run selects
813-
# nothing here; say so rather than exit 0 on an empty run.
843+
# would otherwise add up and report a clean "0 run". Every name is counted
844+
# somewhere -- the local-only ones as skipped against an external host -- so
845+
# this catches a call site that stopped counting; say so rather than exit 0 on
846+
# an empty run.
814847
if [ -n "$MATCH" ] && [ "$TOTAL" -eq 0 ]; then
815848
printf "ERROR: --match %s selected no test that could run here\n" "$MATCH"
816849
exit 1
817850
fi
818851

819-
printf "All tests ran, $TOTAL passed, $SKIPPED skipped\n"
852+
# TOTAL counts every test that was reached, skips included, so it is a "ran"
853+
# count and not a pass count. Print the three separately, and assert they add
854+
# up: a skip site that bumps one counter and not the other then fails the run
855+
# instead of quietly printing a wrong number.
856+
printf "All tests ran, %d run, %d passed, %d skipped\n" \
857+
"$TOTAL" "$PASSED" "$SKIPPED"
858+
859+
if [ "$((PASSED + SKIPPED))" -ne "$TOTAL" ]; then
860+
printf "ERROR: counter mismatch (ran %d, passed %d, skipped %d)\n" \
861+
"$TOTAL" "$PASSED" "$SKIPPED"
862+
exit 1
863+
fi
864+
865+
# Without --match every known test is reached once, run or skipped, so a
866+
# name no call site reaches -- one dropped from local_sshd_tests, say --
867+
# shows up here as a short count.
868+
KNOWN=$(( ${#test_cases[@]} + ${#extra_test_cases[@]} ))
869+
if [ -z "$MATCH" ] && [ "$TOTAL" -ne "$KNOWN" ]; then
870+
printf "ERROR: %d tests known but %d reached\n" "$KNOWN" "$TOTAL"
871+
exit 1
872+
fi
820873

821874
exit 0

0 commit comments

Comments
 (0)