test/sandbox: parse full test case
This makes declaring multiple tests much cleaner. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"slices"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -16,76 +17,103 @@ var (
|
||||
func printf(format string, v ...any) { printfFunc(format, v...) }
|
||||
func fatalf(format string, v ...any) { fatalfFunc(format, v...) }
|
||||
|
||||
func mustDecode(wantFile string, v any) {
|
||||
if f, err := os.Open(wantFile); err != nil {
|
||||
fatalf("cannot open %q: %v", wantFile, err)
|
||||
} else if err = json.NewDecoder(f).Decode(v); err != nil {
|
||||
fatalf("cannot decode %q: %v", wantFile, err)
|
||||
} else if err = f.Close(); err != nil {
|
||||
fatalf("cannot close %q: %v", wantFile, err)
|
||||
}
|
||||
type TestCase struct {
|
||||
FS *FS `json:"fs"`
|
||||
Mount []*Mntent `json:"mount"`
|
||||
Seccomp bool `json:"seccomp"`
|
||||
}
|
||||
|
||||
func MustAssertMounts(name, hostMountsFile, wantFile string) {
|
||||
hostMounts := make([]*Mntent, 0, 128)
|
||||
if err := IterMounts(hostMountsFile, func(e *Mntent) {
|
||||
hostMounts = append(hostMounts, e)
|
||||
}); err != nil {
|
||||
fatalf("cannot parse host mounts: %v", err)
|
||||
type T struct {
|
||||
FS fs.FS
|
||||
|
||||
MountsPath, PMountsPath string
|
||||
}
|
||||
|
||||
func (t *T) MustCheckFile(wantFilePath string) {
|
||||
var want *TestCase
|
||||
mustDecode(wantFilePath, &want)
|
||||
t.MustCheck(want)
|
||||
}
|
||||
|
||||
func (t *T) MustCheck(want *TestCase) {
|
||||
if want.FS != nil && t.FS != nil {
|
||||
if err := want.FS.Compare(".", t.FS); err != nil {
|
||||
fatalf("%v", err)
|
||||
}
|
||||
} else {
|
||||
printf("[SKIP] skipping fs check")
|
||||
}
|
||||
|
||||
var want []Mntent
|
||||
mustDecode(wantFile, &want)
|
||||
if want.Mount != nil && t.PMountsPath != "" {
|
||||
pm := mustOpenMounts(t.PMountsPath)
|
||||
passthruMounts := slices.AppendSeq(make([]*Mntent, 0, 128), pm.Entries())
|
||||
if err := pm.Err(); err != nil {
|
||||
fatalf("cannot parse host mounts: %v", err)
|
||||
}
|
||||
|
||||
for i := range want {
|
||||
if want[i].Opts == "host_passthrough" {
|
||||
for _, ent := range hostMounts {
|
||||
if want[i].FSName == ent.FSName && want[i].Type == ent.Type {
|
||||
// special case for tmpfs bind mounts
|
||||
if want[i].FSName == "tmpfs" && want[i].Dir != ent.Dir {
|
||||
continue
|
||||
for _, e := range want.Mount {
|
||||
if e.Opts == "host_passthrough" {
|
||||
for _, ent := range passthruMounts {
|
||||
if e.FSName == ent.FSName && e.Type == ent.Type {
|
||||
// special case for tmpfs bind mounts
|
||||
if e.FSName == "tmpfs" && e.Dir != ent.Dir {
|
||||
continue
|
||||
}
|
||||
|
||||
e.Opts = ent.Opts
|
||||
goto out
|
||||
}
|
||||
|
||||
want[i].Opts = ent.Opts
|
||||
goto out
|
||||
}
|
||||
fatalf("host passthrough missing %q", e.FSName)
|
||||
out:
|
||||
}
|
||||
fatalf("host passthrough missing %q", want[i].FSName)
|
||||
out:
|
||||
}
|
||||
|
||||
f := mustOpenMounts(t.MountsPath)
|
||||
i := 0
|
||||
for e := range f.Entries() {
|
||||
if i == len(want.Mount) {
|
||||
fatalf("got more than %d entries", i)
|
||||
}
|
||||
if !e.Is(want.Mount[i]) {
|
||||
fatalf("entry %d\n got: %s\nwant: %s", i,
|
||||
e, want.Mount[i])
|
||||
}
|
||||
printf("[ OK ] %s", e)
|
||||
|
||||
i++
|
||||
}
|
||||
if err := f.Err(); err != nil {
|
||||
fatalf("cannot parse mounts: %v", err)
|
||||
}
|
||||
} else {
|
||||
printf("[SKIP] skipping mounts check")
|
||||
}
|
||||
|
||||
i := 0
|
||||
if err := IterMounts(name, func(e *Mntent) {
|
||||
if i == len(want) {
|
||||
fatalf("got more than %d entries", i)
|
||||
if want.Seccomp {
|
||||
if TrySyscalls() != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
if !e.Is(&want[i]) {
|
||||
fatalf("entry %d\n got: %s\nwant: %s", i,
|
||||
e, &want[i])
|
||||
}
|
||||
|
||||
printf("%s", e)
|
||||
i++
|
||||
}); err != nil {
|
||||
fatalf("cannot iterate mounts: %v", err)
|
||||
} else {
|
||||
printf("[SKIP] skipping seccomp check")
|
||||
}
|
||||
}
|
||||
|
||||
func MustAssertFS(e fs.FS, wantFile string) {
|
||||
var want *FS
|
||||
mustDecode(wantFile, &want)
|
||||
if want == nil {
|
||||
fatalf("invalid payload")
|
||||
}
|
||||
|
||||
if err := want.Compare(".", e); err != nil {
|
||||
fatalf("%v", err)
|
||||
func mustDecode(wantFilePath string, v any) {
|
||||
if f, err := os.Open(wantFilePath); err != nil {
|
||||
fatalf("cannot open %q: %v", wantFilePath, err)
|
||||
} else if err = json.NewDecoder(f).Decode(v); err != nil {
|
||||
fatalf("cannot decode %q: %v", wantFilePath, err)
|
||||
} else if err = f.Close(); err != nil {
|
||||
fatalf("cannot close %q: %v", wantFilePath, err)
|
||||
}
|
||||
}
|
||||
|
||||
func MustAssertSeccomp() {
|
||||
if TrySyscalls() != nil {
|
||||
os.Exit(1)
|
||||
func mustOpenMounts(name string) *MountsFile {
|
||||
if f, err := OpenMounts(name); err != nil {
|
||||
fatalf("cannot open mounts %q: %v", name, err)
|
||||
panic("unreachable")
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user