Skip to content

Commit 2547f66

Browse files
committed
test(bench): close export-coverage gaps across nine bench harnesses
Audit pass on the AX-11 sweep surfaced 9 files where the bench harness existed but missed exported funcs / methods on their source file. This pass brings each up to full surface coverage so the contract gate is complete. * slice.go: + SliceReverse, SliceSorted (iter input) * runtime.go: + ServiceStartup, ServiceShutdown (empty Core lifecycle) * string.go: + HTMLUnescape, TrimCutset, TrimLeft, TrimRight, NewBuilder * sync.go: + SyncMap.Swap, LoadAndDelete, CompareAndSwap, CompareAndDelete, Range, Clear + Once.Reset * log.go: + SetLevel, SetOutput, SetRedactKeys, Level.String, Security, NewLogErr, NewLogPanic, LogErr.Log * path.go: + PathAbs (already / relative), PathEvalSymlinks, PathGlob, PathWalk, PathWalkDir * error.go: + (*Err).Unwrap, AllOperations, StackTrace, FormatStackTrace, ErrorPanic.Reports * fs.go: + Fs.Append, ReadStream, EnsureDir, DeleteAll, Rename, NewUnrestricted, ReadDir, ReadFSFile * api.go: + HTTPFS, HTTPFileServer, NewHTTPTestTLSServer (HTTPListenAndServe + RemoteAction excluded — network-bound, not unit-benchable) No source-side perf work this commit — pure surface gating.
1 parent bd43e1f commit 2547f66

9 files changed

Lines changed: 497 additions & 0 deletions

api_bench_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,38 @@ func BenchmarkAPI_Protocols(b *B) {
228228
_ = c.API().Protocols()
229229
}
230230
}
231+
232+
// --- HTTP file server constructors ---
233+
//
234+
// HTTPListenAndServe blocks on a network bind, so we can't run it in a
235+
// bench loop. The pure constructors HTTPFileServer + HTTPFS are cheap
236+
// adapter-builders worth gating, and NewHTTPTestTLSServer is the TLS
237+
// twin of NewHTTPTestServer.
238+
239+
func BenchmarkHTTPFS(b *B) {
240+
fsys := DirFS(".")
241+
b.ReportAllocs()
242+
for i := 0; i < b.N; i++ {
243+
_ = HTTPFS(fsys)
244+
}
245+
}
246+
247+
func BenchmarkHTTPFileServer(b *B) {
248+
root := HTTPFS(DirFS("."))
249+
b.ReportAllocs()
250+
for i := 0; i < b.N; i++ {
251+
_ = HTTPFileServer(root)
252+
}
253+
}
254+
255+
func BenchmarkNewHTTPTestTLSServer(b *B) {
256+
b.ReportAllocs()
257+
for i := 0; i < b.N; i++ {
258+
srv := NewHTTPTestTLSServer(apiBenchHandler)
259+
srv.Close()
260+
}
261+
}
262+
263+
// HTTPListenAndServe + RemoteAction are not benched — they bind a real
264+
// socket / make a real outbound HTTP call. A unit-bench cannot do that
265+
// deterministically. They are exercised end-to-end in api_test.go.

error_bench_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,5 +162,58 @@ func BenchmarkErr_ErrorJoin_Two(b *B) {
162162
}
163163
}
164164

