package main import ( "strings" "testing" ) func TestTopNBasic(t *testing.T) { logs := strings.Join([]string{ "t GET /a 200 1ms", "t GET /b 200 1ms", "t GET /a 200 1ms", "t GET /c 200 1ms", "t GET /a 200 1ms", "t GET /b 200 1ms", }, "\n") got, err := TopN(strings.NewReader(logs), 2) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(got) != 2 { t.Fatalf("want 2 results, got %d: %v", len(got), got) } if got[0].Endpoint != "/a" || got[0].Count != 3 { t.Errorf("want /a x3 first, got %+v", got[0]) } if got[1].Endpoint != "/b" || got[1].Count != 2 { t.Errorf("want /b x2 second, got %+v", got[1]) } } func TestMalformedLinesSkipped(t *testing.T) { logs := "t GET /a 200 1ms\n\ngarbage\nonly two\nt GET /a 200 1ms\n" got, err := TopN(strings.NewReader(logs), 5) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(got) != 1 || got[0].Count != 2 { t.Fatalf("malformed lines mishandled: %v", got) } } func TestNLargerThanDistinct(t *testing.T) { got, err := TopN(strings.NewReader("t GET /a 200 1ms"), 10) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(got) != 1 { t.Fatalf("want 1 result, got %d", len(got)) } } func TestLongLines(t *testing.T) { // A single line > 64KB (bufio.Scanner default max token size). long := "t GET /huge?q=" + strings.Repeat("x", 80*1024) + " 200 1ms" logs := long + "\nt GET /small 200 1ms\nt GET /small 200 1ms\n" got, err := TopN(strings.NewReader(logs), 1) if err != nil { t.Fatalf("long line broke the scanner: %v (raise Scanner.Buffer)", err) } if len(got) == 0 || got[0].Endpoint != "/small" { t.Fatalf("want /small on top, got %v", got) } }