blob: 369094acba12aa533b54248d79b34db70a27ea26 [file] [log] [blame] [edit]
package benchseries
import (
"fmt"
"reflect"
"testing"
"golang.org/x/perf/benchfmt"
)
func makeConfig(key, value string) benchfmt.Config {
return benchfmt.Config{
Key: key,
Value: []byte(value),
File: true, // N.B. Residue ignores non-File config!
}
}
func TestBasic(t *testing.T) {
results := []*benchfmt.Result{
{
Config: []benchfmt.Config{
makeConfig("compare", "numerator"),
makeConfig("runstamp", "2020-01-01T00:00:00Z"),
makeConfig("numerator-hash", "abcdef0123456789"),
makeConfig("denominator-hash", "9876543219fedcba"),
makeConfig("numerator-hash-time", "2020-02-02T00:00:00Z"),
makeConfig("residue", "foo"),
},
Name: []byte("Foo"),
Iters: 10,
Values: []benchfmt.Value{
{Value: 1, Unit: "sec"},
},
},
{
Config: []benchfmt.Config{
makeConfig("compare", "denominator"),
makeConfig("runstamp", "2020-01-01T00:00:00Z"),
makeConfig("numerator-hash", "abcdef0123456789"),
makeConfig("denominator-hash", "9876543219fedcba"),
makeConfig("numerator-hash-time", "2020-02-02T00:00:00Z"),
makeConfig("residue", "foo"),
},
Name: []byte("Foo"),
Iters: 10,
Values: []benchfmt.Value{
{Value: 10, Unit: "sec"},
},
},
}
opts := &BuilderOptions{
Filter: ".unit:/.*/",
Series: "numerator-hash-time",
Table: "", // .unit only
Experiment: "runstamp",
Compare: "compare",
Numerator: "numerator",
Denominator: "denominator",
NumeratorHash: "numerator-hash",
DenominatorHash: "denominator-hash",
Warn: func(format string, args ...interface{}) {
s := fmt.Sprintf(format, args...)
t.Errorf("benchseries warning: %s", s)
},
}
builder, err := NewBuilder(opts)
if err != nil {
t.Fatalf("NewBuilder get err %v, want err nil", err)
}
for _, r := range results {
builder.Add(r)
}
comparisons, err := builder.AllComparisonSeries(nil, DUPE_REPLACE)
if err != nil {
t.Fatalf("AllComparisonSeries got err %v want err nil", err)
}
if len(comparisons) != 1 {
t.Fatalf("len(comparisons) got %d want 1; comparisons: %+v", len(comparisons), comparisons)
}
got := comparisons[0]
if got.Unit != "sec" {
t.Errorf(`Unit got %q, want "sec"`, got.Unit)
}
wantBenchmarks := []string{"Foo"}
if !reflect.DeepEqual(got.Benchmarks, wantBenchmarks) {
t.Errorf("Benchmarks got %v want %v", got.Benchmarks, wantBenchmarks)
}
wantSeries := []string{"2020-02-02T00:00:00+00:00"}
if !reflect.DeepEqual(got.Series, wantSeries) {
t.Errorf("Series got %v want %v", got.Series, wantSeries)
}
wantHashPairs := map[string]ComparisonHashes{
"2020-02-02T00:00:00+00:00": ComparisonHashes{
NumHash: "abcdef0123456789",
DenHash: "9876543219fedcba",
},
}
if !reflect.DeepEqual(got.HashPairs, wantHashPairs) {
t.Errorf("HashPairs got %+v want %+v", got.HashPairs, wantHashPairs)
}
wantResidues := []StringAndSlice{{S: "residue", Slice: []string{"foo"}}}
if !reflect.DeepEqual(got.Residues, wantResidues) {
t.Errorf("Residues got %v want %v", got.Residues, wantResidues)
}
}
// If the compare key is missing, then there is nothing to compare.
func TestMissingCompare(t *testing.T) {
results := []*benchfmt.Result{
{
Config: []benchfmt.Config{
makeConfig("runstamp", "2020-01-01T00:00:00Z"),
makeConfig("numerator-hash", "abcdef0123456789"),
makeConfig("denominator-hash", "9876543219fedcba"),
makeConfig("numerator-hash-time", "2020-02-02T00:00:00Z"),
makeConfig("residue", "foo"),
},
Name: []byte("Foo"),
Iters: 10,
Values: []benchfmt.Value{
{Value: 1, Unit: "sec"},
},
},
{
Config: []benchfmt.Config{
makeConfig("runstamp", "2020-01-01T00:00:00Z"),
makeConfig("numerator-hash", "abcdef0123456789"),
makeConfig("denominator-hash", "9876543219fedcba"),
makeConfig("numerator-hash-time", "2020-02-02T00:00:00Z"),
makeConfig("residue", "foo"),
},
Name: []byte("Foo"),
Iters: 10,
Values: []benchfmt.Value{
{Value: 10, Unit: "sec"},
},
},
}
opts := &BuilderOptions{
Filter: ".unit:/.*/",
Series: "numerator-hash-time",
Table: "", // .unit only
Experiment: "runstamp",
Compare: "compare",
Numerator: "numerator",
Denominator: "denominator",
NumeratorHash: "numerator-hash",
DenominatorHash: "denominator-hash",
Warn: func(format string, args ...interface{}) {
s := fmt.Sprintf(format, args...)
t.Errorf("benchseries warning: %s", s)
},
}
builder, err := NewBuilder(opts)
if err != nil {
t.Fatalf("NewBuilder get err %v, want err nil", err)
}
for _, r := range results {
builder.Add(r)
}
comparisons, err := builder.AllComparisonSeries(nil, DUPE_REPLACE)
if err != nil {
t.Fatalf("AllComparisonSeries got err %v want err nil", err)
}
if len(comparisons) != 1 {
t.Fatalf("len(comparisons) got %d want 1; comparisons: %+v", len(comparisons), comparisons)
}
got := comparisons[0]
if len(got.Series) != 0 {
t.Errorf("len(Series) got %d want 0; Series: %+v", len(got.Series), got.Series)
}
}
// A test point with no denominator.
func TestMissingDenominator(t *testing.T) {
results := []*benchfmt.Result{
{
Config: []benchfmt.Config{
makeConfig("compare", "numerator"),
makeConfig("runstamp", "2020-01-01T00:00:00Z"),
makeConfig("numerator-hash", "abcdef0123456789"),
makeConfig("denominator-hash", "9876543219fedcba"),
makeConfig("numerator-hash-time", "2020-02-02T00:00:00Z"),
makeConfig("residue", "foo"),
},
Name: []byte("Foo"),
Iters: 10,
Values: []benchfmt.Value{
{Value: 10, Unit: "sec"},
},
},
}
opts := &BuilderOptions{
Filter: ".unit:/.*/",
Series: "numerator-hash-time",
Table: "", // .unit only
Experiment: "runstamp",
Compare: "compare",
Numerator: "numerator",
Denominator: "denominator",
NumeratorHash: "numerator-hash",
DenominatorHash: "denominator-hash",
Warn: func(format string, args ...interface{}) {
s := fmt.Sprintf(format, args...)
t.Errorf("benchseries warning: %s", s)
},
}
builder, err := NewBuilder(opts)
if err != nil {
t.Fatalf("NewBuilder get err %v, want err nil", err)
}
for _, r := range results {
builder.Add(r)
}
comparisons, err := builder.AllComparisonSeries(nil, DUPE_REPLACE)
if err != nil {
t.Fatalf("AllComparisonSeries got err %v want err nil", err)
}
if len(comparisons) != 1 {
t.Fatalf("len(comparisons) got %d want 1; comparisons: %+v", len(comparisons), comparisons)
}
got := comparisons[0]
got.AddSummaries(0.95, 1000)
if len(got.Summaries) != 1 {
t.Fatalf("Expect 1 comparison, got: %+v", len(got.Summaries))
}
}