165+
// --- (*Err).Unwrap ---
166+
167+
func BenchmarkErr_Unwrap(b *B) {
168+
b.ReportAllocs()
169+
leaf := errCoreLeaf.(*Err)
170+
for i := 0; i < b.N; i++ {
171+
errSinkErr = leaf.Unwrap()
172+
}
173+
}
174+
175+
// --- AllOperations / StackTrace / FormatStackTrace ---
176+
177+
func BenchmarkErr_AllOperations_Iter(b *B) {
178+
b.ReportAllocs()
179+
for i := 0; i < b.N; i++ {
180+
count := 0
181+
for range AllOperations(errCoreDeep) {
182+
count++
183+
}
184+
errSinkBool = count > 0
185+
}
186+
}
187+
188+
func BenchmarkErr_StackTrace_Deep(b *B) {
189+
b.ReportAllocs()
190+
for i := 0; i < b.N; i++ {
191+
stack := StackTrace(errCoreDeep)
192+
errSinkBool = len(stack) > 0
193+
}
194+
}
195+
196+
func BenchmarkErr_FormatStackTrace_Deep(b *B) {
197+
b.ReportAllocs()
198+
for i := 0; i < b.N; i++ {
199+
errSinkStr = FormatStackTrace(errCoreDeep)
200+
}
201+
}
202+
203+
// --- ErrorPanic surface ---
204+
//
205+
// Recover / SafeGo would require triggering a panic per iteration, which
206+
// is far too costly to bench meaningfully — and not the hot path.
207+
// Reports() is the inspection accessor — that is benchable.
208+
209+
func BenchmarkErr_ErrorPanic_Reports(b *B) {
210+
c := New()
211+
ep := c.Error()
212+
b.ReportAllocs()
213+
for i := 0; i < b.N; i++ {
214+
_ = ep.Reports(10)
215+
}
216+
}
217+
165218
// Quiet unused-imports for "testing" — used implicitly via core.B alias chain.
166219
var _ = testing.Short

fs_bench_test.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,96 @@ func BenchmarkFs_WriteAtomic_1KB(b *B) {
221221
fsSinkResult = fs.WriteAtomic("w.bin", content)
222222
}
223223
}
224+
225+
// --- Append / Stream ---
226+
227+
func BenchmarkFs_Append_Small(b *B) {
228+
fs := fsBenchFixture(b, map[string]int{"appendme.txt": 0})
229+
b.ReportAllocs()
230+
for i := 0; i < b.N; i++ {
231+
fsSinkResult = fs.Append("appendme.txt")
232+
if fsSinkResult.OK {
233+
CloseStream(fsSinkResult.Value)
234+
}
235+
}
236+
}
237+
238+
func BenchmarkFs_ReadStream(b *B) {
239+
fs := fsBenchFixture(b, map[string]int{"stream.bin": 4096})
240+
b.ReportAllocs()
241+
for i := 0; i < b.N; i++ {
242+
fsSinkResult = fs.ReadStream("stream.bin")
243+
if fsSinkResult.OK {
244+
CloseStream(fsSinkResult.Value)
245+
}
246+
}
247+
}
248+
249+
// --- EnsureDir / DeleteAll / Rename ---
250+
251+
func BenchmarkFs_EnsureDir_Exists(b *B) {
252+
fs := fsBenchFixture(b, map[string]int{})
253+
b.ReportAllocs()
254+
for i := 0; i < b.N; i++ {
255+
fsSinkResult = fs.EnsureDir("models")
256+
}
257+
}
258+
259+
func BenchmarkFs_EnsureDir_Create(b *B) {
260+
fs := fsBenchFixture(b, map[string]int{})
261+
b.ReportAllocs()
262+
for i := 0; i < b.N; i++ {
263+
// Cycle the same dir so the bench captures the make-then-noop floor.
264+
fsSinkResult = fs.EnsureDir("ephemeral")
265+
}
266+
}
267+
268+
func BenchmarkFs_DeleteAll(b *B) {
269+
fs := fsBenchFixture(b, map[string]int{})
270+
b.ReportAllocs()
271+
for i := 0; i < b.N; i++ {
272+
fs.EnsureDir("nuked")
273+
fsSinkResult = fs.DeleteAll("nuked")
274+
}
275+
}
276+
277+
func BenchmarkFs_Rename(b *B) {
278+
fs := fsBenchFixture(b, map[string]int{"rename-src.bin": 16})
279+
b.ReportAllocs()
280+
for i := 0; i < b.N; i++ {
281+
fsSinkResult = fs.Rename("rename-src.bin", "rename-dst.bin")
282+
if fsSinkResult.OK {
283+
// Cycle back so the next iteration has the src again.
284+
fs.Rename("rename-dst.bin", "rename-src.bin")
285+
}
286+
}
287+
}
288+
289+
// --- NewUnrestricted ---
290+
291+
func BenchmarkFs_NewUnrestricted(b *B) {
292+
parent := fsBenchFixture(b, map[string]int{})
293+
b.ReportAllocs()
294+
for i := 0; i < b.N; i++ {
295+
_ = parent.NewUnrestricted()
296+
}
297+
}
298+
299+
// --- ReadDir / ReadFSFile (the embed-side helpers) ---
300+
301+
func BenchmarkFs_ReadDir_FS(b *B) {
302+
fsys := DirFS(".")
303+
b.ReportAllocs()
304+
for i := 0; i < b.N; i++ {
305+
fsSinkResult = ReadDir(fsys, ".")
306+
}
307+
}
308+
309+
func BenchmarkFs_ReadFSFile(b *B) {
310+
fs := fsBenchFixture(b, map[string]int{"r.bin": 1024})
311+
fsys := DirFS(fs.Root())
312+
b.ReportAllocs()
313+
for i := 0; i < b.N; i++ {
314+
fsSinkResult = ReadFSFile(fsys, "r.bin")
315+
}
316+
}

