From 88d9a6163e9e91b55b6ebe71f335e7617c76b04e Mon Sep 17 00:00:00 2001 From: Ophestra Date: Tue, 17 Feb 2026 14:13:08 +0900 Subject: [PATCH] container/initplace: return nil for createTemp error injection This matches os package behaviour, and avoids adding the cleanup. Signed-off-by: Ophestra --- container/dispatcher_test.go | 7 ++++-- container/initplace_test.go | 22 +++++++++--------- internal/rosa/hakurei.go | 43 +++++++++++++++++++++++++++++++----- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/container/dispatcher_test.go b/container/dispatcher_test.go index 5de37fc..fe0c4db 100644 --- a/container/dispatcher_test.go +++ b/container/dispatcher_test.go @@ -238,8 +238,11 @@ func sliceAddr[S any](s []S) *[]S { return &s } func newCheckedFile(t *testing.T, name, wantData string, closeErr error) osFile { f := &checkedOsFile{t: t, name: name, want: wantData, closeErr: closeErr} - // check happens in Close, and cleanup is not guaranteed to run, so relying on it for sloppy implementations will cause sporadic test results - f.cleanup = runtime.AddCleanup(f, func(name string) { f.t.Fatalf("checkedOsFile %s became unreachable without a call to Close", name) }, f.name) + // check happens in Close, and cleanup is not guaranteed to run, so relying + // on it for sloppy implementations will cause sporadic test results + f.cleanup = runtime.AddCleanup(f, func(name string) { + panic("checkedOsFile " + name + " became unreachable without a call to Close") + }, name) return f } diff --git a/container/initplace_test.go b/container/initplace_test.go index afeddbe..b1de5fb 100644 --- a/container/initplace_test.go +++ b/container/initplace_test.go @@ -21,7 +21,7 @@ func TestTmpfileOp(t *testing.T) { Path: samplePath, Data: sampleData, }, nil, nil, []stub.Call{ - call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), stub.UniqueError(5)), + call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, (*checkedOsFile)(nil), stub.UniqueError(5)), }, stub.UniqueError(5)}, {"Write", &Params{ParentPerm: 0700}, &TmpfileOp{ @@ -35,14 +35,14 @@ func TestTmpfileOp(t *testing.T) { Path: samplePath, Data: sampleData, }, nil, nil, []stub.Call{ - call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, stub.UniqueError(3)), nil), + call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.Close", sampleDataString, stub.UniqueError(3)), nil), }, stub.UniqueError(3)}, {"ensureFile", &Params{ParentPerm: 0700}, &TmpfileOp{ Path: samplePath, Data: sampleData, }, nil, nil, []stub.Call{ - call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), nil), + call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.ensureFile", sampleDataString, nil), nil), call("ensureFile", stub.ExpectArgs{"/sysroot/etc/passwd", os.FileMode(0444), os.FileMode(0700)}, nil, stub.UniqueError(2)), }, stub.UniqueError(2)}, @@ -50,29 +50,29 @@ func TestTmpfileOp(t *testing.T) { Path: samplePath, Data: sampleData, }, nil, nil, []stub.Call{ - call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), nil), + call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.bindMount", sampleDataString, nil), nil), call("ensureFile", stub.ExpectArgs{"/sysroot/etc/passwd", os.FileMode(0444), os.FileMode(0700)}, nil, nil), - call("bindMount", stub.ExpectArgs{"tmp.32768", "/sysroot/etc/passwd", uintptr(0x5), false}, nil, stub.UniqueError(1)), + call("bindMount", stub.ExpectArgs{"tmp.bindMount", "/sysroot/etc/passwd", uintptr(0x5), false}, nil, stub.UniqueError(1)), }, stub.UniqueError(1)}, {"remove", &Params{ParentPerm: 0700}, &TmpfileOp{ Path: samplePath, Data: sampleData, }, nil, nil, []stub.Call{ - call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), nil), + call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.remove", sampleDataString, nil), nil), call("ensureFile", stub.ExpectArgs{"/sysroot/etc/passwd", os.FileMode(0444), os.FileMode(0700)}, nil, nil), - call("bindMount", stub.ExpectArgs{"tmp.32768", "/sysroot/etc/passwd", uintptr(0x5), false}, nil, nil), - call("remove", stub.ExpectArgs{"tmp.32768"}, nil, stub.UniqueError(0)), + call("bindMount", stub.ExpectArgs{"tmp.remove", "/sysroot/etc/passwd", uintptr(0x5), false}, nil, nil), + call("remove", stub.ExpectArgs{"tmp.remove"}, nil, stub.UniqueError(0)), }, stub.UniqueError(0)}, {"success", &Params{ParentPerm: 0700}, &TmpfileOp{ Path: samplePath, Data: sampleData, }, nil, nil, []stub.Call{ - call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), nil), + call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.success", sampleDataString, nil), nil), call("ensureFile", stub.ExpectArgs{"/sysroot/etc/passwd", os.FileMode(0444), os.FileMode(0700)}, nil, nil), - call("bindMount", stub.ExpectArgs{"tmp.32768", "/sysroot/etc/passwd", uintptr(0x5), false}, nil, nil), - call("remove", stub.ExpectArgs{"tmp.32768"}, nil, nil), + call("bindMount", stub.ExpectArgs{"tmp.success", "/sysroot/etc/passwd", uintptr(0x5), false}, nil, nil), + call("remove", stub.ExpectArgs{"tmp.success"}, nil, nil), }, nil}, }) diff --git a/internal/rosa/hakurei.go b/internal/rosa/hakurei.go index a494fd5..be18430 100644 --- a/internal/rosa/hakurei.go +++ b/internal/rosa/hakurei.go @@ -44,11 +44,44 @@ chmod -R +w /usr/src/hakurei cd /usr/src/hakurei HAKUREI_VERSION='v`+version+`' -`+script, pkg.Path(AbsUsrSrc.Append("hakurei"), true, pkg.NewHTTPGetTar( - nil, "https://git.gensokyo.uk/security/hakurei/archive/"+ - "v"+version+".tar.gz", - mustDecode(checksum), - pkg.TarGzip, +`+script, pkg.Path(AbsUsrSrc.Append("hakurei"), true, t.NewPatchedSource( + "hakurei", version, pkg.NewHTTPGetTar( + nil, "https://git.gensokyo.uk/security/hakurei/archive/"+ + "v"+version+".tar.gz", + mustDecode(checksum), + pkg.TarGzip, + ), true, [2]string{"createTemp-error-injection", `diff --git a/container/dispatcher_test.go b/container/dispatcher_test.go +index 5de37fc..fe0c4db 100644 +--- a/container/dispatcher_test.go ++++ b/container/dispatcher_test.go +@@ -238,8 +238,11 @@ func sliceAddr[S any](s []S) *[]S { return &s } + + func newCheckedFile(t *testing.T, name, wantData string, closeErr error) osFile { + f := &checkedOsFile{t: t, name: name, want: wantData, closeErr: closeErr} +- // check happens in Close, and cleanup is not guaranteed to run, so relying on it for sloppy implementations will cause sporadic test results +- f.cleanup = runtime.AddCleanup(f, func(name string) { f.t.Fatalf("checkedOsFile %s became unreachable without a call to Close", name) }, f.name) ++ // check happens in Close, and cleanup is not guaranteed to run, so relying ++ // on it for sloppy implementations will cause sporadic test results ++ f.cleanup = runtime.AddCleanup(f, func(name string) { ++ panic("checkedOsFile " + name + " became unreachable without a call to Close") ++ }, name) + return f + } + +diff --git a/container/initplace_test.go b/container/initplace_test.go +index afeddbe..1c2f20b 100644 +--- a/container/initplace_test.go ++++ b/container/initplace_test.go +@@ -21,7 +21,7 @@ func TestTmpfileOp(t *testing.T) { + Path: samplePath, + Data: sampleData, + }, nil, nil, []stub.Call{ +- call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), stub.UniqueError(5)), ++ call("createTemp", stub.ExpectArgs{"/", "tmp.*"}, (*checkedOsFile)(nil), stub.UniqueError(5)), + }, stub.UniqueError(5)}, + + {"Write", &Params{ParentPerm: 0700}, &TmpfileOp{ +`}, )), pkg.Path(AbsUsrSrc.Append("hostname", "main.go"), false, pkg.NewFile( "hostname.go", []byte(`