github.com/jgbaldwinbrown/perf@v0.1.1/analysis/app/compare_test.go (about)

     1  // Copyright 2017 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package app
     6  
     7  import (
     8  	"fmt"
     9  	"net/http"
    10  	"net/http/httptest"
    11  	"reflect"
    12  	"strings"
    13  	"testing"
    14  
    15  	"golang.org/x/net/context"
    16  	"golang.org/x/perf/storage"
    17  	"golang.org/x/perf/storage/benchfmt"
    18  )
    19  
    20  func TestResultGroup(t *testing.T) {
    21  	data := `key: value
    22  BenchmarkName 1 ns/op
    23  key: value2
    24  BenchmarkName 1 ns/op`
    25  	var results []*benchfmt.Result
    26  	br := benchfmt.NewReader(strings.NewReader(data))
    27  	g := &resultGroup{}
    28  	for br.Next() {
    29  		results = append(results, br.Result())
    30  		g.add(br.Result())
    31  	}
    32  	if err := br.Err(); err != nil {
    33  		t.Fatalf("Err() = %v, want nil", err)
    34  	}
    35  	if !reflect.DeepEqual(g.results, results) {
    36  		t.Errorf("g.results = %#v, want %#v", g.results, results)
    37  	}
    38  	if want := map[string]valueSet{"key": {"value": 1, "value2": 1}}; !reflect.DeepEqual(g.LabelValues, want) {
    39  		t.Errorf("g.LabelValues = %#v, want %#v", g.LabelValues, want)
    40  	}
    41  	groups := g.splitOn("key")
    42  	if len(groups) != 2 {
    43  		t.Fatalf("g.splitOn returned %d groups, want 2", len(groups))
    44  	}
    45  	for i, results := range [][]*benchfmt.Result{
    46  		{results[0]},
    47  		{results[1]},
    48  	} {
    49  		if !reflect.DeepEqual(groups[i].results, results) {
    50  			t.Errorf("groups[%d].results = %#v, want %#v", i, groups[i].results, results)
    51  		}
    52  	}
    53  }
    54  
    55  // static responses for TestCompareQuery
    56  var compareQueries = map[string]string{
    57  	"one": `upload: 1
    58  upload-part: 1
    59  label: value
    60  BenchmarkOne 1 5 ns/op
    61  BenchmarkTwo 1 10 ns/op`,
    62  	"two": `upload: 1
    63  upload-part: 2
    64  BenchmarkOne 1 10 ns/op
    65  BenchmarkTwo 1 5 ns/op`,
    66  	"onetwo": `upload: 1
    67  upload-part: 1
    68  label: value
    69  BenchmarkOne 1 5 ns/op
    70  BenchmarkTwo 1 10 ns/op
    71  label:
    72  upload-part: 2
    73  BenchmarkOne 1 10 ns/op
    74  BenchmarkTwo 1 5 ns/op`,
    75  }
    76  
    77  func TestCompareQuery(t *testing.T) {
    78  	// TODO(quentin): This test seems too heavyweight; we are but shouldn't be also testing the storage client -> storage server interaction.
    79  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    80  		if err := r.ParseForm(); err != nil {
    81  			t.Errorf("ParseForm = %v", err)
    82  		}
    83  		q := r.Form.Get("q")
    84  		w.Header().Set("Content-Type", "text/plain; charset=utf-8")
    85  		fmt.Fprint(w, compareQueries[q])
    86  	}))
    87  	defer ts.Close()
    88  
    89  	a := &App{StorageClient: &storage.Client{BaseURL: ts.URL}}
    90  
    91  	for _, q := range []string{"one vs two", "onetwo"} {
    92  		t.Run(q, func(t *testing.T) {
    93  			data := a.compareQuery(context.Background(), q)
    94  			if data.Error != "" {
    95  				t.Fatalf("compareQuery failed: %s", data.Error)
    96  			}
    97  			if have := data.Q; have != q {
    98  				t.Errorf("Q = %q, want %q", have, q)
    99  			}
   100  			if len(data.Groups) != 2 {
   101  				t.Errorf("len(Groups) = %d, want 2", len(data.Groups))
   102  			}
   103  			if len(data.Benchstat) == 0 {
   104  				t.Error("len(Benchstat) = 0, want >0")
   105  			}
   106  			if want := map[string]bool{"upload-part": true, "label": true}; !reflect.DeepEqual(data.Labels, want) {
   107  				t.Errorf("Labels = %#v, want %#v", data.Labels, want)
   108  			}
   109  			if want := (benchfmt.Labels{"upload": "1"}); !reflect.DeepEqual(data.CommonLabels, want) {
   110  				t.Errorf("CommonLabels = %#v, want %#v", data.CommonLabels, want)
   111  			}
   112  		})
   113  	}
   114  }
   115  
   116  func TestAddToQuery(t *testing.T) {
   117  	tests := []struct {
   118  		query, add string
   119  		want       string
   120  	}{
   121  		{"one", "two", "two | one"},
   122  		{"pre | one vs two", "three", "three pre | one vs two"},
   123  		{"four", "five six", `"five six" | four`},
   124  		{"seven", `extra "fun"\problem`, `"extra \"fun\"\\problem" | seven`},
   125  		{"eight", `ni\"ne`, `"ni\\\"ne" | eight`},
   126  	}
   127  	for i, test := range tests {
   128  		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
   129  			if got := addToQuery(test.query, test.add); got != test.want {
   130  				t.Errorf("addToQuery(%q, %q) = %q, want %q", test.query, test.add, got, test.want)
   131  			}
   132  		})
   133  	}
   134  }
   135  
   136  func TestElideKeyValues(t *testing.T) {
   137  	type sb map[string]bool
   138  	tests := []struct {
   139  		content string
   140  		keys    sb
   141  		want    string
   142  	}{
   143  		{"BenchmarkOne/key=1-1 1 ns/op", sb{"key": true}, "BenchmarkOne/key=*-1 1 ns/op"},
   144  		{"BenchmarkOne/key=1-2 1 ns/op", sb{"other": true}, "BenchmarkOne/key=1-2 1 ns/op"},
   145  		{"BenchmarkOne/key=1/key2=2-3 1 ns/op", sb{"key": true}, "BenchmarkOne/key=*/key2=2-3 1 ns/op"},
   146  		{"BenchmarkOne/foo/bar-4 1 ns/op", sb{"sub1": true}, "BenchmarkOne/*/bar-4 1 ns/op"},
   147  		{"BenchmarkOne/foo/bar-5 1 ns/op", sb{"gomaxprocs": true}, "BenchmarkOne/foo/bar-* 1 ns/op"},
   148  		{"BenchmarkOne/foo/bar-6 1 ns/op", sb{"name": true}, "Benchmark*/foo/bar-6 1 ns/op"},
   149  	}
   150  	for i, test := range tests {
   151  		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
   152  			have := elideKeyValues(test.content, test.keys)
   153  			if have != test.want {
   154  				t.Errorf("elideKeys(%q, %#v) = %q, want %q", test.content, map[string]bool(test.keys), have, test.want)
   155  			}
   156  		})
   157  	}
   158  }