aboutsummaryrefslogtreecommitdiffhomepage
path: root/pkg/internal
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/internal')
-rw-r--r--pkg/internal/testtool/expected/expected.go9
-rw-r--r--pkg/internal/testtool/expected/sum_amd64.go11
-rw-r--r--pkg/internal/testtool/expected/sum_arm64.go11
-rw-r--r--pkg/internal/testtool/expected/sum_riscv64.go11
-rw-r--r--pkg/internal/testtool/main.go277
5 files changed, 319 insertions, 0 deletions
diff --git a/pkg/internal/testtool/expected/expected.go b/pkg/internal/testtool/expected/expected.go
new file mode 100644
index 00000000..c0e8e4a2
--- /dev/null
+++ b/pkg/internal/testtool/expected/expected.go
@@ -0,0 +1,9 @@
+// Package expected contains data shared between test helper and test harness.
+package expected
+
+const (
+ // Magic are magic bytes in the binfmt test case.
+ Magic = "\xca\xfe\xba\xbe\xfd\xfd"
+ // Full is the full content of the binfmt test case executable.
+ Full = Magic + ":3"
+)
diff --git a/pkg/internal/testtool/expected/sum_amd64.go b/pkg/internal/testtool/expected/sum_amd64.go
new file mode 100644
index 00000000..354931be
--- /dev/null
+++ b/pkg/internal/testtool/expected/sum_amd64.go
@@ -0,0 +1,11 @@
+package expected
+
+const (
+ Offline = "IKmVhALejtYA3JhN1PCfjKF-Dio1XVcOeMWDHhfSHCbb4iBNhGjFy2UspZveZvb8"
+ OfflineS = "6ZubjSyCnz4-TKgQZi_BbY-JUwsStYCtD_f-BTDOOotfEbqkm47W20AazHRaLviz"
+ OvlRoot = "Yox7WpG8B_OqIXWF4HWFZkUfsEl7DGzpFyZM0qtd9T8nQ-7SAkEUurlAe6_DJ6Iu"
+ Layers = "aAwfxDB-efVo379FNl178jK7HEKU3LEjHbZdaVVjk7GnXGZGEANNsXnB3SCUxM9A"
+ Net = "IU3GwU2jTBd7HjotvFo2wsDWBQGVGpamwiSKdc2G1EnhM-ZaacxAuK6q0wbTVxra"
+ Promote = "rOjetGHzT_jPErrBR24IAZKDj8Q9dLLqxFQqloMgjsULss0VXDI--n6LxuMBHvmZ"
+ Work = "7f9XDeREfvJIjCe0qesND0s0tasExAIcc-OH33-eq9tsrQPUXhJp4KEkpsYH4hCD"
+)
diff --git a/pkg/internal/testtool/expected/sum_arm64.go b/pkg/internal/testtool/expected/sum_arm64.go
new file mode 100644
index 00000000..2e6f7cbf
--- /dev/null
+++ b/pkg/internal/testtool/expected/sum_arm64.go
@@ -0,0 +1,11 @@
+package expected
+
+const (
+ Offline = "MTgCSzwPrzGigp9phvDPRwUTNGLm1KM2EsEtbz-l2cNieqjaGtnzm65CDXlSxXrl"
+ OfflineS = "p89bQg7_jR4nwaSbpEd08ne1jHOEw7Wlnlyv5FHq7ba1Kml3HSBZwEKRzu0gCqEb"
+ OvlRoot = "9ifwO6MAaV9kTqRR2O5PJzm8XhfXbr50mFLWyEHQm8OHHcJtAEUgXZzJYoZt9YVV"
+ Layers = "INuGActFPwJtS7mAR9Bkt7FD4yoHlXHSJ9CaSAQJrpkUBL_k815Cs_jvRfxy5-a7"
+ Net = "kJvy24uk4ePvHoxSKf4vMOhR4NxLbmyWlA9bTS7d3z3fE9WF1Tvpao9g-QuYU4vm"
+ Promote = "lYqyYrfjPawIbld5Qz0NbKvd_bmI3nJC1eEnlIQWzsjWE9uA1HuKPAaClnDeyG6L"
+ Work = "V6k4FqOBMRCmHiqchs5-joVGZ_MhNWZyXm3gdbU0S7S5eMze7G4SwYMTf66ojKQL"
+)
diff --git a/pkg/internal/testtool/expected/sum_riscv64.go b/pkg/internal/testtool/expected/sum_riscv64.go
new file mode 100644
index 00000000..53872c08
--- /dev/null
+++ b/pkg/internal/testtool/expected/sum_riscv64.go
@@ -0,0 +1,11 @@
+package expected
+
+const (
+ Offline = "LlieSHVDe1lnKvfI8t4oGRg_2hPxwyy1drmaqc-EKCOENuS9C2YHrp2VY5pSyhbg"
+ OfflineS = "qccjM8oYjUuEYPKFFzAxDFVzMerSUKUZc18NdVQoiPWf-70XOsNK8NaUQqjTgTAD"
+ OvlRoot = "lpV2bb_KGYFHPiOn-jtGop8K_ew0y1p3BezRp0ebM93_a-T9J-vkqGD5uokda1aN"
+ Layers = "sM3DJm210CHPGHkAquIbrXhspB81FpVC60ApQrvJGD5El2i7cSONj7LWf7EWqKpT"
+ Net = "JihQUwsVETRYjb2-yIXLYZ6WVsaFebwl8btSYAsNQ2QapS5MZVaI-dYwrVoySycR"
+ Promote = "lGqwR4W2OjylSVitMQP1lc6wApOBkbMjsmIqkxQbfEZ3DHEQBbJr84ErW6Xb54zo"
+ Work = "aZgtyv6aMtoHFkHAaJr6nLaA7N_SHjShgWPyQ5UdzaIqYSiVqvCrZqSokGTCcTii"
+)
diff --git a/pkg/internal/testtool/main.go b/pkg/internal/testtool/main.go
new file mode 100644
index 00000000..edffab7e
--- /dev/null
+++ b/pkg/internal/testtool/main.go
@@ -0,0 +1,277 @@
+//go:build testtool
+
+package main
+
+import (
+ "encoding/gob"
+ "log"
+ "net"
+ "os"
+ "path/filepath"
+ "reflect"
+ "runtime"
+ "slices"
+ "strconv"
+ "strings"
+
+ "hakurei.app/fhs"
+ "hakurei.app/vfs"
+
+ "hakurei.app/pkg/internal/testtool/expected"
+)
+
+func main() {
+ log.SetFlags(0)
+ log.SetPrefix("testtool: ")
+
+ if os.Getenv("HAKUREI_BINFMT") == "1" {
+ wantArgs := []string{"/interpreter", "/opt/bin/sample"}
+ if !slices.Equal(os.Args, wantArgs) {
+ log.Fatalf("Args: %q, want %q", os.Args, wantArgs)
+ }
+
+ if err := os.WriteFile("check", []byte("binfmt"), 0400); err != nil {
+ log.Fatal(err)
+ }
+
+ return
+ }
+
+ environ := slices.DeleteFunc(slices.Clone(os.Environ()), func(s string) bool {
+ for _, t := range []string{
+ "CURE_JOBS=" + strconv.Itoa(runtime.NumCPU()),
+ "CURE_LOAD=" + strconv.Itoa(runtime.NumCPU()+2),
+ } {
+ if s == t {
+ return true
+ }
+ }
+ return false
+ })
+
+ var hostNet, layers, promote bool
+ if len(os.Args) == 2 && os.Args[0] == "testtool" {
+ switch os.Args[1] {
+ case "net":
+ hostNet = true
+ log.SetPrefix("testtool(net): ")
+ break
+
+ case "layers":
+ layers = true
+ log.SetPrefix("testtool(layers): ")
+ break
+
+ case "promote":
+ promote = true
+ log.SetPrefix("testtool(promote): ")
+
+ default:
+ log.Fatalf("Args: %q", os.Args)
+ return
+ }
+ } else if wantArgs := []string{"testtool"}; !slices.Equal(os.Args, wantArgs) {
+ log.Fatalf("Args: %q, want %q", os.Args, wantArgs)
+ }
+
+ var overlayRoot bool
+ wantEnv := []string{"HAKUREI_TEST=1"}
+ if len(environ) == 2 {
+ overlayRoot = true
+ if !layers && !promote {
+ log.SetPrefix("testtool(overlay root): ")
+ }
+ wantEnv = []string{"HAKUREI_TEST=1", "HAKUREI_ROOT=1"}
+ }
+ if !slices.Equal(wantEnv, environ) {
+ log.Fatalf("Environ: %q, want %q", environ, wantEnv)
+ }
+
+ var overlayWork bool
+ const (
+ wantExec = "/opt/bin/testtool"
+ wantExecWork = "/work/bin/testtool"
+ )
+ var iftPath string
+ if got, err := os.Executable(); err != nil {
+ log.Fatalf("Executable: error = %v", err)
+ } else {
+ iftPath = filepath.Join(filepath.Dir(filepath.Dir(got)), "ift")
+
+ if got != wantExec {
+ switch got {
+ case wantExecWork:
+ overlayWork = true
+ log.SetPrefix("testtool(overlay work): ")
+
+ default:
+ log.Fatalf("Executable: %q, want %q", got, wantExec)
+ }
+ }
+ }
+
+ wantHostname := "cure"
+ if hostNet {
+ wantHostname += "-net"
+ }
+
+ if hostname, err := os.Hostname(); err != nil {
+ log.Fatalf("Hostname: error = %v", err)
+ } else if hostname != wantHostname {
+ log.Fatalf("Hostname: %q, want %q", hostname, wantHostname)
+ }
+
+ var m *vfs.MountInfo
+ if f, err := os.Open(fhs.Proc + "self/mountinfo"); err != nil {
+ log.Fatalf("Open: error = %v", err)
+ } else {
+ err = vfs.NewMountInfoDecoder(f).Decode(&m)
+ closeErr := f.Close()
+ if err != nil {
+ log.Fatalf("Decode: error = %v", err)
+ }
+ if closeErr != nil {
+ log.Fatalf("Close: error = %v", err)
+ }
+ }
+
+ if ift, err := net.Interfaces(); err != nil {
+ log.Fatal(err)
+ } else if !hostNet {
+ if len(ift) != 1 || ift[0].Name != "lo" {
+ log.Fatalln("got interfaces", strings.Join(slices.Collect(func(yield func(ifn string) bool) {
+ for _, ifi := range ift {
+ if !yield(ifi.Name) {
+ break
+ }
+ }
+ }), ", "))
+ }
+ } else {
+ var iftParent []net.Interface
+
+ var r *os.File
+ if r, err = os.Open(iftPath); err != nil {
+ log.Fatal(err)
+ } else {
+ err = gob.NewDecoder(r).Decode(&iftParent)
+ closeErr := r.Close()
+ if err != nil {
+ log.Fatal(err)
+ }
+ if closeErr != nil {
+ log.Fatal(closeErr)
+ }
+ }
+
+ if !reflect.DeepEqual(ift, iftParent) {
+ log.Fatalf("Interfaces: %#v, want %#v", ift, iftParent)
+ }
+ }
+
+ const checksumEmptyDir = "MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU"
+ ident := expected.Offline
+ log.Println(m)
+ next := func() { m = m.Next; log.Println(m) }
+
+ if overlayRoot {
+ ident = expected.OvlRoot
+
+ if m.Root != "/" || m.Target != "/" ||
+ m.Source != "overlay" || m.FsType != "overlay" {
+ log.Fatal("unexpected root mount entry")
+ }
+ var lowerdir []string
+ for _, o := range strings.Split(m.FsOptstr, ",") {
+ const lowerdirKey = "lowerdir+="
+ if strings.HasPrefix(o, lowerdirKey) {
+ lowerdir = append(lowerdir, o[len(lowerdirKey):])
+ }
+ }
+ if !layers {
+ if len(lowerdir) != 1 || filepath.Base(lowerdir[0]) != checksumEmptyDir {
+ log.Fatal("unexpected artifact checksum")
+ }
+ } else {
+ ident = expected.Layers
+
+ if len(lowerdir) != 2 ||
+ filepath.Base(lowerdir[0]) != "MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU" ||
+ filepath.Base(lowerdir[1]) != "nY_CUdiaUM1OL4cPr5TS92FCJ3rCRV7Hm5oVTzAvMXwC03_QnTRfQ5PPs7mOU9fK" {
+ log.Fatalf("unexpected lowerdirs %s", strings.Join(lowerdir, ", "))
+ }
+ }
+ } else {
+ if hostNet {
+ ident = expected.Net
+ }
+
+ if m.Root != "/sysroot" || m.Target != "/" {
+ log.Fatal("unexpected root mount entry")
+ }
+
+ next()
+ if filepath.Base(m.Root) != "OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb" {
+ log.Fatal("unexpected file artifact checksum")
+ }
+
+ next()
+ if filepath.Base(m.Root) != checksumEmptyDir {
+ log.Fatal("unexpected artifact checksum")
+ }
+ }
+
+ if promote {
+ ident = expected.Promote
+ }
+
+ next() // testtool artifact
+
+ next()
+ if overlayWork {
+ ident = expected.Work
+ if m.Root != "/" || m.Target != "/work" ||
+ m.Source != "overlay" || m.FsType != "overlay" {
+ log.Fatal("unexpected work mount entry")
+ }
+ } else {
+ if filepath.Base(m.Root) != ident || m.Target != "/work" {
+ log.Fatal("unexpected work mount entry")
+ }
+ }
+
+ next()
+ if filepath.Base(m.Root) != ident || m.Target != "/tmp" {
+ log.Fatal("unexpected temp mount entry")
+ }
+
+ next()
+ if m.Root != "/" || m.Target != "/proc" || m.Source != "proc" || m.FsType != "proc" {
+ log.Fatal("unexpected proc mount entry")
+ }
+
+ next()
+ if m.Root != "/" || m.Target != "/dev" || m.Source != "devtmpfs" || m.FsType != "tmpfs" {
+ log.Fatal("unexpected dev mount entry")
+ }
+
+ for i := 0; i < 9; i++ { // private /dev entries
+ next()
+ }
+
+ if m.Next != nil {
+ log.Println("unexpected extra mount entries")
+ for m.Next != nil {
+ next()
+ }
+ os.Exit(1)
+ }
+
+ checkData := []byte{0}
+ if hostNet {
+ checkData = []byte("net")
+ }
+ if err := os.WriteFile("check", checkData, 0400); err != nil {
+ log.Fatal(err)
+ }
+}