//go:build testtool package main import ( "errors" "log" "net" "os" "path" "slices" "strings" "syscall" "hakurei.app/container/fhs" "hakurei.app/container/vfs" ) func main() { log.SetFlags(0) log.SetPrefix("testtool: ") var hostNet bool wantArgs := []string{"testtool"} if len(os.Args) == 2 { hostNet = true wantArgs = []string{"testtool", "net"} } if !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 wantEnv = []string{"HAKUREI_TEST=1", "HAKUREI_ROOT=1"} } if !slices.Equal(wantEnv, os.Environ()) { log.Fatalf("Environ: %q, want %q", os.Environ(), wantEnv) } var overlayTmp, overlayWork bool const ( wantExec = "/opt/bin/testtool" wantExecTmp = "/tmp/bin/testtool" wantExecWork = "/work/bin/testtool" ) if got, err := os.Executable(); err != nil { log.Fatalf("Executable: error = %v", err) } else if got != wantExec { switch got { case wantExecTmp: overlayTmp = true case wantExecWork: overlayWork = true 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 _, err := net.Dial("tcp", "127.0.0.1:0"); err == nil { log.Fatal("Dial unexpectedly succeeded") } else if hostNet { if !errors.Is(err, syscall.ECONNREFUSED) { log.Fatalf("Dial: error = %v", err) } } else { if !errors.Is(err, syscall.ENETUNREACH) { log.Fatalf("Dial: error = %v", err) } } const checksumEmptyDir = "MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU" ident := "oHuqV7p0v1Vd8IdAzjyYM8sfCS0P2LR5tfv5cb6Gbf2ZWUm8Ec-7hYPJ_qr183m7" log.Println(m) next := func() { m = m.Next; log.Println(m) } if overlayRoot { ident = "cIjP14zs5el6W_BQhufL_c0vWg-V6Z6pDpsbEa3sYtZ1381u1bKnH3N16RIrw-1S" 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 path.Base(lowerdir) != checksumEmptyDir { log.Fatal("unexpected artifact checksum") } } else { if hostNet { ident = "I3T53NtN6HPAyyodHtq2B0clcsoS1nPdvCEb-Zc5K-hoqFGL2od1mftHhwG7gX1S" } if m.Root != "/sysroot" || m.Target != "/" { log.Fatal("unexpected root mount entry") } next() if path.Base(m.Root) != "OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb" { log.Fatal("unexpected file artifact checksum") } next() if path.Base(m.Root) != checksumEmptyDir { log.Fatal("unexpected artifact checksum") } } if !overlayTmp { next() // testtool artifact } else { ident = "3ELJ8l42g6XeIoLGR9LheVhMIwSIleD6VrhsliBuon5DAdBOwFSMqd7aiUI4fll7" next() if path.Base(m.Root) != checksumEmptyDir || m.Target != "/tmp" { log.Fatal("unexpected artifact checksum") } } if overlayTmp { next() // testtool artifact if m.Root != "/" || m.Target != "/tmp" || m.Source != "overlay" || m.FsType != "overlay" { log.Fatal("unexpected temp mount entry") } } next() if overlayWork { ident = "VMCurZKCA_MV80zb-ZBWVytfl3rhYOKJeo2u9l-OuaytQ_w_r4EsqgJ2nfO93x5_" if m.Root != "/" || m.Target != "/work" || m.Source != "overlay" || m.FsType != "overlay" { log.Fatal("unexpected work mount entry") } } else { if path.Base(m.Root) != ident || m.Target != "/work" { log.Fatal("unexpected work mount entry") } } if !overlayTmp { next() if path.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) } }