All checks were successful
Test / Create distribution (push) Successful in 53s
Test / Sandbox (push) Successful in 2m55s
Test / ShareFS (push) Successful in 4m55s
Test / Sandbox (race detector) (push) Successful in 5m20s
Test / Hpkg (push) Successful in 5m38s
Test / Hakurei (push) Successful in 5m49s
Test / Hakurei (race detector) (push) Successful in 5m9s
Test / Flake checks (push) Successful in 1m52s
This directly submits the upperdir to cache. It is primarily used in bootstrapping where tools are limited and should not be used unless there is a very good reason to. Signed-off-by: Ophestra <cat@gensokyo.uk>
326 lines
8.5 KiB
Go
326 lines
8.5 KiB
Go
package pkg_test
|
|
|
|
//go:generate env CGO_ENABLED=0 go build -tags testtool -o testdata/testtool ./testdata
|
|
|
|
import (
|
|
_ "embed"
|
|
"errors"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"testing"
|
|
|
|
"hakurei.app/container/check"
|
|
"hakurei.app/container/fhs"
|
|
"hakurei.app/container/stub"
|
|
"hakurei.app/hst"
|
|
"hakurei.app/internal/pkg"
|
|
"hakurei.app/message"
|
|
)
|
|
|
|
// testtoolBin is the container test tool binary made available to the
|
|
// execArtifact for testing its curing environment.
|
|
//
|
|
//go:embed testdata/testtool
|
|
var testtoolBin []byte
|
|
|
|
func TestExec(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
wantChecksumOffline := pkg.MustDecode(
|
|
"GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9",
|
|
)
|
|
|
|
checkWithCache(t, []cacheTestCase{
|
|
{"offline", nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
|
c.SetStrict(true)
|
|
testtool, testtoolDestroy := newTesttool()
|
|
|
|
msg := message.New(log.New(os.Stderr, "container: ", 0))
|
|
msg.SwapVerbose(testing.Verbose())
|
|
|
|
cureMany(t, c, []cureStep{
|
|
{"container", pkg.NewExec(
|
|
t.Context(),
|
|
msg,
|
|
0,
|
|
nil,
|
|
pkg.AbsWork,
|
|
[]string{"HAKUREI_TEST=1"},
|
|
check.MustAbs("/opt/bin/testtool"),
|
|
[]string{"testtool"},
|
|
|
|
pkg.MustPath("/file", newStubFile(
|
|
pkg.KindHTTPGet,
|
|
pkg.ID{0xfe, 0},
|
|
nil,
|
|
nil, nil,
|
|
)),
|
|
pkg.MustPath("/.hakurei", stubArtifact{
|
|
kind: pkg.KindTar,
|
|
params: []byte("empty directory"),
|
|
cure: func(c *pkg.CureContext) error {
|
|
return os.MkdirAll(c.GetWorkDir().String(), 0700)
|
|
},
|
|
}),
|
|
pkg.MustPath("/opt", testtool),
|
|
), ignorePathname, wantChecksumOffline, nil},
|
|
|
|
{"error passthrough", pkg.NewExec(
|
|
t.Context(),
|
|
msg,
|
|
0,
|
|
nil,
|
|
pkg.AbsWork,
|
|
[]string{"HAKUREI_TEST=1"},
|
|
check.MustAbs("/opt/bin/testtool"),
|
|
[]string{"testtool"},
|
|
|
|
pkg.MustPath("/proc/nonexistent", stubArtifact{
|
|
kind: pkg.KindTar,
|
|
params: []byte("doomed artifact"),
|
|
cure: func(c *pkg.CureContext) error {
|
|
return stub.UniqueError(0xcafe)
|
|
},
|
|
}),
|
|
), nil, pkg.Checksum{}, errors.Join(stub.UniqueError(0xcafe))},
|
|
|
|
{"invalid paths", pkg.NewExec(
|
|
t.Context(),
|
|
msg,
|
|
0,
|
|
nil,
|
|
pkg.AbsWork,
|
|
[]string{"HAKUREI_TEST=1"},
|
|
check.MustAbs("/opt/bin/testtool"),
|
|
[]string{"testtool"},
|
|
|
|
pkg.ExecContainerPath{},
|
|
), nil, pkg.Checksum{}, os.ErrInvalid},
|
|
})
|
|
|
|
// check init failure passthrough
|
|
var exitError *exec.ExitError
|
|
if _, _, err := c.Cure(pkg.NewExec(
|
|
t.Context(),
|
|
msg,
|
|
0,
|
|
nil,
|
|
pkg.AbsWork,
|
|
nil,
|
|
check.MustAbs("/opt/bin/testtool"),
|
|
[]string{"testtool"},
|
|
)); !errors.As(err, &exitError) ||
|
|
exitError.ExitCode() != hst.ExitFailure {
|
|
t.Fatalf("Cure: error = %v, want init exit status 1", err)
|
|
}
|
|
|
|
testtoolDestroy(t, base, c)
|
|
}, pkg.MustDecode("7PoPpWLjFPXIymbuIYLZAzOpCYr-2PN4CZ11jFdO-mDlnZNgFO3JyOtK8HW8Jxvm")},
|
|
|
|
{"net", nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
|
c.SetStrict(true)
|
|
testtool, testtoolDestroy := newTesttool()
|
|
|
|
msg := message.New(log.New(os.Stderr, "container: ", 0))
|
|
msg.SwapVerbose(testing.Verbose())
|
|
|
|
wantChecksum := pkg.MustDecode(
|
|
"a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W",
|
|
)
|
|
cureMany(t, c, []cureStep{
|
|
{"container", pkg.NewExec(
|
|
t.Context(),
|
|
msg,
|
|
0,
|
|
&wantChecksum,
|
|
pkg.AbsWork,
|
|
[]string{"HAKUREI_TEST=1"},
|
|
check.MustAbs("/opt/bin/testtool"),
|
|
[]string{"testtool", "net"},
|
|
|
|
pkg.MustPath("/file", newStubFile(
|
|
pkg.KindHTTPGet,
|
|
pkg.ID{0xfe, 0},
|
|
nil,
|
|
nil, nil,
|
|
)),
|
|
pkg.MustPath("/.hakurei", stubArtifact{
|
|
kind: pkg.KindTar,
|
|
params: []byte("empty directory"),
|
|
cure: func(c *pkg.CureContext) error {
|
|
return os.MkdirAll(c.GetWorkDir().String(), 0700)
|
|
},
|
|
}),
|
|
pkg.MustPath("/opt", testtool),
|
|
), ignorePathname, wantChecksum, nil},
|
|
})
|
|
|
|
testtoolDestroy(t, base, c)
|
|
}, pkg.MustDecode("bBQVFIt0FnOulljgpLnGtuzHSFgwiCMjc4pmc4rHRqXKQ60Q5aBVYp5f6aH9VdZi")},
|
|
|
|
{"overlay root", nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
|
c.SetStrict(true)
|
|
testtool, testtoolDestroy := newTesttool()
|
|
|
|
msg := message.New(log.New(os.Stderr, "container: ", 0))
|
|
msg.SwapVerbose(testing.Verbose())
|
|
|
|
cureMany(t, c, []cureStep{
|
|
{"container", pkg.NewExec(
|
|
t.Context(),
|
|
msg,
|
|
0,
|
|
nil,
|
|
pkg.AbsWork,
|
|
[]string{"HAKUREI_TEST=1", "HAKUREI_ROOT=1"},
|
|
check.MustAbs("/opt/bin/testtool"),
|
|
[]string{"testtool"},
|
|
|
|
pkg.MustPath("/", stubArtifact{
|
|
kind: pkg.KindTar,
|
|
params: []byte("empty directory"),
|
|
cure: func(c *pkg.CureContext) error {
|
|
return os.MkdirAll(c.GetWorkDir().String(), 0700)
|
|
},
|
|
}),
|
|
pkg.MustPath("/opt", testtool),
|
|
), ignorePathname, wantChecksumOffline, nil},
|
|
})
|
|
|
|
testtoolDestroy(t, base, c)
|
|
}, pkg.MustDecode("gFT9kprYBqEJKifJIl2sHn_3TgULWVLTU4DrYAHiGcRmcdFRZ0YtjiROW820cAEc")},
|
|
|
|
{"overlay temp", nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
|
c.SetStrict(true)
|
|
testtool, testtoolDestroy := newTesttool()
|
|
|
|
msg := message.New(log.New(os.Stderr, "container: ", 0))
|
|
msg.SwapVerbose(testing.Verbose())
|
|
|
|
cureMany(t, c, []cureStep{
|
|
{"container", pkg.NewExec(
|
|
t.Context(),
|
|
msg,
|
|
0,
|
|
nil,
|
|
pkg.AbsWork,
|
|
[]string{"HAKUREI_TEST=1", "HAKUREI_ROOT=1"},
|
|
check.MustAbs("/tmp/bin/testtool"),
|
|
[]string{"testtool"},
|
|
|
|
pkg.MustPath("/", stubArtifact{
|
|
kind: pkg.KindTar,
|
|
params: []byte("empty directory"),
|
|
cure: func(c *pkg.CureContext) error {
|
|
return os.MkdirAll(c.GetWorkDir().String(), 0700)
|
|
},
|
|
}),
|
|
pkg.MustPath("/tmp/", stubArtifact{
|
|
kind: pkg.KindTar,
|
|
params: []byte("empty directory"),
|
|
cure: func(c *pkg.CureContext) error {
|
|
return os.MkdirAll(c.GetWorkDir().String(), 0700)
|
|
},
|
|
}),
|
|
pkg.ExecContainerPath{
|
|
P: fhs.AbsTmp,
|
|
A: testtool,
|
|
},
|
|
), ignorePathname, wantChecksumOffline, nil},
|
|
})
|
|
|
|
testtoolDestroy(t, base, c)
|
|
}, pkg.MustDecode("_r1IBeMWCkLwQ9Im9w0tV9_CWIOfQlXkkP2CogPHLmZp_AB6W3_8HVZqDV00dNAm")},
|
|
|
|
{"overlay work", nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
|
c.SetStrict(true)
|
|
testtool, testtoolDestroy := newTesttool()
|
|
|
|
msg := message.New(log.New(os.Stderr, "container: ", 0))
|
|
msg.SwapVerbose(testing.Verbose())
|
|
|
|
cureMany(t, c, []cureStep{
|
|
{"container", pkg.NewExec(
|
|
t.Context(),
|
|
msg,
|
|
0,
|
|
nil,
|
|
pkg.AbsWork,
|
|
[]string{"HAKUREI_TEST=1", "HAKUREI_ROOT=1"},
|
|
check.MustAbs("/work/bin/testtool"),
|
|
[]string{"testtool"},
|
|
|
|
pkg.MustPath("/", stubArtifact{
|
|
kind: pkg.KindTar,
|
|
params: []byte("empty directory"),
|
|
cure: func(c *pkg.CureContext) error {
|
|
return os.MkdirAll(c.GetWorkDir().String(), 0700)
|
|
},
|
|
}),
|
|
pkg.MustPath("/work/", stubArtifact{
|
|
kind: pkg.KindTar,
|
|
params: []byte("empty directory"),
|
|
cure: func(c *pkg.CureContext) error {
|
|
return os.MkdirAll(c.GetWorkDir().String(), 0700)
|
|
},
|
|
}),
|
|
pkg.ExecContainerPath{
|
|
P: pkg.AbsWork,
|
|
A: testtool,
|
|
},
|
|
), ignorePathname, wantChecksumOffline, nil},
|
|
})
|
|
|
|
testtoolDestroy(t, base, c)
|
|
}, pkg.MustDecode("-DrfvuB9gUAT-Tgw6V1KjFyosYGMGKJW7KMZFF1Ew8jZ9LJ82FtXf0wTgM3fO0oD")},
|
|
})
|
|
}
|
|
|
|
// newTesttool returns an [Artifact] that cures into testtoolBin. The returned
|
|
// function must be called at the end of the test but not deferred.
|
|
func newTesttool() (
|
|
testtool pkg.Artifact,
|
|
testtoolDestroy func(t *testing.T, base *check.Absolute, c *pkg.Cache),
|
|
) {
|
|
// testtoolBin is built during go:generate and is not deterministic
|
|
testtool = overrideIdent{pkg.ID{0xfe, 0xff}, stubArtifact{
|
|
kind: pkg.KindTar,
|
|
cure: func(c *pkg.CureContext) error {
|
|
work := c.GetWorkDir()
|
|
if err := os.MkdirAll(
|
|
work.Append("bin").String(),
|
|
0700,
|
|
); err != nil {
|
|
return err
|
|
}
|
|
return os.WriteFile(c.GetWorkDir().Append(
|
|
"bin",
|
|
"testtool",
|
|
).String(), testtoolBin, 0500)
|
|
},
|
|
}}
|
|
testtoolDestroy = func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
|
if pathname, checksum, err := c.Cure(testtool); err != nil {
|
|
t.Fatalf("Cure: error = %v", err)
|
|
} else if err = os.Remove(pathname.String()); err != nil {
|
|
t.Fatal(err)
|
|
} else {
|
|
p := base.Append(
|
|
"checksum",
|
|
pkg.Encode(checksum),
|
|
)
|
|
if err = os.Chmod(p.Append("bin").String(), 0700); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err = os.Chmod(p.String(), 0700); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err = os.RemoveAll(p.String()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|