github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/colexec/top/top_test.go (about) 1 // Copyright 2021 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package top 16 17 import ( 18 "bytes" 19 "testing" 20 21 "github.com/matrixorigin/matrixone/pkg/common/mpool" 22 "github.com/matrixorigin/matrixone/pkg/container/batch" 23 "github.com/matrixorigin/matrixone/pkg/container/types" 24 "github.com/matrixorigin/matrixone/pkg/pb/plan" 25 "github.com/matrixorigin/matrixone/pkg/sql/colexec/value_scan" 26 "github.com/matrixorigin/matrixone/pkg/testutil" 27 "github.com/matrixorigin/matrixone/pkg/vm" 28 "github.com/matrixorigin/matrixone/pkg/vm/process" 29 "github.com/stretchr/testify/require" 30 ) 31 32 const ( 33 Rows = 10 // default rows 34 BenchmarkRows = 100000 // default rows for benchmark 35 ) 36 37 // add unit tests for cases 38 type topTestCase struct { 39 arg *Argument 40 types []types.Type 41 proc *process.Process 42 } 43 44 var ( 45 tcs []topTestCase 46 ) 47 48 func init() { 49 tcs = []topTestCase{ 50 newTestCase(mpool.MustNewZero(), []types.Type{types.T_int8.ToType()}, 3, []*plan.OrderBySpec{{Expr: newExpression(0), Flag: 0}}), 51 newTestCase(mpool.MustNewZero(), []types.Type{types.T_int8.ToType()}, 3, []*plan.OrderBySpec{{Expr: newExpression(0), Flag: 2}}), 52 newTestCase(mpool.MustNewZero(), []types.Type{types.T_int8.ToType(), types.T_int64.ToType()}, 3, []*plan.OrderBySpec{{Expr: newExpression(0), Flag: 2}, {Expr: newExpression(1), Flag: 0}}), 53 } 54 } 55 56 func TestString(t *testing.T) { 57 buf := new(bytes.Buffer) 58 for _, tc := range tcs { 59 tc.arg.String(buf) 60 } 61 } 62 63 func TestPrepare(t *testing.T) { 64 for _, tc := range tcs { 65 err := tc.arg.Prepare(tc.proc) 66 require.NoError(t, err) 67 } 68 } 69 70 func TestTop(t *testing.T) { 71 for _, tc := range tcs { 72 err := tc.arg.Prepare(tc.proc) 73 require.NoError(t, err) 74 75 bats := []*batch.Batch{ 76 newBatch(tc.types, tc.proc, Rows), 77 newBatch(tc.types, tc.proc, Rows), 78 batch.EmptyBatch, 79 } 80 resetChildren(tc.arg, bats) 81 _, _ = tc.arg.Call(tc.proc) 82 tc.proc.FreeVectors() 83 tc.arg.Free(tc.proc, false, nil) 84 tc.arg.GetChildren(0).Free(tc.proc, false, nil) 85 require.Equal(t, int64(0), tc.proc.Mp().CurrNB()) 86 } 87 } 88 89 func BenchmarkTop(b *testing.B) { 90 for i := 0; i < b.N; i++ { 91 tcs = []topTestCase{ 92 newTestCase(mpool.MustNewZero(), []types.Type{types.T_int8.ToType()}, 3, []*plan.OrderBySpec{{Expr: newExpression(0), Flag: 0}}), 93 newTestCase(mpool.MustNewZero(), []types.Type{types.T_int8.ToType()}, 3, []*plan.OrderBySpec{{Expr: newExpression(0), Flag: 2}}), 94 } 95 t := new(testing.T) 96 for _, tc := range tcs { 97 err := tc.arg.Prepare(tc.proc) 98 require.NoError(t, err) 99 100 bats := []*batch.Batch{ 101 newBatch(tc.types, tc.proc, BenchmarkRows), 102 newBatch(tc.types, tc.proc, BenchmarkRows), 103 batch.EmptyBatch, 104 } 105 resetChildren(tc.arg, bats) 106 _, _ = tc.arg.Call(tc.proc) 107 tc.arg.Free(tc.proc, false, nil) 108 tc.arg.GetChildren(0).Free(tc.proc, false, nil) 109 } 110 } 111 } 112 113 func newTestCase(m *mpool.MPool, ts []types.Type, limit int64, fs []*plan.OrderBySpec) topTestCase { 114 return topTestCase{ 115 types: ts, 116 proc: testutil.NewProcessWithMPool(m), 117 arg: &Argument{ 118 Fs: fs, 119 Limit: limit, 120 OperatorBase: vm.OperatorBase{ 121 OperatorInfo: vm.OperatorInfo{ 122 Idx: 0, 123 IsFirst: false, 124 IsLast: false, 125 }, 126 }, 127 }, 128 } 129 } 130 131 func newExpression(pos int32) *plan.Expr { 132 return &plan.Expr{ 133 Expr: &plan.Expr_Col{ 134 Col: &plan.ColRef{ 135 ColPos: pos, 136 }, 137 }, 138 Typ: plan.Type{}, 139 } 140 } 141 142 // create a new block based on the type information 143 func newBatch(ts []types.Type, proc *process.Process, rows int64) *batch.Batch { 144 return testutil.NewBatch(ts, false, int(rows), proc.Mp()) 145 } 146 147 func resetChildren(arg *Argument, bats []*batch.Batch) { 148 arg.SetChildren( 149 []vm.Operator{ 150 &value_scan.Argument{ 151 Batchs: bats, 152 }, 153 }) 154 }