| 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)) | |
| } | |
| } |