* .forgejo/workflows/planctl.yml: build/test matrix across
{ubuntu-latest, macos-latest, windows-latest} × {1.22, stable}
per D-3 / PRD R7.4. Dedicated bench job on ubuntu+stable so
ns/op numbers stay comparable across runs. Path filters scope
CI to planctl-adjacent changes only.
* cmd/planctl/bench_test.go: Benchmark_Lint_BigPlan times the full
lint pipeline on testdata/perf/big-plan/. Local M4 Pro: ~720µs,
two orders of magnitude under M3's 100ms target.
* TestLint_BigPlan_SoftCeiling logs (via direct os.Stderr write —
not t.Logf, which is suppressed without -v) when wall time
exceeds 100ms. Soft check per task 8.3 — CI runner variance
means a hard assert would be flaky; the visible stderr line is
the regression signal.
* Windows line-ending handling already landed in parent-7's
harness (CRLF → LF normalisation on both sides of golden
compare), so 8.4 is satisfied by construction.
Parent task 8.0 from dev/plans/26172-planctl/tasks.md.
Codex code-review session: 019db2f3-2f80-7fc0-b7bb-9e1f677f978e (2 rounds).
63 lines
2.1 KiB
Go
63 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// spec:planctl/D§7.3
|
|
// Benchmark_Lint_BigPlan measures full-pipeline wall time on the
|
|
// testdata/perf/big-plan fixture (~90 KB across 5 files; 36 R-ids, 18
|
|
// D§ sections, 72 covered task lines). PRD success metric M3 targets
|
|
// <100 ms on a 2023-era M-series machine; this benchmark reports
|
|
// ns/op and the CI runner interprets it — see §7.3 for context.
|
|
func Benchmark_Lint_BigPlan(b *testing.B) {
|
|
fixture, err := filepath.Abs("testdata/perf/big-plan")
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
args := []string{"lint", fixture}
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
var stdout, stderr bytes.Buffer
|
|
exit := run(args, &stdout, &stderr)
|
|
if exit != 0 {
|
|
b.StopTimer()
|
|
b.Fatalf("unexpected exit %d on big-plan fixture: stderr=%q", exit, stderr.String())
|
|
}
|
|
}
|
|
}
|
|
|
|
// spec:planctl/D§7.3
|
|
// TestLint_BigPlan_SoftCeiling times one lint of the perf fixture and
|
|
// LOGS (not fails) when the wall time exceeds PRD M3's 100ms ceiling.
|
|
// CI runners vary substantially; a hard assertion here would produce
|
|
// flaky failures, so task 8.3 explicitly specifies log-only behavior.
|
|
// A pathological regression (e.g. O(n²) scan) still surfaces in the
|
|
// test log even if not reflected in the exit code.
|
|
func TestLint_BigPlan_SoftCeiling(t *testing.T) {
|
|
fixture, err := filepath.Abs("testdata/perf/big-plan")
|
|
if err != nil {
|
|
t.Fatalf("abs: %v", err)
|
|
}
|
|
args := []string{"lint", fixture}
|
|
var stdout, stderr bytes.Buffer
|
|
start := time.Now()
|
|
exit := run(args, &stdout, &stderr)
|
|
elapsed := time.Since(start)
|
|
if exit != 0 {
|
|
t.Fatalf("exit=%d, want 0: stderr=%q", exit, stderr.String())
|
|
}
|
|
const ceiling = 100 * time.Millisecond
|
|
if elapsed > ceiling {
|
|
// Write directly to stderr rather than t.Logf so the warning is
|
|
// visible in non-verbose CI runs (Go test suppresses t.Log output
|
|
// from passing tests without -v). Keeps the test passing so CI
|
|
// stays green; the visible warning is the signal.
|
|
fmt.Fprintf(os.Stderr, "planctl: WARNING big-plan lint took %v, PRD M3 target is <%v (CI runner variance is expected)\n", elapsed, ceiling)
|
|
}
|
|
}
|