cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

main
012 / internal / ui / speedlock_unix_test.go
speedlock_unix_test.go 1.9K
1//go:build unix23package ui45import (6 "errors"7 "io/fs"8 "os"9 "syscall"10 "testing"11 "time"12)1314// benchLockPath is the lock timed runs on this machine share, so their15// timings don't overlap. Two conventions meet there: a file locked with16// flock(2), as `flock /tmp/012-bench.lock <command>` takes it where the17// flock command exists, and a directory made with mkdir and removed18// after, which needs no flock (macOS has none). The speed gate takes19// whichever the path holds, a directory when it holds nothing.20const benchLockPath = "/tmp/012-bench.lock"2122// benchLockWait is how long the gate waits for a directory lock before23// timing without it (the lock may be stale, left by a run that was24// killed).25const benchLockWait = 10 * time.Minute2627// benchLock waits for the lock and returns its release.28func benchLock(t *testing.T) func() {29 t.Helper()30 deadline := time.Now().Add(benchLockWait)31 logged := false32 for {33 err := os.Mkdir(benchLockPath, 0o755)34 if err == nil {35 return func() { os.Remove(benchLockPath) }36 }37 info, serr := os.Stat(benchLockPath)38 switch {39 case !errors.Is(err, fs.ErrExist) || serr != nil:40 t.Logf("timing without the lock: %v", err)41 return func() {}42 case info.Mode().IsRegular():43 return flockFile(t)44 case time.Now().After(deadline):45 t.Logf("timing without the lock: %s held for %v", benchLockPath, benchLockWait)46 return func() {}47 }48 if !logged {49 t.Logf("waiting for %s", benchLockPath)50 logged = true51 }52 time.Sleep(200 * time.Millisecond)53 }54}5556// flockFile takes the lock as a file, with flock(2).57func flockFile(t *testing.T) func() {58 f, err := os.OpenFile(benchLockPath, os.O_RDWR, 0)59 if err != nil {60 t.Logf("timing without the lock: %v", err)61 return func() {}62 }63 if err := syscall.Flock(int(f.Fd()), syscall.LOCK_EX); err != nil {64 f.Close()65 t.Fatalf("locking %s: %v", benchLockPath, err)66 }67 return func() {68 syscall.Flock(int(f.Fd()), syscall.LOCK_UN)69 f.Close()70 }71}