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