diff --git a/cmd/hakurei/command_test.go b/cmd/hakurei/command_test.go index d29485d..66960d9 100644 --- a/cmd/hakurei/command_test.go +++ b/cmd/hakurei/command_test.go @@ -11,6 +11,8 @@ import ( ) func TestHelp(t *testing.T) { + t.Parallel() + testCases := []struct { name string args []string @@ -68,6 +70,8 @@ Flags: } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + out := new(bytes.Buffer) c := buildCommand(t.Context(), message.NewMsg(nil), new(earlyHardeningErrs), out) if err := c.Parse(tc.args); !errors.Is(err, command.ErrHelp) && !errors.Is(err, flag.ErrHelp) { diff --git a/cmd/hakurei/print_test.go b/cmd/hakurei/print_test.go index c38b731..a0bb198 100644 --- a/cmd/hakurei/print_test.go +++ b/cmd/hakurei/print_test.go @@ -27,6 +27,8 @@ var ( ) func TestPrintShowInstance(t *testing.T) { + t.Parallel() + testCases := []struct { name string instance *state.State @@ -487,6 +489,8 @@ App for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + output := new(strings.Builder) gotValid := printShowInstance(output, testTime, tc.instance, tc.config, tc.short, tc.json) if got := output.String(); got != tc.want { @@ -501,6 +505,8 @@ App } func TestPrintPs(t *testing.T) { + t.Parallel() + testCases := []struct { name string entries state.Entries @@ -698,6 +704,8 @@ func TestPrintPs(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + output := new(strings.Builder) printPs(output, testTime, stubStore(tc.entries), tc.short, tc.json) if got := output.String(); got != tc.want { diff --git a/cmd/hsu/parse_test.go b/cmd/hsu/parse_test.go index d5d3946..0fbf8a1 100644 --- a/cmd/hsu/parse_test.go +++ b/cmd/hsu/parse_test.go @@ -6,32 +6,46 @@ import ( "testing" ) -func Test_parseUint32Fast(t *testing.T) { +func TestParseUint32Fast(t *testing.T) { + t.Parallel() + t.Run("zero-length", func(t *testing.T) { + t.Parallel() + if _, err := parseUint32Fast(""); err == nil || err.Error() != "zero length string" { t.Errorf(`parseUint32Fast(""): error = %v`, err) return } }) + t.Run("overflow", func(t *testing.T) { + t.Parallel() + if _, err := parseUint32Fast("10000000000"); err == nil || err.Error() != "string too long" { t.Errorf("parseUint32Fast: error = %v", err) return } }) + t.Run("invalid byte", func(t *testing.T) { + t.Parallel() + if _, err := parseUint32Fast("meow"); err == nil || err.Error() != "invalid character 'm' at index 0" { t.Errorf(`parseUint32Fast("meow"): error = %v`, err) return } }) + t.Run("full range", func(t *testing.T) { + t.Parallel() + testRange := func(i, end int) { for ; i < end; i++ { s := strconv.Itoa(i) w := i t.Run("parse "+s, func(t *testing.T) { t.Parallel() + v, err := parseUint32Fast(s) if err != nil { t.Errorf("parseUint32Fast(%q): error = %v", @@ -55,7 +69,9 @@ func Test_parseUint32Fast(t *testing.T) { }) } -func Test_parseConfig(t *testing.T) { +func TestParseConfig(t *testing.T) { + t.Parallel() + testCases := []struct { name string puid, want int @@ -71,6 +87,8 @@ func Test_parseConfig(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + fid, ok, err := parseConfig(bytes.NewBufferString(tc.rc), tc.puid) if err == nil && tc.wantErr != "" { t.Errorf("parseConfig: error = %v; wantErr %q", diff --git a/command/builder_test.go b/command/builder_test.go index 9523184..7b9a170 100644 --- a/command/builder_test.go +++ b/command/builder_test.go @@ -7,6 +7,7 @@ import ( ) func TestBuild(t *testing.T) { + t.Parallel() c := command.New(nil, nil, "test", nil) stubHandler := func([]string) error { panic("unreachable") } diff --git a/command/parse_test.go b/command/parse_test.go index ce013f2..c2956c6 100644 --- a/command/parse_test.go +++ b/command/parse_test.go @@ -14,6 +14,8 @@ import ( ) func TestParse(t *testing.T) { + t.Parallel() + testCases := []struct { name string buildTree func(wout, wlog io.Writer) command.Command @@ -251,6 +253,7 @@ Commands: } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() wout, wlog := new(bytes.Buffer), new(bytes.Buffer) c := tc.buildTree(wout, wlog) diff --git a/command/unreachable_test.go b/command/unreachable_test.go index 7140818..9e8c19c 100644 --- a/command/unreachable_test.go +++ b/command/unreachable_test.go @@ -6,15 +6,19 @@ import ( ) func TestParseUnreachable(t *testing.T) { + t.Parallel() + // top level bypasses name matching and recursive calls to Parse // returns when encountering zero-length args t.Run("zero-length args", func(t *testing.T) { + t.Parallel() defer checkRecover(t, "Parse", "attempted to parse with zero length args") _ = newNode(panicWriter{}, nil, " ", " ").Parse(nil) }) // top level must not have siblings t.Run("toplevel siblings", func(t *testing.T) { + t.Parallel() defer checkRecover(t, "Parse", "invalid toplevel state") n := newNode(panicWriter{}, nil, " ", "") n.append(newNode(panicWriter{}, nil, " ", " ")) @@ -23,6 +27,7 @@ func TestParseUnreachable(t *testing.T) { // a node with descendents must not have a direct handler t.Run("sub handle conflict", func(t *testing.T) { + t.Parallel() defer checkRecover(t, "Parse", "invalid subcommand tree state") n := newNode(panicWriter{}, nil, " ", " ") n.adopt(newNode(panicWriter{}, nil, " ", " ")) @@ -32,6 +37,7 @@ func TestParseUnreachable(t *testing.T) { // this would only happen if a node was matched twice t.Run("parsed flag set", func(t *testing.T) { + t.Parallel() defer checkRecover(t, "Parse", "invalid set state") n := newNode(panicWriter{}, nil, " ", "") set := flag.NewFlagSet("parsed", flag.ContinueOnError) diff --git a/container/autoetc_test.go b/container/autoetc_test.go index 30f46e5..a7e3ae4 100644 --- a/container/autoetc_test.go +++ b/container/autoetc_test.go @@ -10,7 +10,10 @@ import ( ) func TestAutoEtcOp(t *testing.T) { + t.Parallel() + t.Run("nonrepeatable", func(t *testing.T) { + t.Parallel() wantErr := OpRepeatError("autoetc") if err := (&AutoEtcOp{Prefix: "81ceabb30d37bbdb3868004629cb84e9"}).apply(&setupState{nonrepeatable: nrAutoEtc}, nil); !errors.Is(err, wantErr) { t.Errorf("apply: error = %v, want %v", err, wantErr) @@ -280,6 +283,7 @@ func TestAutoEtcOp(t *testing.T) { }) t.Run("host path rel", func(t *testing.T) { + t.Parallel() op := &AutoEtcOp{Prefix: "048090b6ed8f9ebb10e275ff5d8c0659"} wantHostPath := "/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659" wantHostRel := ".host/048090b6ed8f9ebb10e275ff5d8c0659" diff --git a/container/autoroot_test.go b/container/autoroot_test.go index d53edc7..129ff4e 100644 --- a/container/autoroot_test.go +++ b/container/autoroot_test.go @@ -13,6 +13,7 @@ import ( func TestAutoRootOp(t *testing.T) { t.Run("nonrepeatable", func(t *testing.T) { + t.Parallel() wantErr := OpRepeatError("autoroot") if err := new(AutoRootOp).apply(&setupState{nonrepeatable: nrAutoRoot}, nil); !errors.Is(err, wantErr) { t.Errorf("apply: error = %v, want %v", err, wantErr) @@ -180,6 +181,8 @@ func TestAutoRootOp(t *testing.T) { } func TestIsAutoRootBindable(t *testing.T) { + t.Parallel() + testCases := []struct { name string want bool @@ -196,6 +199,7 @@ func TestIsAutoRootBindable(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() var msg message.Msg if tc.log { msg = &kstub{nil, stub.New(t, func(s *stub.Stub[syscallDispatcher]) syscallDispatcher { panic("unreachable") }, stub.Expect{Calls: []stub.Call{ diff --git a/container/capability_test.go b/container/capability_test.go index 21043fb..9494480 100644 --- a/container/capability_test.go +++ b/container/capability_test.go @@ -3,6 +3,8 @@ package container import "testing" func TestCapToIndex(t *testing.T) { + t.Parallel() + testCases := []struct { name string cap uintptr @@ -14,6 +16,7 @@ func TestCapToIndex(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() if got := capToIndex(tc.cap); got != tc.want { t.Errorf("capToIndex: %#x, want %#x", got, tc.want) } @@ -22,6 +25,8 @@ func TestCapToIndex(t *testing.T) { } func TestCapToMask(t *testing.T) { + t.Parallel() + testCases := []struct { name string cap uintptr @@ -33,6 +38,7 @@ func TestCapToMask(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() if got := capToMask(tc.cap); got != tc.want { t.Errorf("capToMask: %#x, want %#x", got, tc.want) } diff --git a/container/check/absolute_test.go b/container/check/absolute_test.go index a25c0ad..2746ec7 100644 --- a/container/check/absolute_test.go +++ b/container/check/absolute_test.go @@ -18,6 +18,8 @@ import ( func unsafeAbs(_ string) *Absolute func TestAbsoluteError(t *testing.T) { + t.Parallel() + testCases := []struct { name string @@ -27,8 +29,8 @@ func TestAbsoluteError(t *testing.T) { }{ {"EINVAL", new(AbsoluteError), syscall.EINVAL, true}, {"not EINVAL", new(AbsoluteError), syscall.EBADE, false}, - {"ne val", new(AbsoluteError), &AbsoluteError{"etc"}, false}, - {"equals", &AbsoluteError{"etc"}, &AbsoluteError{"etc"}, true}, + {"ne val", new(AbsoluteError), &AbsoluteError{Pathname: "etc"}, false}, + {"equals", &AbsoluteError{Pathname: "etc"}, &AbsoluteError{Pathname: "etc"}, true}, } for _, tc := range testCases { @@ -38,14 +40,18 @@ func TestAbsoluteError(t *testing.T) { } t.Run("string", func(t *testing.T) { + t.Parallel() + want := `path "etc" is not absolute` - if got := (&AbsoluteError{"etc"}).Error(); got != want { + if got := (&AbsoluteError{Pathname: "etc"}).Error(); got != want { t.Errorf("Error: %q, want %q", got, want) } }) } func TestNewAbs(t *testing.T) { + t.Parallel() + testCases := []struct { name string @@ -54,12 +60,14 @@ func TestNewAbs(t *testing.T) { wantErr error }{ {"good", "/etc", MustAbs("/etc"), nil}, - {"not absolute", "etc", nil, &AbsoluteError{"etc"}}, - {"zero", "", nil, &AbsoluteError{""}}, + {"not absolute", "etc", nil, &AbsoluteError{Pathname: "etc"}}, + {"zero", "", nil, &AbsoluteError{Pathname: ""}}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + got, err := NewAbs(tc.pathname) if !reflect.DeepEqual(got, tc.want) { t.Errorf("NewAbs: %#v, want %#v", got, tc.want) @@ -71,6 +79,8 @@ func TestNewAbs(t *testing.T) { } t.Run("must", func(t *testing.T) { + t.Parallel() + defer func() { wantPanic := `path "etc" is not absolute` @@ -85,6 +95,8 @@ func TestNewAbs(t *testing.T) { func TestAbsoluteString(t *testing.T) { t.Run("passthrough", func(t *testing.T) { + t.Parallel() + pathname := "/etc" if got := unsafeAbs(pathname).String(); got != pathname { t.Errorf("String: %q, want %q", got, pathname) @@ -92,6 +104,8 @@ func TestAbsoluteString(t *testing.T) { }) t.Run("zero", func(t *testing.T) { + t.Parallel() + defer func() { wantPanic := "attempted use of zero Absolute" @@ -105,6 +119,8 @@ func TestAbsoluteString(t *testing.T) { } func TestAbsoluteIs(t *testing.T) { + t.Parallel() + testCases := []struct { name string a, v *Absolute @@ -120,6 +136,8 @@ func TestAbsoluteIs(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + if got := tc.a.Is(tc.v); got != tc.want { t.Errorf("Is: %v, want %v", got, tc.want) } @@ -133,6 +151,8 @@ type sCheck struct { } func TestCodecAbsolute(t *testing.T) { + t.Parallel() + testCases := []struct { name string a *Absolute @@ -153,7 +173,7 @@ func TestCodecAbsolute(t *testing.T) { `"/etc"`, `{"val":"/etc","magic":3236757504}`}, {"not absolute", nil, - &AbsoluteError{"etc"}, + &AbsoluteError{Pathname: "etc"}, "\t\x7f\x05\x01\x02\xff\x82\x00\x00\x00\a\xff\x80\x00\x03etc", ",\xff\x83\x03\x01\x01\x06sCheck\x01\xff\x84\x00\x01\x02\x01\bPathname\x01\xff\x80\x00\x01\x05Magic\x01\x04\x00\x00\x00\t\x7f\x05\x01\x02\xff\x82\x00\x00\x00\x0f\xff\x84\x01\x03etc\x01\xfb\x01\x81\xda\x00\x00\x00", @@ -167,13 +187,18 @@ func TestCodecAbsolute(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + t.Run("gob", func(t *testing.T) { if tc.gob == "\x00" && tc.sGob == "\x00" { // these values mark the current test to skip gob return } + t.Parallel() t.Run("encode", func(t *testing.T) { + t.Parallel() + // encode is unchecked if errors.Is(tc.wantErr, syscall.EINVAL) { return @@ -210,6 +235,8 @@ func TestCodecAbsolute(t *testing.T) { }) t.Run("decode", func(t *testing.T) { + t.Parallel() + { var gotA *Absolute err := gob.NewDecoder(strings.NewReader(tc.gob)).Decode(&gotA) @@ -244,7 +271,11 @@ func TestCodecAbsolute(t *testing.T) { }) t.Run("json", func(t *testing.T) { + t.Parallel() + t.Run("marshal", func(t *testing.T) { + t.Parallel() + // marshal is unchecked if errors.Is(tc.wantErr, syscall.EINVAL) { return @@ -279,6 +310,8 @@ func TestCodecAbsolute(t *testing.T) { }) t.Run("unmarshal", func(t *testing.T) { + t.Parallel() + { var gotA *Absolute err := json.Unmarshal([]byte(tc.json), &gotA) @@ -314,6 +347,8 @@ func TestCodecAbsolute(t *testing.T) { } t.Run("json passthrough", func(t *testing.T) { + t.Parallel() + wantErr := "invalid character ':' looking for beginning of value" if err := new(Absolute).UnmarshalJSON([]byte(":3")); err == nil || err.Error() != wantErr { t.Errorf("UnmarshalJSON: error = %v, want %s", err, wantErr) @@ -322,7 +357,11 @@ func TestCodecAbsolute(t *testing.T) { } func TestAbsoluteWrap(t *testing.T) { + t.Parallel() + t.Run("join", func(t *testing.T) { + t.Parallel() + want := "/etc/nix/nix.conf" if got := MustAbs("/etc").Append("nix", "nix.conf"); got.String() != want { t.Errorf("Append: %q, want %q", got, want) @@ -330,6 +369,8 @@ func TestAbsoluteWrap(t *testing.T) { }) t.Run("dir", func(t *testing.T) { + t.Parallel() + want := "/" if got := MustAbs("/etc").Dir(); got.String() != want { t.Errorf("Dir: %q, want %q", got, want) @@ -337,6 +378,8 @@ func TestAbsoluteWrap(t *testing.T) { }) t.Run("sort", func(t *testing.T) { + t.Parallel() + want := []*Absolute{MustAbs("/etc"), MustAbs("/proc"), MustAbs("/sys")} got := []*Absolute{MustAbs("/proc"), MustAbs("/sys"), MustAbs("/etc")} SortAbs(got) @@ -346,6 +389,8 @@ func TestAbsoluteWrap(t *testing.T) { }) t.Run("compact", func(t *testing.T) { + t.Parallel() + want := []*Absolute{MustAbs("/etc"), MustAbs("/proc"), MustAbs("/sys")} if got := CompactAbs([]*Absolute{MustAbs("/etc"), MustAbs("/proc"), MustAbs("/proc"), MustAbs("/sys")}); !reflect.DeepEqual(got, want) { t.Errorf("CompactAbs: %#v, want %#v", got, want) diff --git a/container/check/overlay_test.go b/container/check/overlay_test.go index bd90236..8fdcd69 100644 --- a/container/check/overlay_test.go +++ b/container/check/overlay_test.go @@ -7,6 +7,8 @@ import ( ) func TestEscapeOverlayDataSegment(t *testing.T) { + t.Parallel() + testCases := []struct { name string s string @@ -19,6 +21,8 @@ func TestEscapeOverlayDataSegment(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + if got := check.EscapeOverlayDataSegment(tc.s); got != tc.want { t.Errorf("escapeOverlayDataSegment: %s, want %s", got, tc.want) } diff --git a/container/container_test.go b/container/container_test.go index bc90d8f..e692ab3 100644 --- a/container/container_test.go +++ b/container/container_test.go @@ -30,6 +30,8 @@ import ( ) func TestStartError(t *testing.T) { + t.Parallel() + testCases := []struct { name string err error @@ -137,6 +139,8 @@ func TestStartError(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + t.Run("error", func(t *testing.T) { if got := tc.err.Error(); got != tc.s { t.Errorf("Error: %q, want %q", got, tc.s) @@ -352,6 +356,8 @@ var containerTestCases = []struct { } func TestContainer(t *testing.T) { + t.Parallel() + t.Run("cancel", testContainerCancel(nil, func(t *testing.T, c *container.Container) { wantErr := context.Canceled wantExitCode := 0 @@ -385,6 +391,8 @@ func TestContainer(t *testing.T) { for i, tc := range containerTestCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + wantOps, wantOpsCtx := tc.ops(t) wantMnt := tc.mnt(t, wantOpsCtx) @@ -504,6 +512,7 @@ func testContainerCancel( waitCheck func(t *testing.T, c *container.Container), ) func(t *testing.T) { return func(t *testing.T) { + t.Parallel() ctx, cancel := context.WithTimeout(t.Context(), helperDefaultTimeout) c := helperNewContainer(ctx, "block") @@ -546,6 +555,7 @@ func testContainerCancel( } func TestContainerString(t *testing.T) { + t.Parallel() msg := message.NewMsg(nil) c := container.NewCommand(t.Context(), msg, check.MustAbs("/run/current-system/sw/bin/ldd"), "ldd", "/usr/bin/env") c.SeccompFlags |= seccomp.AllowMultiarch diff --git a/container/dispatcher_test.go b/container/dispatcher_test.go index 4e6ee76..3e5cb91 100644 --- a/container/dispatcher_test.go +++ b/container/dispatcher_test.go @@ -32,10 +32,12 @@ func checkOpsValid(t *testing.T, testCases []opValidTestCase) { t.Run("valid", func(t *testing.T) { t.Helper() + t.Parallel() for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Helper() + t.Parallel() if got := tc.op.Valid(); got != tc.want { t.Errorf("Valid: %v, want %v", got, tc.want) @@ -56,10 +58,12 @@ func checkOpsBuilder(t *testing.T, testCases []opsBuilderTestCase) { t.Run("build", func(t *testing.T) { t.Helper() + t.Parallel() for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Helper() + t.Parallel() if !slices.EqualFunc(*tc.ops, tc.want, func(op Op, v Op) bool { return op.Is(v) }) { t.Errorf("Ops: %#v, want %#v", tc.ops, tc.want) @@ -80,10 +84,12 @@ func checkOpIs(t *testing.T, testCases []opIsTestCase) { t.Run("is", func(t *testing.T) { t.Helper() + t.Parallel() for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Helper() + t.Parallel() if got := tc.op.Is(tc.v); got != tc.want { t.Errorf("Is: %v, want %v", got, tc.want) @@ -106,10 +112,12 @@ func checkOpMeta(t *testing.T, testCases []opMetaTestCase) { t.Run("meta", func(t *testing.T) { t.Helper() + t.Parallel() for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Helper() + t.Parallel() t.Run("prefix", func(t *testing.T) { t.Helper() @@ -150,6 +158,7 @@ func checkSimple(t *testing.T, fname string, testCases []simpleTestCase) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Helper() + t.Parallel() wait4signal := make(chan struct{}) k := &kstub{wait4signal, stub.New(t, func(s *stub.Stub[syscallDispatcher]) syscallDispatcher { return &kstub{wait4signal, s} }, tc.want)} @@ -183,10 +192,12 @@ func checkOpBehaviour(t *testing.T, testCases []opBehaviourTestCase) { t.Run("behaviour", func(t *testing.T) { t.Helper() + t.Parallel() for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Helper() + t.Parallel() k := &kstub{nil, stub.New(t, func(s *stub.Stub[syscallDispatcher]) syscallDispatcher { return &kstub{nil, s} }, diff --git a/container/errors_test.go b/container/errors_test.go index c2d3fa7..bf74265 100644 --- a/container/errors_test.go +++ b/container/errors_test.go @@ -14,6 +14,8 @@ import ( ) func TestMessageFromError(t *testing.T) { + t.Parallel() + testCases := []struct { name string err error @@ -54,6 +56,7 @@ func TestMessageFromError(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() got, ok := messageFromError(tc.err) if got != tc.want { t.Errorf("messageFromError: %q, want %q", got, tc.want) @@ -66,6 +69,8 @@ func TestMessageFromError(t *testing.T) { } func TestMountError(t *testing.T) { + t.Parallel() + testCases := []struct { name string err error @@ -111,6 +116,7 @@ func TestMountError(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() t.Run("is", func(t *testing.T) { if !errors.Is(tc.err, tc.errno) { t.Errorf("Is: %#v is not %v", tc.err, tc.errno) @@ -125,6 +131,7 @@ func TestMountError(t *testing.T) { } t.Run("zero", func(t *testing.T) { + t.Parallel() if errors.Is(new(MountError), syscall.Errno(0)) { t.Errorf("Is: zero MountError unexpected true") } @@ -132,6 +139,8 @@ func TestMountError(t *testing.T) { } func TestErrnoFallback(t *testing.T) { + t.Parallel() + testCases := []struct { name string err error @@ -154,6 +163,7 @@ func TestErrnoFallback(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() errno, err := errnoFallback(tc.name, Nonexistent, tc.err) if errno != tc.wantErrno { t.Errorf("errnoFallback: errno = %v, want %v", errno, tc.wantErrno) diff --git a/container/executable_test.go b/container/executable_test.go index 33981bb..38e8943 100644 --- a/container/executable_test.go +++ b/container/executable_test.go @@ -9,10 +9,10 @@ import ( ) func TestExecutable(t *testing.T) { + t.Parallel() for i := 0; i < 16; i++ { if got := container.MustExecutable(message.NewMsg(nil)); got != os.Args[0] { - t.Errorf("MustExecutable: %q, want %q", - got, os.Args[0]) + t.Errorf("MustExecutable: %q, want %q", got, os.Args[0]) } } } diff --git a/container/init_test.go b/container/init_test.go index 1db8174..4973972 100644 --- a/container/init_test.go +++ b/container/init_test.go @@ -13,6 +13,7 @@ import ( ) func TestInitEntrypoint(t *testing.T) { + t.Parallel() checkSimple(t, "initEntrypoint", []simpleTestCase{ {"getpid", func(k *kstub) error { initEntrypoint(k, k); return nil }, stub.Expect{ @@ -2649,6 +2650,7 @@ func TestInitEntrypoint(t *testing.T) { } func TestOpsGrow(t *testing.T) { + t.Parallel() ops := new(Ops) ops.Grow(1 << 4) if got := cap(*ops); got == 0 { diff --git a/container/initbind_test.go b/container/initbind_test.go index 41a1d97..323a032 100644 --- a/container/initbind_test.go +++ b/container/initbind_test.go @@ -12,6 +12,8 @@ import ( ) func TestBindMountOp(t *testing.T) { + t.Parallel() + checkOpBehaviour(t, []opBehaviourTestCase{ {"ENOENT not optional", new(Params), &BindMountOp{ Source: check.MustAbs("/bin/"), @@ -164,7 +166,10 @@ func TestBindMountOp(t *testing.T) { }) t.Run("unreachable", func(t *testing.T) { + t.Parallel() + t.Run("nil sourceFinal not optional", func(t *testing.T) { + t.Parallel() wantErr := OpStateError("bind") if err := new(BindMountOp).apply(nil, nil); !errors.Is(err, wantErr) { t.Errorf("apply: error = %v, want %v", err, wantErr) diff --git a/container/initdev_test.go b/container/initdev_test.go index 4081dd2..e885c35 100644 --- a/container/initdev_test.go +++ b/container/initdev_test.go @@ -9,6 +9,8 @@ import ( ) func TestMountDevOp(t *testing.T) { + t.Parallel() + checkOpBehaviour(t, []opBehaviourTestCase{ {"mountTmpfs", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: check.MustAbs("/dev/"), diff --git a/container/initmkdir_test.go b/container/initmkdir_test.go index 31f3fb8..4bec4fa 100644 --- a/container/initmkdir_test.go +++ b/container/initmkdir_test.go @@ -9,6 +9,8 @@ import ( ) func TestMkdirOp(t *testing.T) { + t.Parallel() + checkOpBehaviour(t, []opBehaviourTestCase{ {"success", new(Params), &MkdirOp{ Path: check.MustAbs("/.hakurei"), diff --git a/container/initoverlay_test.go b/container/initoverlay_test.go index ad07ef9..1c0e642 100644 --- a/container/initoverlay_test.go +++ b/container/initoverlay_test.go @@ -10,7 +10,11 @@ import ( ) func TestMountOverlayOp(t *testing.T) { + t.Parallel() + t.Run("argument error", func(t *testing.T) { + t.Parallel() + testCases := []struct { name string err *OverlayArgumentError @@ -30,6 +34,7 @@ func TestMountOverlayOp(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() if got := tc.err.Error(); got != tc.want { t.Errorf("Error: %q, want %q", got, tc.want) } @@ -270,7 +275,10 @@ func TestMountOverlayOp(t *testing.T) { }) t.Run("unreachable", func(t *testing.T) { + t.Parallel() + t.Run("nil Upper non-nil Work not ephemeral", func(t *testing.T) { + t.Parallel() wantErr := OpStateError("overlay") if err := (&MountOverlayOp{ Work: check.MustAbs("/"), diff --git a/container/initplace_test.go b/container/initplace_test.go index 03f298b..afeddbe 100644 --- a/container/initplace_test.go +++ b/container/initplace_test.go @@ -14,6 +14,7 @@ func TestTmpfileOp(t *testing.T) { samplePath = check.MustAbs("/etc/passwd") sampleData = []byte(sampleDataString) ) + t.Parallel() checkOpBehaviour(t, []opBehaviourTestCase{ {"createTemp", &Params{ParentPerm: 0700}, &TmpfileOp{ diff --git a/container/initproc_test.go b/container/initproc_test.go index 8633414..12b4def 100644 --- a/container/initproc_test.go +++ b/container/initproc_test.go @@ -9,6 +9,8 @@ import ( ) func TestMountProcOp(t *testing.T) { + t.Parallel() + checkOpBehaviour(t, []opBehaviourTestCase{ {"mkdir", &Params{ParentPerm: 0755}, &MountProcOp{ diff --git a/container/initremount_test.go b/container/initremount_test.go index 74afe0b..03a7b64 100644 --- a/container/initremount_test.go +++ b/container/initremount_test.go @@ -9,6 +9,8 @@ import ( ) func TestRemountOp(t *testing.T) { + t.Parallel() + checkOpBehaviour(t, []opBehaviourTestCase{ {"success", new(Params), &RemountOp{ Target: check.MustAbs("/"), diff --git a/container/initsymlink_test.go b/container/initsymlink_test.go index 1b69740..e260b51 100644 --- a/container/initsymlink_test.go +++ b/container/initsymlink_test.go @@ -9,6 +9,8 @@ import ( ) func TestSymlinkOp(t *testing.T) { + t.Parallel() + checkOpBehaviour(t, []opBehaviourTestCase{ {"mkdir", &Params{ParentPerm: 0700}, &SymlinkOp{ Target: check.MustAbs("/etc/nixos"), diff --git a/container/inittmpfs_test.go b/container/inittmpfs_test.go index f67c45c..f5dfafa 100644 --- a/container/inittmpfs_test.go +++ b/container/inittmpfs_test.go @@ -10,7 +10,10 @@ import ( ) func TestMountTmpfsOp(t *testing.T) { + t.Parallel() + t.Run("size error", func(t *testing.T) { + t.Parallel() tmpfsSizeError := TmpfsSizeError(-1) want := "tmpfs size -1 out of bounds" if got := tmpfsSizeError.Error(); got != want { diff --git a/container/landlock_test.go b/container/landlock_test.go index d204bc3..87dc249 100644 --- a/container/landlock_test.go +++ b/container/landlock_test.go @@ -8,6 +8,8 @@ import ( ) func TestLandlockString(t *testing.T) { + t.Parallel() + testCases := []struct { name string rulesetAttr *container.RulesetAttr @@ -46,6 +48,7 @@ func TestLandlockString(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() if got := tc.rulesetAttr.String(); got != tc.want { t.Errorf("String: %s, want %s", got, tc.want) } @@ -54,6 +57,7 @@ func TestLandlockString(t *testing.T) { } func TestLandlockAttrSize(t *testing.T) { + t.Parallel() want := 24 if got := unsafe.Sizeof(container.RulesetAttr{}); got != uintptr(want) { t.Errorf("Sizeof: %d, want %d", got, want) diff --git a/container/mount_test.go b/container/mount_test.go index daa2287..c6a5710 100644 --- a/container/mount_test.go +++ b/container/mount_test.go @@ -10,6 +10,8 @@ import ( ) func TestBindMount(t *testing.T) { + t.Parallel() + checkSimple(t, "bindMount", []simpleTestCase{ {"mount", func(k *kstub) error { return newProcPaths(k, hostPath).bindMount(nil, "/host/nix", "/sysroot/nix", syscall.MS_RDONLY) @@ -34,6 +36,8 @@ func TestBindMount(t *testing.T) { } func TestRemount(t *testing.T) { + t.Parallel() + const sampleMountinfoNix = `254 407 253:0 / /host rw,relatime master:1 - ext4 /dev/disk/by-label/nixos rw 255 254 0:28 / /host/mnt/.ro-cwd ro,noatime master:2 - 9p cwd ro,access=client,msize=16384,trans=virtio 256 254 0:29 / /host/nix/.ro-store rw,relatime master:3 - 9p nix-store rw,cache=f,access=client,msize=16384,trans=virtio @@ -216,6 +220,8 @@ func TestRemount(t *testing.T) { } func TestRemountWithFlags(t *testing.T) { + t.Parallel() + checkSimple(t, "remountWithFlags", []simpleTestCase{ {"noop unmatched", func(k *kstub) error { return remountWithFlags(k, k, &vfs.MountInfoNode{MountInfoEntry: &vfs.MountInfoEntry{VfsOptstr: "rw,relatime,cat"}}, 0) @@ -236,6 +242,8 @@ func TestRemountWithFlags(t *testing.T) { } func TestMountTmpfs(t *testing.T) { + t.Parallel() + checkSimple(t, "mountTmpfs", []simpleTestCase{ {"mkdirAll", func(k *kstub) error { return mountTmpfs(k, "ephemeral", "/sysroot/run/user/1000", 0, 1<<10, 0700) @@ -260,6 +268,8 @@ func TestMountTmpfs(t *testing.T) { } func TestParentPerm(t *testing.T) { + t.Parallel() + testCases := []struct { perm os.FileMode want os.FileMode @@ -275,6 +285,7 @@ func TestParentPerm(t *testing.T) { for _, tc := range testCases { t.Run(tc.perm.String(), func(t *testing.T) { + t.Parallel() if got := parentPerm(tc.perm); got != tc.want { t.Errorf("parentPerm: %#o, want %#o", got, tc.want) } diff --git a/container/seccomp/libseccomp.go b/container/seccomp/libseccomp.go index c7a3b67..21236a0 100644 --- a/container/seccomp/libseccomp.go +++ b/container/seccomp/libseccomp.go @@ -117,7 +117,7 @@ func Export(fd int, rules []NativeRule, flags ExportFlag) error { var ret C.int - rulesPinner := new(runtime.Pinner) + var rulesPinner runtime.Pinner for i := range rules { rule := &rules[i] rulesPinner.Pin(rule) @@ -189,6 +189,5 @@ func syscallResolveName(s string) (trap int) { v := C.CString(s) trap = int(C.seccomp_syscall_resolve_name(v)) C.free(unsafe.Pointer(v)) - return } diff --git a/container/seccomp/libseccomp_test.go b/container/seccomp/libseccomp_test.go index 81f5251..d947105 100644 --- a/container/seccomp/libseccomp_test.go +++ b/container/seccomp/libseccomp_test.go @@ -13,6 +13,8 @@ import ( ) func TestExport(t *testing.T) { + t.Parallel() + testCases := []struct { name string flags ExportFlag @@ -32,14 +34,15 @@ func TestExport(t *testing.T) { {"hakurei tty", 0, PresetExt | PresetDenyNS | PresetDenyDevel, false}, } - buf := make([]byte, 8) for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + e := New(Preset(tc.presets, tc.flags), tc.flags) want := bpfExpected[bpfPreset{tc.flags, tc.presets}] digest := sha512.New() - if _, err := io.CopyBuffer(digest, e, buf); (err != nil) != tc.wantErr { + if _, err := io.Copy(digest, e); (err != nil) != tc.wantErr { t.Errorf("Exporter: error = %v, wantErr %v", err, tc.wantErr) return } @@ -47,7 +50,7 @@ func TestExport(t *testing.T) { t.Errorf("Close: error = %v", err) } if got := digest.Sum(nil); !slices.Equal(got, want) { - t.Fatalf("Export() hash = %x, want %x", + t.Fatalf("Export: hash = %x, want %x", got, want) return } diff --git a/container/seccomp/proc.go b/container/seccomp/proc.go index 7027cc6..fb6f543 100644 --- a/container/seccomp/proc.go +++ b/container/seccomp/proc.go @@ -21,9 +21,7 @@ Methods of Encoder are not safe for concurrent use. An Encoder must not be copied after first use. */ -type Encoder struct { - *exporter -} +type Encoder struct{ *exporter } func (e *Encoder) Read(p []byte) (n int, err error) { if err = e.prepare(); err != nil { diff --git a/container/seccomp/seccomp_test.go b/container/seccomp/seccomp_test.go index a3dcad5..c19f2c4 100644 --- a/container/seccomp/seccomp_test.go +++ b/container/seccomp/seccomp_test.go @@ -10,6 +10,8 @@ import ( ) func TestLibraryError(t *testing.T) { + t.Parallel() + testCases := []struct { name string sample *seccomp.LibraryError @@ -41,6 +43,8 @@ func TestLibraryError(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + if errors.Is(tc.sample, tc.compare) != tc.wantIs { t.Errorf("errors.Is(%#v, %#v) did not return %v", tc.sample, tc.compare, tc.wantIs) @@ -54,6 +58,8 @@ func TestLibraryError(t *testing.T) { } t.Run("invalid", func(t *testing.T) { + t.Parallel() + wantPanic := "invalid libseccomp error" defer func() { if r := recover(); r != wantPanic { diff --git a/container/seccomp/syscall_test.go b/container/seccomp/syscall_test.go index 933f060..e385a12 100644 --- a/container/seccomp/syscall_test.go +++ b/container/seccomp/syscall_test.go @@ -5,15 +5,17 @@ import ( ) func TestSyscallResolveName(t *testing.T) { + t.Parallel() + for name, want := range Syscalls() { t.Run(name, func(t *testing.T) { + t.Parallel() + if got := syscallResolveName(name); got != want { - t.Errorf("syscallResolveName(%q) = %d, want %d", - name, got, want) + t.Errorf("syscallResolveName(%q) = %d, want %d", name, got, want) } if got, ok := SyscallResolveName(name); !ok || got != want { - t.Errorf("SyscallResolveName(%q) = %d, want %d", - name, got, want) + t.Errorf("SyscallResolveName(%q) = %d, want %d", name, got, want) } }) } diff --git a/container/stub/call_test.go b/container/stub/call_test.go index 6718798..db0b59d 100644 --- a/container/stub/call_test.go +++ b/container/stub/call_test.go @@ -8,13 +8,17 @@ import ( ) func TestCallError(t *testing.T) { + t.Parallel() + t.Run("contains false", func(t *testing.T) { + t.Parallel() if err := new(stub.Call).Error(true, false, true); !reflect.DeepEqual(err, stub.ErrCheck) { t.Errorf("Error: %#v, want %#v", err, stub.ErrCheck) } }) t.Run("passthrough", func(t *testing.T) { + t.Parallel() wantErr := stub.UniqueError(0xbabe) if err := (&stub.Call{Err: wantErr}).Error(true); !reflect.DeepEqual(err, wantErr) { t.Errorf("Error: %#v, want %#v", err, wantErr) diff --git a/container/stub/errors_test.go b/container/stub/errors_test.go index 4d9252d..604841a 100644 --- a/container/stub/errors_test.go +++ b/container/stub/errors_test.go @@ -9,7 +9,10 @@ import ( ) func TestUniqueError(t *testing.T) { + t.Parallel() + t.Run("format", func(t *testing.T) { + t.Parallel() want := "unique error 2989 injected by the test suite" if got := stub.UniqueError(0xbad).Error(); got != want { t.Errorf("Error: %q, want %q", got, want) @@ -17,13 +20,17 @@ func TestUniqueError(t *testing.T) { }) t.Run("is", func(t *testing.T) { + t.Parallel() + t.Run("type", func(t *testing.T) { + t.Parallel() if errors.Is(stub.UniqueError(0), syscall.ENOTRECOVERABLE) { t.Error("Is: unexpected true") } }) t.Run("val", func(t *testing.T) { + t.Parallel() if errors.Is(stub.UniqueError(0), stub.UniqueError(1)) { t.Error("Is: unexpected true") } diff --git a/container/stub/exit_test.go b/container/stub/exit_test.go index 4e935ff..15ad31f 100644 --- a/container/stub/exit_test.go +++ b/container/stub/exit_test.go @@ -32,13 +32,20 @@ func (o *overrideTFailNow) Fail() { } func TestHandleExit(t *testing.T) { + t.Parallel() + t.Run("exit", func(t *testing.T) { + t.Parallel() defer stub.HandleExit(t) panic(stub.PanicExit) }) t.Run("goexit", func(t *testing.T) { + t.Parallel() + t.Run("FailNow", func(t *testing.T) { + t.Parallel() + ot := &overrideTFailNow{T: t} defer func() { if !ot.failNow { @@ -50,6 +57,8 @@ func TestHandleExit(t *testing.T) { }) t.Run("Fail", func(t *testing.T) { + t.Parallel() + ot := &overrideTFailNow{T: t} defer func() { if !ot.fail { @@ -62,11 +71,16 @@ func TestHandleExit(t *testing.T) { }) t.Run("nil", func(t *testing.T) { + t.Parallel() defer stub.HandleExit(t) }) t.Run("passthrough", func(t *testing.T) { + t.Parallel() + t.Run("toplevel", func(t *testing.T) { + t.Parallel() + defer func() { want := 0xcafebabe if r := recover(); r != want { @@ -79,6 +93,8 @@ func TestHandleExit(t *testing.T) { }) t.Run("new", func(t *testing.T) { + t.Parallel() + defer func() { want := 0xcafe if r := recover(); r != want { diff --git a/container/stub/stub_test.go b/container/stub/stub_test.go index de9971f..9c9b0eb 100644 --- a/container/stub/stub_test.go +++ b/container/stub/stub_test.go @@ -36,8 +36,14 @@ func (t *overrideT) Errorf(format string, args ...any) { } func TestStub(t *testing.T) { + t.Parallel() + t.Run("goexit", func(t *testing.T) { + t.Parallel() + t.Run("FailNow", func(t *testing.T) { + t.Parallel() + defer func() { if r := recover(); r != panicFailNow { t.Errorf("recover: %v", r) @@ -47,6 +53,8 @@ func TestStub(t *testing.T) { }) t.Run("SkipNow", func(t *testing.T) { + t.Parallel() + defer func() { want := "invalid call to SkipNow" if r := recover(); r != want { @@ -57,6 +65,8 @@ func TestStub(t *testing.T) { }) t.Run("Skip", func(t *testing.T) { + t.Parallel() + defer func() { want := "invalid call to Skip" if r := recover(); r != want { @@ -67,6 +77,8 @@ func TestStub(t *testing.T) { }) t.Run("Skipf", func(t *testing.T) { + t.Parallel() + defer func() { want := "invalid call to Skipf" if r := recover(); r != want { @@ -78,7 +90,11 @@ func TestStub(t *testing.T) { }) t.Run("new", func(t *testing.T) { + t.Parallel() + t.Run("success", func(t *testing.T) { + t.Parallel() + s := New(t, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{ {"New", ExpectArgs{}, nil, nil}, }, Tracks: []Expect{{Calls: []Call{ @@ -112,6 +128,8 @@ func TestStub(t *testing.T) { }) t.Run("overrun", func(t *testing.T) { + t.Parallel() + ot := &overrideT{T: t} ot.error.Store(checkError(t, "New: track overrun")) s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{ @@ -135,7 +153,11 @@ func TestStub(t *testing.T) { }) t.Run("expects", func(t *testing.T) { + t.Parallel() + t.Run("overrun", func(t *testing.T) { + t.Parallel() + ot := &overrideT{T: t} ot.error.Store(checkError(t, "Expects: advancing beyond expected calls")) s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{}) @@ -143,7 +165,11 @@ func TestStub(t *testing.T) { }) t.Run("separator", func(t *testing.T) { + t.Parallel() + t.Run("overrun", func(t *testing.T) { + t.Parallel() + ot := &overrideT{T: t} ot.errorf.Store(checkErrorf(t, "Expects: func = %s, separator overrun", "meow")) s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{ @@ -153,6 +179,8 @@ func TestStub(t *testing.T) { }) t.Run("mismatch", func(t *testing.T) { + t.Parallel() + ot := &overrideT{T: t} ot.errorf.Store(checkErrorf(t, "Expects: separator, want %s", "panic")) s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{ @@ -163,6 +191,8 @@ func TestStub(t *testing.T) { }) t.Run("mismatch", func(t *testing.T) { + t.Parallel() + ot := &overrideT{T: t} ot.errorf.Store(checkErrorf(t, "Expects: func = %s, want %s", "meow", "nya")) s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{ @@ -176,6 +206,8 @@ func TestStub(t *testing.T) { func TestCheckArg(t *testing.T) { t.Run("oob negative", func(t *testing.T) { + t.Parallel() + defer func() { want := "invalid call to CheckArg" if r := recover(); r != want { @@ -191,12 +223,14 @@ func TestCheckArg(t *testing.T) { {"panic", ExpectArgs{PanicExit}, nil, nil}, {"meow", ExpectArgs{-1}, nil, nil}, }}) + t.Run("match", func(t *testing.T) { s.Expects("panic") if !CheckArg(s, "v", PanicExit, 0) { t.Errorf("CheckArg: unexpected false") } }) + t.Run("mismatch", func(t *testing.T) { defer HandleExit(t) s.Expects("meow") @@ -205,6 +239,7 @@ func TestCheckArg(t *testing.T) { t.Errorf("CheckArg: unexpected true") } }) + t.Run("oob", func(t *testing.T) { s.pos++ defer func() { @@ -218,7 +253,11 @@ func TestCheckArg(t *testing.T) { } func TestCheckArgReflect(t *testing.T) { + t.Parallel() + t.Run("oob lower", func(t *testing.T) { + t.Parallel() + defer func() { want := "invalid call to CheckArgReflect" if r := recover(); r != want { diff --git a/container/vfs/mangle_test.go b/container/vfs/mangle_test.go index 2cc65be..0227e8e 100644 --- a/container/vfs/mangle_test.go +++ b/container/vfs/mangle_test.go @@ -7,6 +7,8 @@ import ( ) func TestUnmangle(t *testing.T) { + t.Parallel() + testCases := []struct { want string sample string @@ -17,6 +19,7 @@ func TestUnmangle(t *testing.T) { for _, tc := range testCases { t.Run(tc.want, func(t *testing.T) { + t.Parallel() got := vfs.Unmangle(tc.sample) if got != tc.want { t.Errorf("Unmangle: %q, want %q", diff --git a/container/vfs/mountinfo_test.go b/container/vfs/mountinfo_test.go index 7d9b240..ecca370 100644 --- a/container/vfs/mountinfo_test.go +++ b/container/vfs/mountinfo_test.go @@ -17,6 +17,8 @@ import ( ) func TestDecoderError(t *testing.T) { + t.Parallel() + testCases := []struct { name string err *vfs.DecoderError @@ -35,13 +37,17 @@ func TestDecoderError(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + t.Run("error", func(t *testing.T) { + t.Parallel() if got := tc.err.Error(); got != tc.want { t.Errorf("Error: %s, want %s", got, tc.want) } }) t.Run("is", func(t *testing.T) { + t.Parallel() if !errors.Is(tc.err, tc.target) { t.Errorf("Is: unexpected false") } @@ -54,6 +60,8 @@ func TestDecoderError(t *testing.T) { } func TestMountInfo(t *testing.T) { + t.Parallel() + testCases := []mountInfoTest{ {"count", sampleMountinfoBase + ` 21 20 0:53/ /mnt/test rw,relatime - tmpfs rw @@ -187,7 +195,10 @@ id 20 0:53 / /mnt/test rw,relatime shared:212 - tmpfs rw for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + t.Run("decode", func(t *testing.T) { + t.Parallel() var got *vfs.MountInfo d := vfs.NewMountInfoDecoder(strings.NewReader(tc.sample)) err := d.Decode(&got) @@ -206,6 +217,7 @@ id 20 0:53 / /mnt/test rw,relatime shared:212 - tmpfs rw }) t.Run("iter", func(t *testing.T) { + t.Parallel() d := vfs.NewMountInfoDecoder(strings.NewReader(tc.sample)) tc.check(t, d, "Entries", d.Entries(), d.Err) @@ -217,6 +229,7 @@ id 20 0:53 / /mnt/test rw,relatime shared:212 - tmpfs rw }) t.Run("yield", func(t *testing.T) { + t.Parallel() d := vfs.NewMountInfoDecoder(strings.NewReader(tc.sample)) v := false d.Entries()(func(entry *vfs.MountInfoEntry) bool { v = !v; return v }) diff --git a/container/vfs/unfold_test.go b/container/vfs/unfold_test.go index e04c51a..3e9d270 100644 --- a/container/vfs/unfold_test.go +++ b/container/vfs/unfold_test.go @@ -10,6 +10,8 @@ import ( ) func TestUnfold(t *testing.T) { + t.Parallel() + testCases := []struct { name string sample string @@ -50,6 +52,8 @@ func TestUnfold(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + d := vfs.NewMountInfoDecoder(strings.NewReader(tc.sample)) got, err := d.Unfold(tc.target) diff --git a/helper/args_test.go b/helper/args_test.go index e22842e..3aff8cf 100644 --- a/helper/args_test.go +++ b/helper/args_test.go @@ -11,27 +11,29 @@ import ( ) func TestArgsString(t *testing.T) { + t.Parallel() wantString := strings.Join(wantArgs, " ") if got := argsWt.(fmt.Stringer).String(); got != wantString { - t.Errorf("String: %q, want %q", - got, wantString) + t.Errorf("String: %q, want %q", got, wantString) } } func TestNewCheckedArgs(t *testing.T) { + t.Parallel() + args := []string{"\x00"} if _, err := helper.NewCheckedArgs(args); !errors.Is(err, syscall.EINVAL) { - t.Errorf("NewCheckedArgs: error = %v, wantErr %v", - err, syscall.EINVAL) + t.Errorf("NewCheckedArgs: error = %v, wantErr %v", err, syscall.EINVAL) } t.Run("must panic", func(t *testing.T) { + t.Parallel() + badPayload := []string{"\x00"} defer func() { wantPanic := "invalid argument" if r := recover(); r != wantPanic { - t.Errorf("MustNewCheckedArgs: panic = %v, wantPanic %v", - r, wantPanic) + t.Errorf("MustNewCheckedArgs: panic = %v, wantPanic %v", r, wantPanic) } }() helper.MustNewCheckedArgs(badPayload) diff --git a/helper/cmd_test.go b/helper/cmd_test.go index 64ac643..966707c 100644 --- a/helper/cmd_test.go +++ b/helper/cmd_test.go @@ -13,6 +13,8 @@ import ( ) func TestCmd(t *testing.T) { + t.Parallel() + t.Run("start non-existent helper path", func(t *testing.T) { h := helper.NewDirect(t.Context(), container.Nonexistent, argsWt, false, argF, nil, nil) diff --git a/helper/container_test.go b/helper/container_test.go index 922d825..4c23d3e 100644 --- a/helper/container_test.go +++ b/helper/container_test.go @@ -13,6 +13,8 @@ import ( ) func TestContainer(t *testing.T) { + t.Parallel() + t.Run("start invalid container", func(t *testing.T) { h := helper.New(t.Context(), nil, check.MustAbs(container.Nonexistent), "hakurei", argsWt, false, argF, nil, nil) diff --git a/helper/stub_test.go b/helper/stub_test.go index 0679a73..58a2538 100644 --- a/helper/stub_test.go +++ b/helper/stub_test.go @@ -8,8 +8,4 @@ import ( "hakurei.app/helper" ) -func TestMain(m *testing.M) { - container.TryArgv0(nil) - helper.InternalHelperStub() - os.Exit(m.Run()) -} +func TestMain(m *testing.M) { container.TryArgv0(nil); helper.InternalHelperStub(); os.Exit(m.Run()) } diff --git a/hst/config_test.go b/hst/config_test.go index 211bd1c..f3690eb 100644 --- a/hst/config_test.go +++ b/hst/config_test.go @@ -9,6 +9,8 @@ import ( ) func TestConfigValidate(t *testing.T) { + t.Parallel() + testCases := []struct { name string config *hst.Config @@ -45,6 +47,7 @@ func TestConfigValidate(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() if err := tc.config.Validate(); !reflect.DeepEqual(err, tc.wantErr) { t.Errorf("Validate: error = %#v, want %#v", err, tc.wantErr) } @@ -53,6 +56,8 @@ func TestConfigValidate(t *testing.T) { } func TestExtraPermConfig(t *testing.T) { + t.Parallel() + testCases := []struct { name string config *hst.ExtraPermConfig @@ -72,6 +77,7 @@ func TestExtraPermConfig(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() if got := tc.config.String(); got != tc.want { t.Errorf("String: %q, want %q", got, tc.want) } diff --git a/hst/dbus_test.go b/hst/dbus_test.go index d575f7d..413767e 100644 --- a/hst/dbus_test.go +++ b/hst/dbus_test.go @@ -10,6 +10,8 @@ import ( ) func TestBadInterfaceError(t *testing.T) { + t.Parallel() + testCases := []struct { name string err error @@ -23,6 +25,7 @@ func TestBadInterfaceError(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() if gotError := tc.err.Error(); gotError != tc.want { t.Errorf("Error: %s, want %s", gotError, tc.want) } @@ -36,6 +39,8 @@ func TestBadInterfaceError(t *testing.T) { } func TestBusConfigInterfaces(t *testing.T) { + t.Parallel() + testCases := []struct { name string c *hst.BusConfig @@ -63,6 +68,7 @@ func TestBusConfigInterfaces(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() var got []string if tc.cutoff > 0 { var i int @@ -86,6 +92,8 @@ func TestBusConfigInterfaces(t *testing.T) { } func TestBusConfigCheckInterfaces(t *testing.T) { + t.Parallel() + testCases := []struct { name string c *hst.BusConfig @@ -101,6 +109,7 @@ func TestBusConfigCheckInterfaces(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() if err := tc.c.CheckInterfaces(tc.name); !reflect.DeepEqual(err, tc.err) { t.Errorf("CheckInterfaces: error = %#v, want %#v", err, tc.err) } diff --git a/hst/enablement_test.go b/hst/enablement_test.go index 82059aa..ac8810f 100644 --- a/hst/enablement_test.go +++ b/hst/enablement_test.go @@ -10,6 +10,8 @@ import ( ) func TestEnablementString(t *testing.T) { + t.Parallel() + testCases := []struct { flags hst.Enablement want string @@ -38,6 +40,7 @@ func TestEnablementString(t *testing.T) { for _, tc := range testCases { t.Run(tc.want, func(t *testing.T) { + t.Parallel() if got := tc.flags.String(); got != tc.want { t.Errorf("String: %q, want %q", got, tc.want) } @@ -46,6 +49,8 @@ func TestEnablementString(t *testing.T) { } func TestEnablements(t *testing.T) { + t.Parallel() + testCases := []struct { name string e *hst.Enablements @@ -63,7 +68,10 @@ func TestEnablements(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + t.Run("marshal", func(t *testing.T) { + t.Parallel() if got, err := json.Marshal(tc.e); err != nil { t.Fatalf("Marshal: error = %v", err) } else if string(got) != tc.data { @@ -81,6 +89,8 @@ func TestEnablements(t *testing.T) { }) t.Run("unmarshal", func(t *testing.T) { + t.Parallel() + { got := new(hst.Enablements) if err := json.Unmarshal([]byte(tc.data), &got); err != nil { @@ -116,6 +126,8 @@ func TestEnablements(t *testing.T) { } t.Run("unwrap", func(t *testing.T) { + t.Parallel() + t.Run("nil", func(t *testing.T) { if got := (*hst.Enablements)(nil).Unwrap(); got != 0 { t.Errorf("Unwrap: %v", got) @@ -130,6 +142,8 @@ func TestEnablements(t *testing.T) { }) t.Run("passthrough", func(t *testing.T) { + t.Parallel() + if _, err := (*hst.Enablements)(nil).MarshalJSON(); !errors.Is(err, syscall.EINVAL) { t.Errorf("MarshalJSON: error = %v", err) } diff --git a/hst/fs_test.go b/hst/fs_test.go index 8350be5..10e075b 100644 --- a/hst/fs_test.go +++ b/hst/fs_test.go @@ -15,6 +15,8 @@ import ( ) func TestFilesystemConfigJSON(t *testing.T) { + t.Parallel() + testCases := []struct { name string want hst.FilesystemConfigJSON @@ -86,7 +88,10 @@ func TestFilesystemConfigJSON(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + t.Run("marshal", func(t *testing.T) { + t.Parallel() wantErr := tc.wantErr if errors.As(wantErr, new(hst.FSTypeError)) { // for unsupported implementation tc @@ -122,6 +127,7 @@ func TestFilesystemConfigJSON(t *testing.T) { }) t.Run("unmarshal", func(t *testing.T) { + t.Parallel() if tc.data == "\x00" && tc.sData == "\x00" { if errors.As(tc.wantErr, new(hst.FSImplError)) { // this error is only returned on marshal @@ -163,6 +169,8 @@ func TestFilesystemConfigJSON(t *testing.T) { } t.Run("valid", func(t *testing.T) { + t.Parallel() + if got := (*hst.FilesystemConfigJSON).Valid(nil); got { t.Errorf("Valid: %v, want false", got) } @@ -177,6 +185,7 @@ func TestFilesystemConfigJSON(t *testing.T) { }) t.Run("passthrough", func(t *testing.T) { + t.Parallel() if err := new(hst.FilesystemConfigJSON).UnmarshalJSON(make([]byte, 0)); err == nil { t.Errorf("UnmarshalJSON: error = %v", err) } @@ -184,7 +193,10 @@ func TestFilesystemConfigJSON(t *testing.T) { } func TestFSErrors(t *testing.T) { + t.Parallel() + t.Run("type", func(t *testing.T) { + t.Parallel() want := `invalid filesystem type "cat"` if got := hst.FSTypeError("cat").Error(); got != want { t.Errorf("Error: %q, want %q", got, want) @@ -192,6 +204,8 @@ func TestFSErrors(t *testing.T) { }) t.Run("impl", func(t *testing.T) { + t.Parallel() + testCases := []struct { name string val hst.FilesystemConfig @@ -205,6 +219,7 @@ func TestFSErrors(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() err := hst.FSImplError{Value: tc.val} if got := err.Error(); got != tc.want { t.Errorf("Error: %q, want %q", got, tc.want) @@ -242,13 +257,17 @@ type fsTestCase struct { func checkFs(t *testing.T, testCases []fsTestCase) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + t.Run("valid", func(t *testing.T) { + t.Parallel() if got := tc.fs.Valid(); got != tc.valid { t.Errorf("Valid: %v, want %v", got, tc.valid) } }) t.Run("ops", func(t *testing.T) { + t.Parallel() ops := new(container.Ops) tc.fs.Apply(&hst.ApplyState{AutoEtcPrefix: ":3", Ops: opsAdapter{ops}}) if !reflect.DeepEqual(ops, &tc.ops) { @@ -265,18 +284,21 @@ func checkFs(t *testing.T, testCases []fsTestCase) { }) t.Run("path", func(t *testing.T) { + t.Parallel() if got := tc.fs.Path(); !reflect.DeepEqual(got, tc.path) { t.Errorf("Target: %q, want %q", got, tc.path) } }) t.Run("host", func(t *testing.T) { + t.Parallel() if got := tc.fs.Host(); !reflect.DeepEqual(got, tc.host) { t.Errorf("Host: %q, want %q", got, tc.host) } }) t.Run("string", func(t *testing.T) { + t.Parallel() if tc.str == "\x00" { return } diff --git a/hst/fsbind_test.go b/hst/fsbind_test.go index 62de240..d5cf102 100644 --- a/hst/fsbind_test.go +++ b/hst/fsbind_test.go @@ -9,6 +9,8 @@ import ( ) func TestFSBind(t *testing.T) { + t.Parallel() + checkFs(t, []fsTestCase{ {"nil", (*hst.FSBind)(nil), false, nil, nil, nil, ""}, {"ensure optional", &hst.FSBind{Source: m("/"), Ensure: true, Optional: true}, diff --git a/hst/fsephemeral_test.go b/hst/fsephemeral_test.go index 4bda316..23399ac 100644 --- a/hst/fsephemeral_test.go +++ b/hst/fsephemeral_test.go @@ -9,6 +9,8 @@ import ( ) func TestFSEphemeral(t *testing.T) { + t.Parallel() + checkFs(t, []fsTestCase{ {"nil", (*hst.FSEphemeral)(nil), false, nil, nil, nil, ""}, diff --git a/hst/fslink_test.go b/hst/fslink_test.go index b3e196e..758ae42 100644 --- a/hst/fslink_test.go +++ b/hst/fslink_test.go @@ -8,6 +8,8 @@ import ( ) func TestFSLink(t *testing.T) { + t.Parallel() + checkFs(t, []fsTestCase{ {"nil", (*hst.FSLink)(nil), false, nil, nil, nil, ""}, {"zero", new(hst.FSLink), false, nil, nil, nil, ""}, diff --git a/hst/fsoverlay_test.go b/hst/fsoverlay_test.go index 15875bb..df6ec08 100644 --- a/hst/fsoverlay_test.go +++ b/hst/fsoverlay_test.go @@ -9,6 +9,8 @@ import ( ) func TestFSOverlay(t *testing.T) { + t.Parallel() + checkFs(t, []fsTestCase{ {"nil", (*hst.FSOverlay)(nil), false, nil, nil, nil, ""}, {"nil lower", &hst.FSOverlay{Target: m("/etc"), Lower: []*check.Absolute{nil}}, false, nil, nil, nil, ""}, diff --git a/hst/hst_test.go b/hst/hst_test.go index 247df2c..8bca8d6 100644 --- a/hst/hst_test.go +++ b/hst/hst_test.go @@ -14,6 +14,8 @@ import ( ) func TestAppError(t *testing.T) { + t.Parallel() + testCases := []struct { name string err error @@ -58,13 +60,17 @@ func TestAppError(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + t.Run("error", func(t *testing.T) { + t.Parallel() if got := tc.err.Error(); got != tc.s { t.Errorf("Error: %s, want %s", got, tc.s) } }) t.Run("message", func(t *testing.T) { + t.Parallel() gotMessage, gotMessageOk := message.GetMessage(tc.err) if want := tc.message != "\x00"; gotMessageOk != want { t.Errorf("GetMessage: ok = %v, want %v", gotMessage, want) @@ -78,6 +84,7 @@ func TestAppError(t *testing.T) { }) t.Run("is", func(t *testing.T) { + t.Parallel() if !errors.Is(tc.err, tc.is) { t.Errorf("Is: unexpected false for %v", tc.is) } @@ -90,6 +97,8 @@ func TestAppError(t *testing.T) { } func TestTemplate(t *testing.T) { + t.Parallel() + const want = `{ "id": "org.chromium.Chromium", "enablements": { diff --git a/internal/app/app_test.go b/internal/app/app_test.go index 0142152..2f42f70 100644 --- a/internal/app/app_test.go +++ b/internal/app/app_test.go @@ -28,6 +28,7 @@ import ( ) func TestApp(t *testing.T) { + t.Parallel() msg := message.NewMsg(nil) msg.SwapVerbose(testing.Verbose()) @@ -445,6 +446,7 @@ func TestApp(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() gr, gw := io.Pipe() var gotSys *system.I diff --git a/internal/app/dispatcher_test.go b/internal/app/dispatcher_test.go index b39986f..3e608c3 100644 --- a/internal/app/dispatcher_test.go +++ b/internal/app/dispatcher_test.go @@ -77,6 +77,7 @@ func checkOpBehaviour(t *testing.T, testCases []opBehaviourTestCase) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Helper() + t.Parallel() wantCallsFull := slices.Concat(wantNewState, tc.toSystem, []stub.Call{{Name: stub.CallSeparator}}) if tc.wantErrSystem == nil { diff --git a/internal/app/env_test.go b/internal/app/env_test.go index b28c156..9e2c959 100644 --- a/internal/app/env_test.go +++ b/internal/app/env_test.go @@ -13,6 +13,8 @@ import ( ) func TestEnvPaths(t *testing.T) { + t.Parallel() + testCases := []struct { name string env *EnvPaths @@ -48,6 +50,7 @@ func TestEnvPaths(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() if tc.wantPanic != "" { defer func() { if r := recover(); r != tc.wantPanic { @@ -66,6 +69,8 @@ func TestEnvPaths(t *testing.T) { } func TestCopyPaths(t *testing.T) { + t.Parallel() + testCases := []struct { name string env map[string]string @@ -84,6 +89,7 @@ func TestCopyPaths(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() if tc.fatal != "" { defer stub.HandleExit(t) } diff --git a/internal/app/outcome_test.go b/internal/app/outcome_test.go index 183dbfd..53c8958 100644 --- a/internal/app/outcome_test.go +++ b/internal/app/outcome_test.go @@ -8,6 +8,8 @@ import ( ) func TestOutcomeStateValid(t *testing.T) { + t.Parallel() + testCases := []struct { name string s *outcomeState @@ -23,6 +25,7 @@ func TestOutcomeStateValid(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() if got := tc.s.valid(); got != tc.want { t.Errorf("valid: %v, want %v", got, tc.want) } diff --git a/internal/app/path_test.go b/internal/app/path_test.go index b01d73c..1f2d8fa 100644 --- a/internal/app/path_test.go +++ b/internal/app/path_test.go @@ -5,6 +5,8 @@ import ( ) func TestDeepContainsH(t *testing.T) { + t.Parallel() + testCases := []struct { name string basepath string @@ -75,6 +77,7 @@ func TestDeepContainsH(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() if got, err := deepContainsH(tc.basepath, tc.targpath); (err != nil) != tc.wantErr { t.Errorf("deepContainsH() error = %v, wantErr %v", err, tc.wantErr) } else if got != tc.want { diff --git a/internal/app/spaccount_test.go b/internal/app/spaccount_test.go index a587c12..7ebda46 100644 --- a/internal/app/spaccount_test.go +++ b/internal/app/spaccount_test.go @@ -12,6 +12,7 @@ import ( ) func TestSpAccountOp(t *testing.T) { + t.Parallel() config := hst.Template() checkOpBehaviour(t, []opBehaviourTestCase{ diff --git a/internal/app/spcontainer_test.go b/internal/app/spcontainer_test.go index d5bb6d0..6d5713c 100644 --- a/internal/app/spcontainer_test.go +++ b/internal/app/spcontainer_test.go @@ -19,6 +19,7 @@ import ( ) func TestSpParamsOp(t *testing.T) { + t.Parallel() config := hst.Template() checkOpBehaviour(t, []opBehaviourTestCase{ @@ -422,5 +423,5 @@ type invalidFSHost bool func (f invalidFSHost) Valid() bool { return bool(f) } func (invalidFSHost) Path() *check.Absolute { panic("unreachable") } func (invalidFSHost) Host() []*check.Absolute { return []*check.Absolute{nil} } -func (invalidFSHost) Apply(z *hst.ApplyState) { panic("unreachable") } +func (invalidFSHost) Apply(*hst.ApplyState) { panic("unreachable") } func (invalidFSHost) String() string { panic("unreachable") } diff --git a/internal/app/sysconf_test.go b/internal/app/sysconf_test.go index b73f2d0..fb0c7f8 100644 --- a/internal/app/sysconf_test.go +++ b/internal/app/sysconf_test.go @@ -7,6 +7,8 @@ const ( ) func TestSysconf(t *testing.T) { + t.Parallel() + t.Run("LOGIN_NAME_MAX", func(t *testing.T) { if got := sysconf(_SC_LOGIN_NAME_MAX); got < _POSIX_LOGIN_NAME_MAX { t.Errorf("sysconf(_SC_LOGIN_NAME_MAX): %d < _POSIX_LOGIN_NAME_MAX", got) diff --git a/internal/app/username_test.go b/internal/app/username_test.go index 15f15a4..1b2e045 100644 --- a/internal/app/username_test.go +++ b/internal/app/username_test.go @@ -6,6 +6,8 @@ import ( ) func TestIsValidUsername(t *testing.T) { + t.Parallel() + t.Run("long", func(t *testing.T) { if isValidUsername(strings.Repeat("a", sysconf(_SC_LOGIN_NAME_MAX))) { t.Errorf("isValidUsername unexpected true") diff --git a/internal/path_test.go b/internal/path_test.go index cb4571e..5bcdd85 100644 --- a/internal/path_test.go +++ b/internal/path_test.go @@ -8,6 +8,8 @@ import ( ) func TestMustCheckPath(t *testing.T) { + t.Parallel() + testCases := []struct { name string pathname string @@ -20,6 +22,7 @@ func TestMustCheckPath(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() fatal := func(v ...any) { t.Fatal(append([]any{"invalid call to fatal:"}, v...)...) } if tc.wantFatal != "" { fatal = func(v ...any) { diff --git a/ldd/ldd_test.go b/ldd/ldd_test.go index 707154a..a6044f6 100644 --- a/ldd/ldd_test.go +++ b/ldd/ldd_test.go @@ -9,6 +9,8 @@ import ( ) func TestParseError(t *testing.T) { + t.Parallel() + testCases := []struct { name, out string wantErr error @@ -33,6 +35,7 @@ libzstd.so.1 => /usr/lib/libzstd.so.1 7ff71bfd2000 } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() if _, err := ldd.Parse([]byte(tc.out)); !errors.Is(err, tc.wantErr) { t.Errorf("Parse() error = %v, wantErr %v", err, tc.wantErr) } @@ -41,6 +44,8 @@ libzstd.so.1 => /usr/lib/libzstd.so.1 7ff71bfd2000 } func TestParse(t *testing.T) { + t.Parallel() + testCases := []struct { file, out string want []*ldd.Entry @@ -107,6 +112,7 @@ libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7ff71c0a4000)`, } for _, tc := range testCases { t.Run(tc.file, func(t *testing.T) { + t.Parallel() if got, err := ldd.Parse([]byte(tc.out)); err != nil { t.Errorf("Parse() error = %v", err) } else if !reflect.DeepEqual(got, tc.want) { diff --git a/message/message_test.go b/message/message_test.go index 93ceaac..6b781e3 100644 --- a/message/message_test.go +++ b/message/message_test.go @@ -15,6 +15,8 @@ import ( ) func TestMessageError(t *testing.T) { + t.Parallel() + testCases := []struct { name string err error @@ -30,6 +32,7 @@ func TestMessageError(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() got, ok := message.GetMessage(tc.err) if got != tc.want { t.Errorf("GetMessage: %q, want %q", got, tc.want) @@ -44,6 +47,7 @@ func TestMessageError(t *testing.T) { func TestDefaultMsg(t *testing.T) { // copied from output.go const suspendBufMax = 1 << 24 + t.Parallel() t.Run("logger", func(t *testing.T) { t.Run("nil", func(t *testing.T) { diff --git a/message/output_test.go b/message/output_test.go index ab69fe5..0305f3f 100644 --- a/message/output_test.go +++ b/message/output_test.go @@ -15,6 +15,7 @@ import ( func TestSuspendable(t *testing.T) { // copied from output.go const suspendBufMax = 1 << 24 + t.Parallel() const ( // equivalent to len(want.pt) diff --git a/system/acl_test.go b/system/acl_test.go index 992271a..a7465f2 100644 --- a/system/acl_test.go +++ b/system/acl_test.go @@ -11,6 +11,8 @@ import ( ) func TestACLUpdateOp(t *testing.T) { + t.Parallel() + checkOpBehaviour(t, []opBehaviourTestCase{ {"apply aclUpdate", 0xdeadbeef, 0xff, &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{ diff --git a/system/dbus/address_escape_test.go b/system/dbus/address_escape_test.go index 3ea2cd2..4ef48f8 100644 --- a/system/dbus/address_escape_test.go +++ b/system/dbus/address_escape_test.go @@ -5,6 +5,8 @@ import ( ) func TestUnescapeValue(t *testing.T) { + t.Parallel() + testCases := []struct { value string want string @@ -45,6 +47,8 @@ func TestUnescapeValue(t *testing.T) { for _, tc := range testCases { t.Run("unescape "+tc.value, func(t *testing.T) { + t.Parallel() + if got, errno := unescapeValue([]byte(tc.value)); errno != tc.wantErr { t.Errorf("unescapeValue() errno = %v, wantErr %v", errno, tc.wantErr) } else if tc.wantErr == errSuccess && string(got) != tc.want { diff --git a/system/dbus/address_test.go b/system/dbus/address_test.go index 6bd0627..5de9053 100644 --- a/system/dbus/address_test.go +++ b/system/dbus/address_test.go @@ -9,6 +9,8 @@ import ( ) func TestParse(t *testing.T) { + t.Parallel() + testCases := []struct { name string addr string @@ -109,6 +111,8 @@ func TestParse(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + if got, err := dbus.Parse([]byte(tc.addr)); !errors.Is(err, tc.wantErr) { t.Errorf("Parse() error = %v, wantErr %v", err, tc.wantErr) } else if tc.wantErr == nil && !reflect.DeepEqual(got, tc.want) { diff --git a/system/dbus/config_test.go b/system/dbus/config_test.go index 84477e4..644c766 100644 --- a/system/dbus/config_test.go +++ b/system/dbus/config_test.go @@ -11,6 +11,8 @@ import ( ) func TestConfigArgs(t *testing.T) { + t.Parallel() + for _, tc := range testCasesExt { if tc.wantErr { // args does not check for nulls @@ -18,6 +20,8 @@ func TestConfigArgs(t *testing.T) { } t.Run("build arguments for "+tc.id, func(t *testing.T) { + t.Parallel() + if got := dbus.Args(tc.c, tc.bus); !slices.Equal(got, tc.want) { t.Errorf("Args: %v, want %v", got, tc.want) } @@ -26,6 +30,7 @@ func TestConfigArgs(t *testing.T) { } func TestNewConfig(t *testing.T) { + t.Parallel() ids := [...]string{"org.chromium.Chromium", "dev.vencord.Vesktop"} type newTestCase struct { @@ -107,6 +112,8 @@ func TestNewConfig(t *testing.T) { } t.Run(name.String(), func(t *testing.T) { + t.Parallel() + if gotC := dbus.NewConfig(tc.id, tc.args[0], tc.args[1]); !reflect.DeepEqual(gotC, tc.want) { t.Errorf("NewConfig(%q, %t, %t) = %v, want %v", tc.id, tc.args[0], tc.args[1], diff --git a/system/dbus/dbus_test.go b/system/dbus/dbus_test.go index 299a463..abe324b 100644 --- a/system/dbus/dbus_test.go +++ b/system/dbus/dbus_test.go @@ -65,7 +65,7 @@ func TestProxyStartWaitCloseString(t *testing.T) { } const ( - stubProxyTimeout = 30 * time.Second + stubProxyTimeout = 5 * time.Second ) func testProxyFinaliseStartWaitCloseString(t *testing.T, useSandbox bool) { @@ -99,8 +99,7 @@ func testProxyFinaliseStartWaitCloseString(t *testing.T, useSandbox bool) { } if err := p.Start(); !errors.Is(err, syscall.ENOTRECOVERABLE) { - t.Errorf("Start: error = %q, wantErr %q", - err, syscall.ENOTRECOVERABLE) + t.Errorf("Start: error = %q, wantErr %q", err, syscall.ENOTRECOVERABLE) return } }) @@ -115,71 +114,57 @@ func testProxyFinaliseStartWaitCloseString(t *testing.T, useSandbox bool) { var final *dbus.Final t.Run("finalise", func(t *testing.T) { if v, err := dbus.Finalise(tc[0].bus, tc[1].bus, tc[0].c, tc[1].c); err != nil { - t.Errorf("Finalise: error = %v, wantErr %v", - err, tc[0].wantErr) + t.Errorf("Finalise: error = %v, wantErr %v", err, tc[0].wantErr) return } else { final = v } }) - t.Run("run", func(t *testing.T) { - ctx, cancel := context.WithTimeout(t.Context(), stubProxyTimeout) - defer cancel() - output := new(strings.Builder) - if !useSandbox { - p = dbus.NewDirect(ctx, message.NewMsg(nil), final, output) - } else { - p = dbus.New(ctx, message.NewMsg(nil), final, output) + ctx, cancel := context.WithTimeout(t.Context(), stubProxyTimeout) + defer cancel() + output := new(strings.Builder) + if !useSandbox { + p = dbus.NewDirect(ctx, message.NewMsg(nil), final, output) + } else { + p = dbus.New(ctx, message.NewMsg(nil), final, output) + } + + { // check invalid wait behaviour + wantErr := "dbus: not started" + if err := p.Wait(); err == nil || err.Error() != wantErr { + t.Errorf("Wait: error = %v, wantErr %v", err, wantErr) } + } - t.Run("invalid wait", func(t *testing.T) { - wantErr := "dbus: not started" - if err := p.Wait(); err == nil || err.Error() != wantErr { - t.Errorf("Wait: error = %v, wantErr %v", - err, wantErr) - } - }) - - t.Run("string", func(t *testing.T) { - want := "(unused dbus proxy)" - if got := p.String(); got != want { - t.Errorf("String: %q, want %q", - got, want) - return - } - }) - - if err := p.Start(); err != nil { - t.Fatalf("Start: error = %v", - err) + { // check string behaviour + want := "(unused dbus proxy)" + if got := p.String(); got != want { + t.Errorf("String: %q, want %q", got, want) + return } + } - t.Run("string", func(t *testing.T) { - wantSubstr := fmt.Sprintf("%s --args=3 --fd=4", os.Args[0]) - if useSandbox { - wantSubstr = `argv: ["xdg-dbus-proxy" "--args=3" "--fd=4"], filter: true, rules: 0, flags: 0x1, presets: 0xf` - } - if got := p.String(); !strings.Contains(got, wantSubstr) { - t.Errorf("String: %q, want %q", - got, wantSubstr) - return - } - }) + if err := p.Start(); err != nil { + t.Fatalf("Start: error = %v", err) + } - t.Run("wait", func(t *testing.T) { - done := make(chan struct{}) - go func() { - if err := p.Wait(); err != nil { - t.Errorf("Wait: error = %v\noutput: %s", - err, output.String()) - } - close(done) - }() - p.Close() - <-done - }) - }) + { // check running string behaviour + wantSubstr := fmt.Sprintf("%s --args=3 --fd=4", os.Args[0]) + if useSandbox { + wantSubstr = `argv: ["xdg-dbus-proxy" "--args=3" "--fd=4"], filter: true, rules: 0, flags: 0x1, presets: 0xf` + } + if got := p.String(); !strings.Contains(got, wantSubstr) { + t.Errorf("String: %q, want %q", + got, wantSubstr) + return + } + } + + p.Close() + if err := p.Wait(); err != nil { + t.Errorf("Wait: error = %v\noutput: %s", err, output.String()) + } }) } } diff --git a/system/dbus/proc.go b/system/dbus/proc.go index 005b914..b386eec 100644 --- a/system/dbus/proc.go +++ b/system/dbus/proc.go @@ -146,7 +146,7 @@ func (p *Proxy) Wait() error { return errors.New("dbus: not started") } - errs := make([]error, 3) + var errs [3]error errs[0] = p.helper.Wait() if errors.Is(errs[0], context.Canceled) && @@ -165,7 +165,7 @@ func (p *Proxy) Wait() error { } } - return errors.Join(errs...) + return errors.Join(errs[:]...) } // Close cancels the context passed to the helper instance attached to xdg-dbus-proxy. diff --git a/system/dbus/proc_test.go b/system/dbus/proc_test.go index 8b41c04..a3ce163 100644 --- a/system/dbus/proc_test.go +++ b/system/dbus/proc_test.go @@ -8,8 +8,4 @@ import ( "hakurei.app/helper" ) -func TestMain(m *testing.M) { - container.TryArgv0(nil) - helper.InternalHelperStub() - os.Exit(m.Run()) -} +func TestMain(m *testing.M) { container.TryArgv0(nil); helper.InternalHelperStub(); os.Exit(m.Run()) } diff --git a/system/dbus_test.go b/system/dbus_test.go index 0bc7b7f..2a1f12d 100644 --- a/system/dbus_test.go +++ b/system/dbus_test.go @@ -16,6 +16,8 @@ import ( ) func TestDBusProxyOp(t *testing.T) { + t.Parallel() + checkOpBehaviour(t, []opBehaviourTestCase{ {"dbusProxyStart", 0xdeadbeef, 0xff, &dbusProxyOp{ final: dbusNewFinalSample(4), @@ -377,6 +379,8 @@ func dbusNewFinalSample(v int) *dbus.Final { } func TestLinePrefixWriter(t *testing.T) { + t.Parallel() + testCases := []struct { name string prefix string @@ -588,6 +592,7 @@ func TestLinePrefixWriter(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() gotPt := make([]string, 0, len(tc.wantPt)) out := &linePrefixWriter{ prefix: tc.prefix, @@ -631,11 +636,11 @@ func TestLinePrefixWriter(t *testing.T) { } wantDump := make([]string, len(tc.want)+len(tc.wantExt)) - for i, m := range tc.want { - wantDump[i] = tc.prefix + m + for i, want := range tc.want { + wantDump[i] = tc.prefix + want } - for i, m := range tc.wantExt { - wantDump[len(tc.want)+i] = m + for i, want := range tc.wantExt { + wantDump[len(tc.want)+i] = want } t.Run("dump", func(t *testing.T) { got := make([]string, 0, len(wantDump)) diff --git a/system/dispatcher_test.go b/system/dispatcher_test.go index 9a1a0d9..53444a9 100644 --- a/system/dispatcher_test.go +++ b/system/dispatcher_test.go @@ -42,10 +42,12 @@ func checkOpBehaviour(t *testing.T, testCases []opBehaviourTestCase) { t.Run("behaviour", func(t *testing.T) { t.Helper() + t.Parallel() for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Helper() + t.Parallel() var ec *Criteria if tc.ec != 0xff { @@ -94,10 +96,12 @@ func checkOpsBuilder(t *testing.T, fname string, testCases []opsBuilderTestCase) t.Run("build", func(t *testing.T) { t.Helper() + t.Parallel() for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Helper() + t.Parallel() sys, s := InternalNew(t, tc.exp, tc.uid) defer stub.HandleExit(t) @@ -126,10 +130,12 @@ func checkOpIs(t *testing.T, testCases []opIsTestCase) { t.Run("is", func(t *testing.T) { t.Helper() + t.Parallel() for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Helper() + t.Parallel() if got := tc.op.Is(tc.v); got != tc.want { t.Errorf("Is: %v, want %v", got, tc.want) @@ -153,10 +159,12 @@ func checkOpMeta(t *testing.T, testCases []opMetaTestCase) { t.Run("meta", func(t *testing.T) { t.Helper() + t.Parallel() for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Helper() + t.Parallel() t.Run("type", func(t *testing.T) { t.Helper() diff --git a/system/link_test.go b/system/link_test.go index 2085596..065f9fe 100644 --- a/system/link_test.go +++ b/system/link_test.go @@ -8,6 +8,8 @@ import ( ) func TestHardlinkOp(t *testing.T) { + t.Parallel() + checkOpBehaviour(t, []opBehaviourTestCase{ {"link", 0xdeadbeef, 0xff, &hardlinkOp{hst.EPulse, "/run/user/1000/hakurei/9663730666a44cfc2a81610379e02ed6/pulse", "/run/user/1000/pulse/native"}, []stub.Call{ call("verbose", stub.ExpectArgs{[]any{"linking", &hardlinkOp{hst.EPulse, "/run/user/1000/hakurei/9663730666a44cfc2a81610379e02ed6/pulse", "/run/user/1000/pulse/native"}}}, nil, nil), diff --git a/system/mkdir_test.go b/system/mkdir_test.go index 7d79075..e2f8c11 100644 --- a/system/mkdir_test.go +++ b/system/mkdir_test.go @@ -8,6 +8,8 @@ import ( ) func TestMkdirOp(t *testing.T) { + t.Parallel() + checkOpBehaviour(t, []opBehaviourTestCase{ {"mkdir", 0xdeadbeef, 0xff, &mkdirOp{User, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711, false}, []stub.Call{ call("verbose", stub.ExpectArgs{[]any{"ensuring directory", &mkdirOp{User, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711, false}}}, nil, nil), diff --git a/system/output_test.go b/system/output_test.go index d395b13..c0cbfdf 100644 --- a/system/output_test.go +++ b/system/output_test.go @@ -13,6 +13,8 @@ import ( ) func TestOpError(t *testing.T) { + t.Parallel() + testCases := []struct { name string err error @@ -49,6 +51,8 @@ func TestOpError(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + t.Run("error", func(t *testing.T) { if got := tc.err.Error(); got != tc.s { t.Errorf("Error: %q, want %q", got, tc.s) @@ -88,6 +92,8 @@ func TestOpError(t *testing.T) { } func TestPrintJoinedError(t *testing.T) { + t.Parallel() + testCases := []struct { name string err error @@ -123,6 +129,7 @@ func TestPrintJoinedError(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() var got [][]any printJoinedError(func(v ...any) { got = append(got, v) }, "not a joined error:", tc.err) if !reflect.DeepEqual(got, tc.want) { diff --git a/system/system_test.go b/system/system_test.go index 6d21747..83d97a6 100644 --- a/system/system_test.go +++ b/system/system_test.go @@ -16,6 +16,8 @@ import ( ) func TestCriteria(t *testing.T) { + t.Parallel() + testCases := []struct { name string ec, t hst.Enablement @@ -28,6 +30,7 @@ func TestCriteria(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() var criteria *Criteria if tc.ec != 0xff { criteria = (*Criteria)(&tc.ec) @@ -41,6 +44,8 @@ func TestCriteria(t *testing.T) { } func TestTypeString(t *testing.T) { + t.Parallel() + testCases := []struct { e hst.Enablement want string @@ -58,6 +63,7 @@ func TestTypeString(t *testing.T) { for _, tc := range testCases { t.Run("label type string "+strconv.Itoa(int(tc.e)), func(t *testing.T) { + t.Parallel() if got := TypeString(tc.e); got != tc.want { t.Errorf("TypeString: %q, want %q", got, tc.want) } @@ -66,6 +72,8 @@ func TestTypeString(t *testing.T) { } func TestNew(t *testing.T) { + t.Parallel() + t.Run("panic", func(t *testing.T) { t.Run("ctx", func(t *testing.T) { defer func() { @@ -108,6 +116,8 @@ func TestNew(t *testing.T) { } func TestEqual(t *testing.T) { + t.Parallel() + testCases := []struct { name string sys *I @@ -175,6 +185,8 @@ func TestEqual(t *testing.T) { } func TestCommitRevert(t *testing.T) { + t.Parallel() + testCases := []struct { name string f func(sys *I) @@ -252,6 +264,8 @@ func TestCommitRevert(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + var ec *Criteria if tc.ec != 0xff { ec = (*Criteria)(&tc.ec) diff --git a/system/wayland_test.go b/system/wayland_test.go index d6a3b93..367b1e5 100644 --- a/system/wayland_test.go +++ b/system/wayland_test.go @@ -86,6 +86,8 @@ func (conn *stubWaylandConn) Close() error { } func TestWaylandOp(t *testing.T) { + t.Parallel() + checkOpBehaviour(t, []opBehaviourTestCase{ {"attach", 0xdeadbeef, 0xff, &waylandOp{nil, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", diff --git a/system/xhost_test.go b/system/xhost_test.go index ad3ba89..bcff3a5 100644 --- a/system/xhost_test.go +++ b/system/xhost_test.go @@ -9,6 +9,8 @@ import ( ) func TestXHostOp(t *testing.T) { + t.Parallel() + checkOpBehaviour(t, []opBehaviourTestCase{ {"xcbChangeHosts revert", 0xbeef, hst.EX11, xhostOp("chronos"), []stub.Call{ call("verbosef", stub.ExpectArgs{"inserting entry %s to X11", []any{xhostOp("chronos")}}, nil, nil), diff --git a/test/sandbox/fs_test.go b/test/sandbox/fs_test.go index 8dd920b..62a39d4 100644 --- a/test/sandbox/fs_test.go +++ b/test/sandbox/fs_test.go @@ -19,6 +19,8 @@ var ( ) func TestCompare(t *testing.T) { + t.Parallel() + testCases := []struct { name string @@ -61,6 +63,8 @@ func TestCompare(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + gotOut := new(strings.Builder) oldPrint := sandbox.SwapPrint(func(format string, v ...any) { _, _ = fmt.Fprintf(gotOut, format+"\x00", v...) }) t.Cleanup(func() { sandbox.SwapPrint(oldPrint) }) diff --git a/test/sandbox/mount_test.go b/test/sandbox/mount_test.go index 7d6b0df..f5a407a 100644 --- a/test/sandbox/mount_test.go +++ b/test/sandbox/mount_test.go @@ -11,6 +11,8 @@ import ( ) func TestMountinfo(t *testing.T) { + t.Parallel() + testCases := []struct { name string @@ -93,6 +95,8 @@ func TestMountinfo(t *testing.T) { } t.Run(tc.name, func(t *testing.T) { + t.Parallel() + m := sandbox.NewMountinfo(name) if err := m.Parse(); err != nil { t.Fatalf("Parse: error = %v", err)