package oltp
import (
"path/filepath"
"testing"
)
// benchCaps is the hottest path in the forge: every gate resolves it,
// many times per page render. RFC 0018 adds a team lookup to it, so the
// cost of that lookup is measured rather than assumed — twice today a
// performance guess about this codebase turned out to be wrong.
func benchCaps(b *testing.B, withTeam bool) {
db, err := Open(filepath.Join(b.TempDir(), "o.db"))
if err != nil {
b.Fatal(err)
}
defer db.Close()
if err := db.AddAccount("dan", "a-long-enough-password", false); err != nil {
b.Fatal(err)
}
if err := db.SetCaps("dan", "repo", "uv3bBC78"); err != nil {
b.Fatal(err)
}
if withTeam {
if err := db.AddTeam("core", "", "", "dan"); err != nil {
b.Fatal(err)
}
if err := db.SetTeamRepo("core", "repo", "dan"); err != nil {
b.Fatal(err)
}
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = db.EffectiveCaps("dan", "repo")
}
}
// The case almost every forge is in: no teams at all. hasAnyTeam must
// make this free rather than merely cheap.
func BenchmarkEffectiveCapsNoTeams(b *testing.B) { benchCaps(b, false) }
// A forge that has teams pays the lookup. This is the number that
// matters if teams become common.
func BenchmarkEffectiveCapsWithTeams(b *testing.B) { benchCaps(b, true) }
// The short-circuit must not need a query of its own after the first
// call, or it has moved the cost rather than removed it.
func TestTheNoTeamShortCircuitIsCached(t *testing.T) {
db, err := Open(filepath.Join(t.TempDir(), "o.db"))
if err != nil {
t.Fatal(err)
}
defer db.Close()
// First call learns there are none and caches that for the TTL, so
// the second asks nothing at all — the cost the flag exists to
// remove. The first version of this code re-queried every call,
// which the benchmark caught.
if got := db.teamCaps("dan", "repo"); got != "" {
t.Fatalf("FAIL: teamCaps = %q with no teams", got)
}
if db.teamsExist.checked.IsZero() {
t.Error("FAIL: the negative answer was not cached at all")
}
// Once a team exists the flag latches true and stays true.
if err := db.AddAccount("dan", "a-long-enough-password", false); err != nil {
t.Fatal(err)
}
if err := db.AddTeam("core", "", "", "dan"); err != nil {
t.Fatal(err)
}
if !db.hasAnyTeam() {
t.Fatal("FAIL: the flag did not latch when a team was created")
}
if err := db.DeleteTeam("core"); err != nil {
t.Fatal(err)
}
// Deliberately still true: a redundant query on a forge that once
// had a team costs nothing, and clearing it correctly would need a
// count under the lock.
if !db.hasAnyTeam() {
t.Error("FAIL: the flag cleared on delete; that is a race, not an optimisation")
}
}