package grants import "testing" // The grant string these benchmarks work on is the shape a real working token // carries on this instance: a handful of : members from the // vocabulary of SPEC ch. 3, plus the reserved id: member a registered token is // stamped with. It is deliberately unsorted — Parse sorts on the way out, and a // pre-sorted input would measure a cheaper parse than the one that runs. const benchGrantString = "dolt:push bench:upload cov:upload artifacts:upload dolt:pull meta:profile id:4711" // The sinks exist so that nothing below can be discarded as a call whose result // is never read. b.Loop already keeps the call itself, but the assignment is // what keeps the *value* alive across the toolchain versions this builds on. var ( sinkGrants Grants sinkBool bool sinkString string sinkErr error ) // BenchmarkParse is the per-request cost of this package, not a corner of it: // bearer.decodeOurs parses the grant string of every presented token on every // request, so this allocation profile is the one every service pays per call. func BenchmarkParse(b *testing.B) { b.ReportAllocs() for b.Loop() { sinkGrants, sinkErr = Parse(benchGrantString) } if sinkErr != nil { b.Fatalf("the fixture must parse: %v", sinkErr) } } // BenchmarkParseRequested is the mint path — the same parse with the reserved // id: member refused. It is here beside Parse because the refusal is a // privilege boundary, and a change that made it cost noticeably more than the // stored parse would be a change worth seeing. func BenchmarkParseRequested(b *testing.B) { // Without the id: member, which ParseRequested refuses by design. const requested = "dolt:push bench:upload cov:upload artifacts:upload dolt:pull meta:profile" b.ReportAllocs() for b.Loop() { sinkGrants, sinkErr = ParseRequested(requested) } if sinkErr != nil { b.Fatalf("the fixture must parse: %v", sinkErr) } } // BenchmarkHas is step 3 of the validation: one map lookup, taken on every // authorized request. The miss is measured beside the hit because a refusal is // what a flood of ill-scoped tokens produces, and the two must cost the same — // a set whose miss is slower than its hit answers "was this refused?" to // anybody who can time it. func BenchmarkHas(b *testing.B) { g, err := Parse(benchGrantString) if err != nil { b.Fatalf("the fixture must parse: %v", err) } universal := All() b.Run("hit", func(b *testing.B) { b.ReportAllocs() for b.Loop() { sinkBool = g.Has("bench:upload") } }) b.Run("miss", func(b *testing.B) { b.ReportAllocs() for b.Loop() { sinkBool = g.Has("dolt:admin") } }) b.Run("universal", func(b *testing.B) { b.ReportAllocs() for b.Loop() { sinkBool = universal.Has("bench:upload") } }) } // BenchmarkIsSubsetOf is the narrowing rule of SPEC ch. 2, which runs once per // exchange. The "narrower" case walks the whole member set and is the one that // bounds the cost; "wider" is the early refusal. func BenchmarkIsSubsetOf(b *testing.B) { parent, err := Parse(benchGrantString) if err != nil { b.Fatalf("the fixture must parse: %v", err) } child, err := Parse("bench:upload cov:upload id:8123") if err != nil { b.Fatalf("the fixture must parse: %v", err) } b.Run("narrower", func(b *testing.B) { b.ReportAllocs() for b.Loop() { sinkBool = child.IsSubsetOf(parent) } }) b.Run("wider", func(b *testing.B) { b.ReportAllocs() for b.Loop() { sinkBool = parent.IsSubsetOf(child) } }) } // BenchmarkString is the render half: sorting the members and appending the // id:. It runs whenever a set is written back into a token payload or a // database column, and it is the one operation here that sorts. func BenchmarkString(b *testing.B) { g, err := Parse(benchGrantString) if err != nil { b.Fatalf("the fixture must parse: %v", err) } b.ReportAllocs() for b.Loop() { sinkString = g.String() } }