log_bench_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,76 @@ func BenchmarkLog_PackageInfo_BelowThreshold(b *B) {
100100
Info("agent ready", "host", "homelab.lan")
101101
}
102102
}
103+
104+
// --- Setters (mutex-gated, no formatting) ---
105+
106+
func BenchmarkLog_SetLevel(b *B) {
107+
l := logBenchFixture(LevelInfo)
108+
b.ReportAllocs()
109+
for i := 0; i < b.N; i++ {
110+
l.SetLevel(LevelInfo)
111+
}
112+
}
113+
114+
func BenchmarkLog_SetOutput(b *B) {
115+
l := logBenchFixture(LevelInfo)
116+
b.ReportAllocs()
117+
for i := 0; i < b.N; i++ {
118+
l.SetOutput(io.Discard)
119+
}
120+
}
121+
122+
func BenchmarkLog_SetRedactKeys(b *B) {
123+
l := logBenchFixture(LevelInfo)
124+
b.ReportAllocs()
125+
for i := 0; i < b.N; i++ {
126+
l.SetRedactKeys("token", "authorization", "cookie")
127+
}
128+
}
129+
130+
// --- Level.String ---
131+
132+
func BenchmarkLog_LevelString(b *B) {
133+
b.ReportAllocs()
134+
for i := 0; i < b.N; i++ {
135+
_ = LevelInfo.String()
136+
}
137+
}
138+
139+
// --- Security path (formatter shared with Error) ---
140+
141+
func BenchmarkLog_Security(b *B) {
142+
l := logBenchFixture(LevelError)
143+
b.ReportAllocs()
144+
for i := 0; i < b.N; i++ {
145+
l.Security("entitlement.denied", "action", "process.run", "user", "darbs")
146+
}
147+
}
148+
149+
// --- LogErr / LogPanic ---
150+
151+
func BenchmarkLog_NewLogErr(b *B) {
152+
l := logBenchFixture(LevelError)
153+
b.ReportAllocs()
154+
for i := 0; i < b.N; i++ {
155+
_ = NewLogErr(l)
156+
}
157+
}
158+
159+
func BenchmarkLog_NewLogPanic(b *B) {
160+
l := logBenchFixture(LevelError)
161+
b.ReportAllocs()
162+
for i := 0; i < b.N; i++ {
163+
_ = NewLogPanic(l)
164+
}
165+
}
166+
167+
func BenchmarkLog_LogErr_Log(b *B) {
168+
l := logBenchFixture(LevelError)
169+
logger := NewLogErr(l)
170+
err := E("bench.LogErr", "synthetic", nil)
171+
b.ReportAllocs()
172+
for i := 0; i < b.N; i++ {
173+
logger.Log(err)
174+
}
175+
}

