package timing
import (
"strings"
"testing"
"time"
)
// A category total says a LAYER was busy. It cannot say which call made
// it so, and "ops 952.6ms×4" sends a reader to the server log to find
// out which of the four it was. The name travels with the number.
func TestBreakdownNamesTheCallThatDominates(t *testing.T) {
tm := &Timing{by: map[Category]*entry{}}
t0 := time.Now()
tm.AddNamed(Ops, "me.feed", t0, t0.Add(890*time.Millisecond))
tm.AddNamed(Ops, "ticket.across", t0.Add(890*time.Millisecond), t0.Add(900*time.Millisecond))
tm.AddNamed(Ops, "repo.list", t0.Add(900*time.Millisecond), t0.Add(905*time.Millisecond))
got := tm.Breakdown()
if !strings.Contains(got, "me.feed") {
t.Errorf("breakdown = %q, want the op that took the time", got)
}
if strings.Contains(got, "ticket.across") {
t.Errorf("breakdown = %q, want ONE suspect, not a profile", got)
}
if !strings.Contains(got, "×3") {
t.Errorf("breakdown = %q, want the call count kept", got)
}
}
// No single call dominating means there is no suspect to name, and
// naming one anyway would point at whichever was marginally slowest —
// an accusation the numbers do not support.
func TestNoSuspectWhenTheCostIsSpread(t *testing.T) {
tm := &Timing{by: map[Category]*entry{}}
t0 := time.Now()
for i, name := range []string{"a.one", "b.two", "c.three", "d.four"} {
from := t0.Add(time.Duration(i) * 100 * time.Millisecond)
tm.AddNamed(Ops, name, from, from.Add(100*time.Millisecond))
}
if got := tm.Breakdown(); strings.ContainsAny(got, "()") {
t.Errorf("breakdown = %q, want no suspect when four calls cost the same", got)
}
}
// One call in a category needs no name: the category is that call, and
// printing it twice is noise on every ordinary page.
func TestASingleCallIsNotAnnotated(t *testing.T) {
tm := &Timing{by: map[Category]*entry{}}
t0 := time.Now()
tm.AddNamed(Ops, "me.feed", t0, t0.Add(300*time.Millisecond))
if got := tm.Breakdown(); strings.Contains(got, "me.feed") {
t.Errorf("breakdown = %q, want no annotation for a lone call", got)
}
}