Skip to content

Commit 95bd2a3

Browse files
committed
cmd/runtimetest/main: Use TAP diagnostics for errors
This lets us print SHOULD violations even if they're non-fatal. It also gets us back to consumable TAP output. I added a /foo entry to defaultFS for testing, and before this commit: $ ./runtimetest TAP version 13 ok 1 - root filesystem ok 2 - hostname ok 3 - mounts not ok 4 - capabilities ok 5 - default symlinks ok 6 - default devices ok 7 - linux devices not ok 8 - linux process ok 9 - masked paths ok 10 - oom score adj ok 11 - read only paths not ok 12 - rlimits ok 13 - sysctls ok 14 - uid mappings ok 15 - gid mappings 1..15 3 errors occurred: * Unexpected bounding capability chown set for process * UID expected: 1, actual: 1000 * Wrong rlimit value: $ echo $? 1 The TAP 13 spec doesn't cover script exit-code handling [1], but that exit code confuses prove unless you set --ignore-exit: $ prove ./runtimetest ./runtimetest .. 1/? 3 errors occurred: * Unexpected bounding capability chown set for process * UID expected: 1, actual: 1000 * Wrong rlimit value: ./runtimetest .. Dubious, test returned 1 (wstat 256, 0x100) Failed 4/16 subtests Test Summary Report ------------------- ./runtimetest (Wstat: 256 Tests: 16 Failed: 4) Failed tests: 4, 6, 9, 13 Non-zero exit status: 1 Files=1, Tests=16, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL Note the "Dubious, test returned 1". And with the diagnostics written to stderr, there's no way to have prove catch that. With this commit, we're back to TAP-compatible output and exit codes, using TAP's diagnostics [2] to share the failure details. $ ./runtimetest TAP version 13 ok 1 - root filesystem ok 2 - hostname ok 3 - mounts not ok 4 - capabilities # Unexpected bounding capability chown set for process ok 5 - default symlinks ok 6 - default file system # /foo SHOULD exist and expected type is tmpfs # Refer to: https://github.com/opencontainers/runtime-spec/blob/v1.0.0/config-linux.md#default-filesystems ok 7 - default devices ok 8 - linux devices not ok 9 - linux process # UID expected: 1, actual: 1000 ok 10 - masked paths ok 11 - oom score adj ok 12 - read only paths not ok 13 - rlimits # Wrong rlimit value: ok 14 - sysctls ok 15 - uid mappings ok 16 - gid mappings 1..16 $ echo $? 0 You can use prove without --ignore-edit to summarize: $ prove ./runtimetest ./runtimetest .. Failed 3/16 subtests Test Summary Report ------------------- ./runtimetest (Wstat: 0 Tests: 16 Failed: 3) Failed tests: 4, 9, 13 Files=1, Tests=16, 0 wallclock secs ( 0.01 usr + 0.00 sys = 0.01 CPU) Result: FAIL And prove knows that the tests failed from TAP, with the script exit code saying "we were able to run the tests" and not speaking to pass/fail: $ echo $? 1 If that's too compact, you can ask prove to show failures and comments: $ prove -fo ./runtimetest ./runtimetest .. 1/? not ok 4 - capabilities # Unexpected bounding capability chown set for process # /foo SHOULD exist and expected type is tmpfs # Refer to: https://github.com/opencontainers/runtime-spec/blob/v1.0.0/config-linux.md#default-filesystems not ok 9 - linux process # UID expected: 1, actual: 1000 not ok 13 - rlimits # Wrong rlimit value: ./runtimetest .. Failed 3/16 subtests Test Summary Report ------------------- ./runtimetest (Wstat: 0 Tests: 16 Failed: 3) Failed tests: 4, 9, 13 Files=1, Tests=16, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL You can also turn that SHOULD error into a failure by cranking up the compliance level: $ prove -fo ./runtimetest :: --compliance-level SHOULD ./runtimetest .. 1/? not ok 4 - capabilities # Unexpected bounding capability chown set for process not ok 6 - default file system # /foo SHOULD exist and expected type is tmpfs # Refer to: https://github.com/opencontainers/runtime-spec/blob/v1.0.0/config-linux.md#default-filesystems not ok 9 - linux process # UID expected: 1, actual: 1000 not ok 13 - rlimits # Wrong rlimit value: ./runtimetest .. Failed 4/16 subtests Test Summary Report ------------------- ./runtimetest (Wstat: 0 Tests: 16 Failed: 4) Failed tests: 4, 6, 9, 13 Files=1, Tests=16, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL [1]: https://testanything.org/tap-version-13-specification.html#todo [2]: https://testanything.org/tap-version-13-specification.html#diagnostics Signed-off-by: W. Trevor King <[email protected]>
1 parent 8178fda commit 95bd2a3

File tree

1 file changed

+14
-21
lines changed

1 file changed

+14
-21
lines changed

cmd/runtimetest/main.go

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
"strings"
1515
"syscall"
1616

17-
"github.com/hashicorp/go-multierror"
1817
"github.com/mndrix/tap-go"
1918
rspec "github.com/opencontainers/runtime-spec/specs-go"
2019
"github.com/sirupsen/logrus"
@@ -706,33 +705,27 @@ func validate(context *cli.Context) error {
706705
complianceLevel = ociErr.ComplianceMust
707706
logrus.Warningf("%s, using 'MUST' by default.", err.Error())
708707
}
709-
var validationErrors error
710-
for _, v := range defaultValidations {
711-
err := v.test(spec)
712-
t.Ok(err == nil, v.description)
713-
if err != nil {
714-
if e, ok := err.(*ociErr.Error); ok && e.Level < complianceLevel {
715-
continue
716-
}
717-
validationErrors = multierror.Append(validationErrors, err)
718-
}
708+
validations := defaultValidations
709+
if platform == "linux" {
710+
validations = append(validations, linuxValidations...)
719711
}
720712

721-
if platform == "linux" {
722-
for _, v := range linuxValidations {
723-
err := v.test(spec)
724-
t.Ok(err == nil, v.description)
725-
if err != nil {
726-
if e, ok := err.(*ociErr.Error); ok && e.Level < complianceLevel {
727-
continue
728-
}
729-
validationErrors = multierror.Append(validationErrors, err)
713+
for _, v := range validations {
714+
err := v.test(spec)
715+
if err == nil {
716+
t.Pass(v.description)
717+
} else {
718+
if e, ok := err.(*ociErr.Error); ok {
719+
t.Ok(e.Level < complianceLevel, v.description)
720+
} else {
721+
t.Fail(v.description)
730722
}
723+
t.Diagnostic(err.Error())
731724
}
732725
}
733726
t.AutoPlan()
734727

735-
return validationErrors
728+
return nil
736729
}
737730

738731
func main() {

0 commit comments

Comments
 (0)