path_bench_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,67 @@ func BenchmarkPathToSlash(b *B) {
131131
pathSinkString = PathToSlash("/home/agent/models")
132132
}
133133
}
134+
135+
// --- Filesystem-aware (Abs / EvalSymlinks / Glob / Walk*) ---
136+
//
137+
// These touch syscalls, so they are slower than the pure-string ops
138+
// above. The bench harness gates the contract — slowdowns from a Core
139+
// reroute show up here.
140+
141+
func BenchmarkPathAbs_Already(b *B) {
142+
b.ReportAllocs()
143+
for i := 0; i < b.N; i++ {
144+
pathSinkResult = PathAbs("/already/absolute/path")
145+
}
146+
}
147+
148+
func BenchmarkPathAbs_Relative(b *B) {
149+
b.ReportAllocs()
150+
for i := 0; i < b.N; i++ {
151+
pathSinkResult = PathAbs("relative/path")
152+
}
153+
}
154+
155+
func BenchmarkPathEvalSymlinks_RealDir(b *B) {
156+
// /tmp is real on every dev box and has no surprising depth.
157+
b.ReportAllocs()
158+
for i := 0; i < b.N; i++ {
159+
pathSinkResult = PathEvalSymlinks("/tmp")
160+
}
161+
}
162+
163+
func BenchmarkPathGlob_NoMatch(b *B) {
164+
pat := "/tmp/__core-bench-no-match-*.gguf"
165+
b.ReportAllocs()
166+
for i := 0; i < b.N; i++ {
167+
pathSinkStrings = PathGlob(pat)
168+
}
169+
}
170+
171+
func BenchmarkPathWalk_TmpShallow(b *B) {
172+
root := "/tmp"
173+
noop := func(_ string, _ FsFileInfo, err error) error {
174+
if err != nil {
175+
return nil
176+
}
177+
return PathSkipDir
178+
}
179+
b.ReportAllocs()
180+
for i := 0; i < b.N; i++ {
181+
_ = PathWalk(root, noop)
182+
}
183+
}
184+
185+
func BenchmarkPathWalkDir_TmpShallow(b *B) {
186+
root := "/tmp"
187+
noop := func(_ string, _ FsDirEntry, err error) error {
188+
if err != nil {
189+
return nil
190+
}
191+
return PathSkipDir
192+
}
193+
b.ReportAllocs()
194+
for i := 0; i < b.N; i++ {
195+
_ = PathWalkDir(root, noop)
196+
}
197+
}

runtime_bench_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,27 @@ func BenchmarkRuntime_ServiceName(b *B) {
118118
runtimeSinkString = r.ServiceName()
119119
}
120120
}
121+
122+
// --- Service lifecycle (startup + shutdown round-trip on empty Core) ---
123+
//
124+
// Service registration is a one-shot per process — but the cost matters
125+
// during test loops + multi-Core consumers. Empty Core is the floor;
126+
// adds a startable to time the iteration overhead the dispatcher pays.
127+
128+
func BenchmarkServiceStartup_Empty(b *B) {
129+
b.ReportAllocs()
130+
for i := 0; i < b.N; i++ {
131+
c := New()
132+
runtimeSinkRuntimeRes = c.ServiceStartup(Background(), nil)
133+
c.ServiceShutdown(Background())
134+
}
135+
}
136+
137+
func BenchmarkServiceShutdown_Empty(b *B) {
138+
b.ReportAllocs()
139+
for i := 0; i < b.N; i++ {
140+
c := New()
141+
c.ServiceStartup(Background(), nil)
142+
runtimeSinkRuntimeRes = c.ServiceShutdown(Background())
143+
}
144+
}

slice_bench_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,28 @@ func BenchmarkSliceFlatMap(b *B) {
167167
_ = SliceFlatMap(src, func(n int) []int { return []int{n, n * 2, n * 3} })
168168
}
169169
}
170+
171+
// --- Reverse / Sorted ---
172+
173+
func BenchmarkSliceReverse_Medium(b *B) {
174+
b.ReportAllocs()
175+
for i := 0; i < b.N; i++ {
176+
s := SliceClone(benchSliceMedium)
177+
SliceReverse(s)
178+
}
179+
}
180+
181+
func BenchmarkSliceSorted_Iter(b *B) {
182+
src := benchSliceMedium
183+
seq := Seq[int](func(yield func(int) bool) {
184+
for _, v := range src {
185+
if !yield(v) {
186+
return
187+
}
188+
}
189+
})
190+
b.ReportAllocs()
191+
for i := 0; i < b.N; i++ {
192+
_ = SliceSorted(seq)
193+
}
194+
}

0 commit comments

Comments
 (0)