From 2c64f977066ead9f17c2404b18ee3e307e8656d9 Mon Sep 17 00:00:00 2001 From: Yahor Yuzefovich Date: Fri, 15 Feb 2019 20:54:34 -0800 Subject: [PATCH] exec: verify test results based on set or ordered comparison Before my recent change (#34924), test results were compared in order; after the change, test results are compared using a set comparison (i.e. whether two sets contain the same tuples). However, we should be able to use one or the other based on what we are testing, so this commit adds this ability. Release note: None --- pkg/sql/exec/aggregator_test.go | 8 +++---- pkg/sql/exec/count_test.go | 2 +- pkg/sql/exec/distinct_test.go | 2 +- pkg/sql/exec/hashjoiner_test.go | 2 +- pkg/sql/exec/limit_test.go | 2 +- pkg/sql/exec/offset_test.go | 2 +- pkg/sql/exec/utils_test.go | 41 +++++++++++++++++++++++++++++---- 7 files changed, 45 insertions(+), 14 deletions(-) diff --git a/pkg/sql/exec/aggregator_test.go b/pkg/sql/exec/aggregator_test.go index dab8a3ba441d..abac86cd8d59 100644 --- a/pkg/sql/exec/aggregator_test.go +++ b/pkg/sql/exec/aggregator_test.go @@ -241,7 +241,7 @@ func TestAggregatorOneFunc(t *testing.T) { // Explicitly reinitialize the aggregator with the given output batch // size. a.(*orderedAggregator).initWithBatchSize(tc.batchSize, tc.outputBatchSize) - if err := out.Verify(); err != nil { + if err := out.VerifyAnyOrder(); err != nil { t.Fatal(err) } @@ -255,7 +255,7 @@ func TestAggregatorOneFunc(t *testing.T) { t.Fatal(err) } out := newOpTestOutput(a, []int{0}, tc.expected) - if err := out.Verify(); err != nil { + if err := out.VerifyAnyOrder(); err != nil { t.Fatal(err) } }) @@ -341,7 +341,7 @@ func TestAggregatorMultiFunc(t *testing.T) { t.Fatal(err) } out := newOpTestOutput(a, []int{0, 1}, tc.expected) - if err := out.Verify(); err != nil { + if err := out.VerifyAnyOrder(); err != nil { t.Fatal(err) } }) @@ -392,7 +392,7 @@ func TestAggregatorKitchenSink(t *testing.T) { t.Fatal(err) } out := newOpTestOutput(a, []int{0, 1, 2, 3}, tc.expected) - if err := out.Verify(); err != nil { + if err := out.VerifyAnyOrder(); err != nil { t.Fatal(err) } }) diff --git a/pkg/sql/exec/count_test.go b/pkg/sql/exec/count_test.go index 309e0bb37419..d1d35bf22c7e 100644 --- a/pkg/sql/exec/count_test.go +++ b/pkg/sql/exec/count_test.go @@ -35,7 +35,7 @@ func TestCount(t *testing.T) { count := NewCountOp(input[0]) out := newOpTestOutput(count, []int{0}, tc.expected) - if err := out.Verify(); err != nil { + if err := out.VerifyAnyOrder(); err != nil { t.Fatal(err) } }) diff --git a/pkg/sql/exec/distinct_test.go b/pkg/sql/exec/distinct_test.go index 5d9ffa2239d1..b4affbe870f2 100644 --- a/pkg/sql/exec/distinct_test.go +++ b/pkg/sql/exec/distinct_test.go @@ -58,7 +58,7 @@ func TestSortedDistinct(t *testing.T) { } out := newOpTestOutput(distinct, []int{0, 1, 2, 3}, tc.expected) - if err := out.Verify(); err != nil { + if err := out.VerifyAnyOrder(); err != nil { t.Fatal(err) } }) diff --git a/pkg/sql/exec/hashjoiner_test.go b/pkg/sql/exec/hashjoiner_test.go index 40baa18cc66b..1a7f44dfd59d 100644 --- a/pkg/sql/exec/hashjoiner_test.go +++ b/pkg/sql/exec/hashjoiner_test.go @@ -738,7 +738,7 @@ func TestHashJoinerInt64(t *testing.T) { out := newOpTestOutput(hj, cols, tc.expectedTuples) - if err := out.Verify(); err != nil { + if err := out.VerifyAnyOrder(); err != nil { t.Fatal(err) } }) diff --git a/pkg/sql/exec/limit_test.go b/pkg/sql/exec/limit_test.go index ac99eccce1a0..dd4a66531239 100644 --- a/pkg/sql/exec/limit_test.go +++ b/pkg/sql/exec/limit_test.go @@ -64,7 +64,7 @@ func TestLimit(t *testing.T) { limit := NewLimitOp(input[0], tc.limit) out := newOpTestOutput(limit, []int{0}, tc.expected) - if err := out.Verify(); err != nil { + if err := out.VerifyAnyOrder(); err != nil { t.Fatal(err) } }) diff --git a/pkg/sql/exec/offset_test.go b/pkg/sql/exec/offset_test.go index 161d68991d40..27a22e55f213 100644 --- a/pkg/sql/exec/offset_test.go +++ b/pkg/sql/exec/offset_test.go @@ -58,7 +58,7 @@ func TestOffset(t *testing.T) { s := NewOffsetOp(input[0], tc.offset) out := newOpTestOutput(s, []int{0}, tc.expected) - if err := out.Verify(); err != nil { + if err := out.VerifyAnyOrder(); err != nil { t.Fatal(err) } }) diff --git a/pkg/sql/exec/utils_test.go b/pkg/sql/exec/utils_test.go index f0a59fee27bf..0d9bf931f501 100644 --- a/pkg/sql/exec/utils_test.go +++ b/pkg/sql/exec/utils_test.go @@ -254,10 +254,27 @@ func (r *opTestOutput) next() tuple { } // Verify ensures that the input to this opTestOutput produced the same results -// as the ones expected in the opTestOutput's expected tuples, using a slow, +// and in the same order as the ones expected in the opTestOutput's expected +// tuples, using a slow, reflection-based comparison method, returning an error +// if the input isn't equal to the expected. +func (r *opTestOutput) Verify() error { + var actual tuples + for { + tup := r.next() + if tup == nil { + break + } + actual = append(actual, tup) + } + return assertTuplesOrderedEqual(r.expected, actual) +} + +// VerifyAnyOrder ensures that the input to this opTestOutput produced the same +// results but in any order (meaning set comparison behavior is used) as the +// ones expected in the opTestOutput's expected tuples, using a slow, // reflection-based comparison method, returning an error if the input isn't // equal to the expected. -func (r *opTestOutput) Verify() error { +func (r *opTestOutput) VerifyAnyOrder() error { var actual tuples for { tup := r.next() @@ -266,7 +283,7 @@ func (r *opTestOutput) Verify() error { } actual = append(actual, tup) } - return assertTuplesEquals(r.expected, actual) + return assertTuplesSetsEqual(r.expected, actual) } // tupleEquals checks that two tuples are equal, using a slow, @@ -290,8 +307,8 @@ func tupleEquals(expected tuple, actual tuple) bool { return true } -// assertTuplesEquals asserts that two sets of tuples are equal. -func assertTuplesEquals(expected tuples, actual tuples) error { +// assertTuplesSetsEqual asserts that two sets of tuples are equal. +func assertTuplesSetsEqual(expected tuples, actual tuples) error { if len(expected) != len(actual) { return errors.Errorf("expected %+v, actual %+v", expected, actual) } @@ -314,6 +331,20 @@ func assertTuplesEquals(expected tuples, actual tuples) error { return nil } +// assertTuplesOrderedEqual asserts that two permutations of tuples are equal +// in order. +func assertTuplesOrderedEqual(expected tuples, actual tuples) error { + if len(expected) != len(actual) { + return errors.Errorf("expected %+v, actual %+v", expected, actual) + } + for i := range expected { + if !tupleEquals(expected[i], actual[i]) { + return errors.Errorf("expected %+v, actual %+v\n", expected, actual) + } + } + return nil +} + // repeatableBatchSource is an Operator that returns the same batch forever. type repeatableBatchSource struct { internalBatch ColBatch