Re-lock the mailbox window on lost phase instead of anchoring blind: one loop goroutine per module owns all transport, windows edge-locked from first touch, bringup verifies both modules before either AN restart; corrected charges and link-down reads print raw registers; harness -fuzz repeats lifecycles judging by exit status (30/30 module-clean)

This commit is contained in:
flamingcow
2026-08-13 16:32:14 -07:00
parent fef6b52b74
commit 9301348850
5 changed files with 280 additions and 166 deletions
+44 -3
View File
@@ -5,9 +5,11 @@
package main
import (
"bytes"
"flag"
"fmt"
"image/png"
"io"
"os"
"os/exec"
"path/filepath"
@@ -20,19 +22,58 @@ import (
const (
shotsDir = "shots"
grace = 3 * time.Second
// The framebuffer's DRM master can outlive the process group by a moment;
// an immediate next run finds the device busy.
fuzzGap = 2 * time.Second
)
func main() {
runFor := flag.Duration("for", 15*time.Second, "how long to let cabletest run")
at := flag.String("at", "", "offsets to capture the panel at, comma separated, e.g. 3s,10s")
fuzzN := flag.Int("fuzz", 0, "repeat the whole lifecycle this many times; full output only for runs that fail or log module events")
flag.Parse()
if err := run(*runFor, *at, flag.Args()); err != nil {
var err error
if *fuzzN > 0 {
err = fuzz(*fuzzN, *runFor, flag.Args())
} else {
err = run(*runFor, *at, os.Stdout, flag.Args())
}
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func fuzz(n int, runFor time.Duration, args []string) error {
failed := 0
for i := 1; i <= n; i++ {
if i > 1 {
time.Sleep(fuzzGap)
}
var buf bytes.Buffer
start := time.Now()
err := run(runFor, "", &buf, args)
dur := time.Since(start).Round(100 * time.Millisecond)
if err != nil {
failed++
name := fmt.Sprintf("fuzz-run%02d.log", i)
if werr := os.WriteFile(name, buf.Bytes(), 0o644); werr != nil {
name = fmt.Sprintf("unsaved: %v", werr)
}
fmt.Printf("run %02d/%02d: FAILED (%s): %v [%s]\n", i, n, dur, err, name)
os.Stdout.Write(buf.Bytes())
continue
}
fmt.Printf("run %02d/%02d: ok (%s)\n", i, n, dur)
}
fmt.Printf("fuzz: %d/%d ok, %d failed\n", n-failed, n, failed)
if failed > 0 {
return fmt.Errorf("%d/%d runs failed", failed, n)
}
return nil
}
func parseShots(s string, runFor time.Duration) ([]time.Duration, error) {
if s == "" {
return nil, nil
@@ -52,7 +93,7 @@ func parseShots(s string, runFor time.Duration) ([]time.Duration, error) {
return out, nil
}
func run(runFor time.Duration, at string, args []string) error {
func run(runFor time.Duration, at string, out io.Writer, args []string) error {
if os.Geteuid() != 0 {
return fmt.Errorf("needs root for the raw sockets and the framebuffer: sudo go run ./harness")
}
@@ -67,7 +108,7 @@ func run(runFor time.Duration, at string, args []string) error {
}
cmd := exec.Command("go", append([]string{"run", "."}, args...)...)
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
cmd.Stdout, cmd.Stderr = out, out
// Its own process group: go run's compiled child is reparented rather than
// killed when go run dies, and an orphan holding the wire poisons every
// measurement after it.