internal/pkg: implement exec artifact
All checks were successful
Test / Create distribution (push) Successful in 52s
Test / Sandbox (push) Successful in 2m35s
Test / Hakurei (push) Successful in 3m41s
Test / ShareFS (push) Successful in 3m46s
Test / Hpkg (push) Successful in 4m30s
Test / Sandbox (race detector) (push) Successful in 4m57s
Test / Hakurei (race detector) (push) Successful in 5m57s
Test / Flake checks (push) Successful in 1m43s
All checks were successful
Test / Create distribution (push) Successful in 52s
Test / Sandbox (push) Successful in 2m35s
Test / Hakurei (push) Successful in 3m41s
Test / ShareFS (push) Successful in 3m46s
Test / Hpkg (push) Successful in 4m30s
Test / Sandbox (race detector) (push) Successful in 4m57s
Test / Hakurei (race detector) (push) Successful in 5m57s
Test / Flake checks (push) Successful in 1m43s
This runs a program in a container environment. Artifacts can be made available to the container, they are cured concurrently and mounted in order. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
138
internal/pkg/exec_test.go
Normal file
138
internal/pkg/exec_test.go
Normal file
@@ -0,0 +1,138 @@
|
||||
package pkg_test
|
||||
|
||||
//go:generate go build -tags testtool -ldflags "-extldflags='-static'" -o testdata/testtool ./testdata
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"errors"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"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()
|
||||
|
||||
checkWithCache(t, []cacheTestCase{
|
||||
{"container", nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||
c.SetStrict(true)
|
||||
|
||||
// this 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)
|
||||
},
|
||||
}}
|
||||
|
||||
msg := message.New(log.New(os.Stderr, "container: ", 0))
|
||||
msg.SwapVerbose(testing.Verbose())
|
||||
|
||||
cureMany(t, c, []cureStep{
|
||||
{"container", pkg.NewExec(
|
||||
t.Context(),
|
||||
msg,
|
||||
0,
|
||||
check.MustAbs("/work"),
|
||||
[]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, pkg.MustDecode(
|
||||
"GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9",
|
||||
), nil},
|
||||
|
||||
{"error passthrough", pkg.NewExec(
|
||||
t.Context(),
|
||||
msg,
|
||||
0,
|
||||
check.MustAbs("/work"),
|
||||
[]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))},
|
||||
})
|
||||
|
||||
// check init failure passthrough
|
||||
var exitError *exec.ExitError
|
||||
if _, _, err := c.Cure(pkg.NewExec(
|
||||
t.Context(),
|
||||
msg,
|
||||
0,
|
||||
check.MustAbs("/work"),
|
||||
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)
|
||||
}
|
||||
|
||||
// the testtool is not deterministic
|
||||
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)
|
||||
}
|
||||
}
|
||||
}, pkg.MustDecode("7PoPpWLjFPXIymbuIYLZAzOpCYr-2PN4CZ11jFdO-mDlnZNgFO3JyOtK8HW8Jxvm")},
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user