All checks were successful
Test / Create distribution (push) Successful in 1m17s
Test / Sandbox (push) Successful in 3m5s
Test / Hakurei (push) Successful in 4m12s
Test / ShareFS (push) Successful in 4m25s
Test / Sandbox (race detector) (push) Successful in 5m39s
Test / Hakurei (race detector) (push) Successful in 6m44s
Test / Flake checks (push) Successful in 1m24s
This makes package check portable, and removes nonportable behaviour from package pkg, pipewire, and system. All other packages remain nonportable due to their nature. No latency increase was observed due to this change on amd64 and arm64 linux. Signed-off-by: Ophestra <cat@gensokyo.uk>
269 lines
6.4 KiB
Go
269 lines
6.4 KiB
Go
//go:build testtool
|
|
|
|
package main
|
|
|
|
import (
|
|
"encoding/gob"
|
|
"log"
|
|
"net"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"slices"
|
|
"strings"
|
|
|
|
"hakurei.app/check"
|
|
"hakurei.app/fhs"
|
|
"hakurei.app/vfs"
|
|
)
|
|
|
|
func main() {
|
|
log.SetFlags(0)
|
|
log.SetPrefix("testtool: ")
|
|
|
|
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(os.Environ()) == 2 {
|
|
overlayRoot = true
|
|
if !layers && !promote {
|
|
log.SetPrefix("testtool(overlay root): ")
|
|
}
|
|
wantEnv = []string{"HAKUREI_TEST=1", "HAKUREI_ROOT=1"}
|
|
}
|
|
if !slices.Equal(wantEnv, os.Environ()) {
|
|
log.Fatalf("Environ: %q, want %q", os.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 := "dztPS6jRjiZtCF4_p8AzfnxGp6obkhrgFVsxdodbKWUoAEVtDz3MykepJB4kI_ks"
|
|
log.Println(m)
|
|
next := func() { m = m.Next; log.Println(m) }
|
|
|
|
if overlayRoot {
|
|
ident = "RdMA-mubnrHuu3Ky1wWyxauSYCO0ZH_zCPUj3uDHqkfwv5sGcByoF_g5PjlGiClb"
|
|
|
|
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 = o[len(lowerdirKey):]
|
|
}
|
|
}
|
|
if !layers {
|
|
if filepath.Base(lowerdir) != checksumEmptyDir {
|
|
log.Fatal("unexpected artifact checksum")
|
|
}
|
|
} else {
|
|
ident = "p1t_drXr34i-jZNuxDMLaMOdL6tZvQqhavNafGynGqxOZoXAUTSn7kqNh3Ovv3DT"
|
|
|
|
lowerdirsEscaped := strings.Split(lowerdir, ":")
|
|
lowerdirs := lowerdirsEscaped[:0]
|
|
// ignore the option separator since it does not appear in ident
|
|
for i, e := range lowerdirsEscaped {
|
|
if len(e) > 0 &&
|
|
e[len(e)-1] == check.SpecialOverlayEscape[0] &&
|
|
(len(e) == 1 || e[len(e)-2] != check.SpecialOverlayEscape[0]) {
|
|
// ignore escaped pathname separator since it does not
|
|
// appear in ident
|
|
|
|
e = e[:len(e)-1]
|
|
if len(lowerdirsEscaped) != i {
|
|
lowerdirsEscaped[i+1] = e + lowerdirsEscaped[i+1]
|
|
continue
|
|
}
|
|
}
|
|
lowerdirs = append(lowerdirs, e)
|
|
}
|
|
|
|
if len(lowerdirs) != 2 ||
|
|
filepath.Base(lowerdirs[0]) != "MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU" ||
|
|
filepath.Base(lowerdirs[1]) != "nY_CUdiaUM1OL4cPr5TS92FCJ3rCRV7Hm5oVTzAvMXwC03_QnTRfQ5PPs7mOU9fK" {
|
|
log.Fatalf("unexpected lowerdirs %s", strings.Join(lowerdirs, ", "))
|
|
}
|
|
}
|
|
} else {
|
|
if hostNet {
|
|
ident = "G8qPxD9puvvoOVV7lrT80eyDeIl3G_CCFoKw12c8mCjMdG1zF7NEPkwYpNubClK3"
|
|
}
|
|
|
|
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 = "xXTIYcXmgJWNLC91c417RRrNM9cjELwEZHpGvf8Fk_GNP5agRJp_SicD0w9aMeLJ"
|
|
}
|
|
|
|
next() // testtool artifact
|
|
|
|
next()
|
|
if overlayWork {
|
|
ident = "5hlaukCirnXE4W_RSLJFOZN47Z5RiHnacXzdFp_70cLgiJUGR6cSb_HaFftkzi0-"
|
|
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)
|
|
}
|
|
}
|