blob: d7f1f6c76784246dacd4f8b9274176cf3331a93e [file] [log] [blame]
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package app
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"reflect"
"strings"
"testing"
"golang.org/x/build/perfdata"
"golang.org/x/perf/storage/benchfmt"
)
func TestResultGroup(t *testing.T) {
data := `key: value
BenchmarkName 1 ns/op
key: value2
BenchmarkName 1 ns/op`
var results []*benchfmt.Result
br := benchfmt.NewReader(strings.NewReader(data))
g := &resultGroup{}
for br.Next() {
results = append(results, br.Result())
g.add(br.Result())
}
if err := br.Err(); err != nil {
t.Fatalf("Err() = %v, want nil", err)
}
if !reflect.DeepEqual(g.results, results) {
t.Errorf("g.results = %#v, want %#v", g.results, results)
}
if want := map[string]valueSet{"key": {"value": 1, "value2": 1}}; !reflect.DeepEqual(g.LabelValues, want) {
t.Errorf("g.LabelValues = %#v, want %#v", g.LabelValues, want)
}
groups := g.splitOn("key")
if len(groups) != 2 {
t.Fatalf("g.splitOn returned %d groups, want 2", len(groups))
}
for i, results := range [][]*benchfmt.Result{
{results[0]},
{results[1]},
} {
if !reflect.DeepEqual(groups[i].results, results) {
t.Errorf("groups[%d].results = %#v, want %#v", i, groups[i].results, results)
}
}
}
// static responses for TestCompareQuery
var compareQueries = map[string]string{
"one": `upload: 1
upload-part: 1
label: value
BenchmarkOne 1 5 ns/op
BenchmarkTwo 1 10 ns/op`,
"two": `upload: 1
upload-part: 2
BenchmarkOne 1 10 ns/op
BenchmarkTwo 1 5 ns/op`,
"onetwo": `upload: 1
upload-part: 1
label: value
BenchmarkOne 1 5 ns/op
BenchmarkTwo 1 10 ns/op
label:
upload-part: 2
BenchmarkOne 1 10 ns/op
BenchmarkTwo 1 5 ns/op`,
}
func TestCompareQuery(t *testing.T) {
// TODO(quentin): This test seems too heavyweight; we are but shouldn't be also testing the perfdata client -> perfdata server interaction.
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
t.Errorf("ParseForm = %v", err)
}
q := r.Form.Get("q")
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
fmt.Fprint(w, compareQueries[q])
}))
defer ts.Close()
a := &App{StorageClient: &perfdata.Client{BaseURL: ts.URL}}
for _, q := range []string{"one vs two", "onetwo"} {
t.Run(q, func(t *testing.T) {
data := a.compareQuery(context.Background(), q)
if data.Error != "" {
t.Fatalf("compareQuery failed: %s", data.Error)
}
if have := data.Q; have != q {
t.Errorf("Q = %q, want %q", have, q)
}
if len(data.Groups) != 2 {
t.Errorf("len(Groups) = %d, want 2", len(data.Groups))
}
if len(data.Benchstat.String()) == 0 {
t.Error("len(Benchstat) = 0, want >0")
}
if want := map[string]bool{"upload-part": true, "label": true}; !reflect.DeepEqual(data.Labels, want) {
t.Errorf("Labels = %#v, want %#v", data.Labels, want)
}
if want := (benchfmt.Labels{"upload": "1"}); !reflect.DeepEqual(data.CommonLabels, want) {
t.Errorf("CommonLabels = %#v, want %#v", data.CommonLabels, want)
}
})
}
}
func TestAddToQuery(t *testing.T) {
tests := []struct {
query, add string
want string
}{
{"one", "two", "two | one"},
{"pre | one vs two", "three", "three pre | one vs two"},
{"four", "five six", `"five six" | four`},
{"seven", `extra "fun"\problem`, `"extra \"fun\"\\problem" | seven`},
{"eight", `ni\"ne`, `"ni\\\"ne" | eight`},
}
for i, test := range tests {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
if got := addToQuery(test.query, test.add); got != test.want {
t.Errorf("addToQuery(%q, %q) = %q, want %q", test.query, test.add, got, test.want)
}
})
}
}
func TestElideKeyValues(t *testing.T) {
type sb map[string]bool
tests := []struct {
content string
keys sb
want string
}{
{"BenchmarkOne/key=1-1 1 ns/op", sb{"key": true}, "BenchmarkOne/key=*-1 1 ns/op"},
{"BenchmarkOne/key=1-2 1 ns/op", sb{"other": true}, "BenchmarkOne/key=1-2 1 ns/op"},
{"BenchmarkOne/key=1/key2=2-3 1 ns/op", sb{"key": true}, "BenchmarkOne/key=*/key2=2-3 1 ns/op"},
{"BenchmarkOne/foo/bar-4 1 ns/op", sb{"sub1": true}, "BenchmarkOne/*/bar-4 1 ns/op"},
{"BenchmarkOne/foo/bar-5 1 ns/op", sb{"gomaxprocs": true}, "BenchmarkOne/foo/bar-* 1 ns/op"},
{"BenchmarkOne/foo/bar-6 1 ns/op", sb{"name": true}, "Benchmark*/foo/bar-6 1 ns/op"},
}
for i, test := range tests {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
have := elideKeyValues(test.content, test.keys)
if have != test.want {
t.Errorf("elideKeys(%q, %#v) = %q, want %q", test.content, map[string]bool(test.keys), have, test.want)
}
})
}
}