diff --git a/.gitignore b/.gitignore index 673cd2135443792323ed326f3dd5dfeec97a6624..c7b4858b6bdc96131fd0a6974e605980cc131bb4 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ .dolt/ *.db .beads-credential-key .beads/proxieddb/ +cover.out +bench.txt diff --git a/bearer/bearer_bench_test.go b/bearer/bearer_bench_test.go index d5c9915f36e95259699f7a7bd074e6c58ba76ecb..18c3249b72f6831b948c8233094ad31a24f67936 100644 --- a/bearer/bearer_bench_test.go +++ b/bearer/bearer_bench_test.go @@ -3,11 +3,32 @@ import ( "context" "errors" + "io" + "log" "net/http" "net/http/httptest" "testing" ) +// discardStdLog silences the standard logger for one benchmark. sr-ht-core's +// auth.DecodeBearerToken calls log.Printf on every token it refuses, so the +// invalid case below writes one line per iteration — an unfiltered run of this +// package produced 9.5 million of them and a 901 MB file. Two things follow. +// The number stops being a measurement of this package: log.Printf takes a +// mutex, so what was timed was the logger. And the file is worse than useless +// rather than merely large, because benchfmt skips lines it cannot parse, so +// bench.sr.ht would accept that upload and report success over it. +// +// It is the std log package here rather than slog — that is why this is not +// the discardLog the middleware and chimw benchmarks share. +func discardStdLog(b *testing.B) { + b.Helper() + + previous := log.Writer() + log.SetOutput(io.Discard) + b.Cleanup(func() { log.SetOutput(previous) }) +} + // The grant strings these benchmarks present. The stateless one is what a short // token carries; the registered one adds the id: member that turns step 4 from // a no-op into a cache lookup. @@ -74,6 +95,8 @@ // - invalid: junk. Step 1 refuses it without allocating a token, and this is // the path an instance under a flood of forged credentials runs; it must // stay the cheapest thing here. func BenchmarkValidate(b *testing.B) { + discardStdLog(b) + ctx := context.Background() v := benchValidator(b) @@ -136,6 +159,8 @@ // four steps without step 3, once per request, upstream of the router. Read it // beside BenchmarkValidate/stateless — the gap is the grant check that Inspect // leaves to the handler. func BenchmarkInspect(b *testing.B) { + discardStdLog(b) + ctx := context.Background() v := benchValidator(b) presented := ourToken(benchGrants) @@ -158,6 +183,8 @@ // choice shows up. A per-request HMAC is embarrassingly parallel; a shared lock // is not, and the point of measuring it is to know which of the two dominates // before somebody proposes sharding the cache. func BenchmarkValidateParallel(b *testing.B) { + discardStdLog(b) + ctx := context.Background() v := benchValidator(b) registered := ourToken(benchGrantsRegistered)