aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/app/dispatcher_test.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-10-12 03:58:53 +0900
committerOphestra <cat@gensokyo.uk>2025-10-12 03:58:53 +0900
commitdb7051a36814a5c9e02e22c2e8d1df42c5f4b8f0 (patch)
tree1ca0fcfe061d1b09c3a423dabbc4c535ba8028d9 /internal/app/dispatcher_test.go
parent36f312b3ba45f1bec6341b4f66a1f2e89971bc51 (diff)
internal/app/spcontainer: check fs init behaviour
This covers every statement. Some of them are unreachable unless the kernel returns garbage. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/app/dispatcher_test.go')
-rw-r--r--internal/app/dispatcher_test.go37
1 files changed, 35 insertions, 2 deletions
diff --git a/internal/app/dispatcher_test.go b/internal/app/dispatcher_test.go
index e1d8f538..b39986f2 100644
--- a/internal/app/dispatcher_test.go
+++ b/internal/app/dispatcher_test.go
@@ -2,6 +2,7 @@ package app
import (
"bytes"
+ "io/fs"
"log"
"os"
"os/exec"
@@ -28,6 +29,9 @@ func call(name string, args stub.ExpectArgs, ret any, err error) stub.Call {
// checkExpectUid is the uid value used by checkOpBehaviour to initialise [system.I].
const checkExpectUid = 0xcafebabe
+// wantAutoEtcPrefix is the autoetc prefix corresponding to checkExpectInstanceId.
+const wantAutoEtcPrefix = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+
// checkExpectInstanceId is the [state.ID] value used by checkOpBehaviour to initialise outcomeState.
var checkExpectInstanceId = *(*state.ID)(bytes.Repeat([]byte{0xaa}, len(state.ID{})))
@@ -99,7 +103,7 @@ func checkOpBehaviour(t *testing.T, testCases []opBehaviourTestCase) {
op := tc.newOp(false, true)
if err := op.toSystem(stateSys); !reflect.DeepEqual(err, tc.wantErrSystem) {
- t.Errorf("toSystem: error = %v, want %v", err, tc.wantErrSystem)
+ t.Fatalf("toSystem: error = %#v, want %#v", err, tc.wantErrSystem)
}
k.Expects(stub.CallSeparator)
if !reflect.DeepEqual(config, wantConfig) {
@@ -134,7 +138,7 @@ func checkOpBehaviour(t *testing.T, testCases []opBehaviourTestCase) {
op := tc.newOp(true, true)
if err := op.toContainer(stateParams); !reflect.DeepEqual(err, tc.wantErrContainer) {
- t.Errorf("toContainer: error = %v, want %v", err, tc.wantErrContainer)
+ t.Fatalf("toContainer: error = %#v, want %#v", err, tc.wantErrContainer)
}
if tc.wantErrContainer != nil {
@@ -184,7 +188,19 @@ func (k *kstub) lookupEnv(key string) (string, bool) {
}
return expect.Ret.(string), true
}
+func (k *kstub) readdir(name string) ([]os.DirEntry, error) {
+ k.Helper()
+ expect := k.Expects("readdir")
+ return expect.Ret.([]os.DirEntry), expect.Error(
+ stub.CheckArg(k.Stub, "name", name, 0))
+}
func (k *kstub) tempdir() string { k.Helper(); return k.Expects("tempdir").Ret.(string) }
+func (k *kstub) evalSymlinks(path string) (string, error) {
+ k.Helper()
+ expect := k.Expects("evalSymlinks")
+ return expect.Ret.(string), expect.Error(
+ stub.CheckArg(k.Stub, "path", path, 0))
+}
func (k *kstub) cmdOutput(cmd *exec.Cmd) ([]byte, error) {
k.Helper()
@@ -249,6 +265,23 @@ func (k *kstub) Suspend() bool { k.Helper(); return k.Expects("suspend").Ret.(bo
func (k *kstub) Resume() bool { k.Helper(); return k.Expects("resume").Ret.(bool) }
func (k *kstub) BeforeExit() { k.Helper(); k.Expects("beforeExit") }
+// stubDir returns a slice of [os.DirEntry] with only their Name method implemented.
+func stubDir(names ...string) []os.DirEntry {
+ d := make([]os.DirEntry, len(names))
+ for i, name := range names {
+ d[i] = nameDentry(name)
+ }
+ return d
+}
+
+// nameDentry implements the Name method on [os.DirEntry].
+type nameDentry string
+
+func (e nameDentry) Name() string { return string(e) }
+func (nameDentry) IsDir() bool { panic("unreachable") }
+func (nameDentry) Type() fs.FileMode { panic("unreachable") }
+func (nameDentry) Info() (fs.FileInfo, error) { panic("unreachable") }
+
// panicMsgContext implements [message.Msg] and [context.Context] with methods wrapping panic.
// This should be assigned to test cases to be checked against.
type panicMsgContext struct{}