Skip to content

Commit

Permalink
add unit test. (arana-db#306)
Browse files Browse the repository at this point in the history
* Add: add Range interface mock.

* Add: add test case for iterator.

* fix: format import.

* fix: fix test case error.

* Add: add test case for shard_expr.

* Add: add license header.

* Add: add new test case.

* fix: fix import format.
  • Loading branch information
dongzl authored Jul 23, 2022
1 parent 5b141bf commit 397e304
Show file tree
Hide file tree
Showing 5 changed files with 441 additions and 0 deletions.
2 changes: 2 additions & 0 deletions pkg/config/file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import (

import (
"github.com/pkg/errors"

"github.com/tidwall/gjson"

"gopkg.in/yaml.v3"
)

Expand Down
268 changes: 268 additions & 0 deletions pkg/runtime/rule/iterator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package rule

import (
"testing"
)

import (
"github.com/golang/mock/gomock"

"github.com/stretchr/testify/assert"
)

import (
"github.com/arana-db/arana/pkg/proto/rule"
"github.com/arana-db/arana/testdata"
)

func TestFilter(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockRange := testdata.NewMockRange(ctrl)
type args struct {
src rule.Range
predicate func(interface{}) bool
}
tests := []struct {
name string
args args
want rule.Range
}{
{
"TestFilter",
args{mockRange, nil},
&filterRange{inner: mockRange, filter: nil},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, Filter(tt.args.src, tt.args.predicate), "Filter(%v, %v)", tt.args.src, tt.args.predicate)
})
}
}

func TestMultiple(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
slice := make([]interface{}, 0)
for i := 0; i < 3; i++ {
mockRange := testdata.NewMockRange(ctrl)
slice = append(slice, mockRange)
}
type args struct {
values []interface{}
}
tests := []struct {
name string
args args
want rule.Range
}{
{"TestMultiple", args{slice}, &sliceRange{0, slice}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, Multiple(tt.args.values...), "Multiple(%v)", tt.args.values...)
})
}
}

func TestSingle(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockRange := testdata.NewMockRange(ctrl)
type args struct {
value interface{}
}
tests := []struct {
name string
args args
want rule.Range
}{
{"TestSingle", args{mockRange}, &singleRange{0, mockRange}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, Single(tt.args.value), "Single(%v)", tt.args.value)
})
}
}

func Test_filterRange_HasNext(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
filter := func(interface{}) bool { return true }
mockRange := testdata.NewMockRange(ctrl)
mockRange.EXPECT().HasNext().Return(true)
mockRange.EXPECT().Next().Return(filter)
type fields struct {
inner rule.Range
filter func(next interface{}) bool
next interface{}
}
tests := []struct {
name string
fields fields
want bool
}{
{"HasNext", fields{mockRange, filter, nil}, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
f := &filterRange{
inner: tt.fields.inner,
filter: tt.fields.filter,
next: tt.fields.next,
}
assert.Equalf(t, tt.want, f.HasNext(), "HasNext()")
})
}
}

func Test_filterRange_Next(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockRange := testdata.NewMockRange(ctrl)
filter := func(interface{}) bool { return true }
type fields struct {
inner rule.Range
filter func(next interface{}) bool
next interface{}
}
tests := []struct {
name string
fields fields
want interface{}
}{
{"Next", fields{mockRange, filter, "filter_range_next"}, "filter_range_next"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
f := &filterRange{
inner: tt.fields.inner,
filter: tt.fields.filter,
next: tt.fields.next,
}
assert.Equalf(t, tt.want, f.Next(), "Next()")
})
}
}

func Test_singleRange_HasNext(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockRange := testdata.NewMockRange(ctrl)
type fields struct {
n uint8
value interface{}
}
tests := []struct {
name string
fields fields
want bool
}{
{"HasNext", fields{0, mockRange}, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &singleRange{
n: tt.fields.n,
value: tt.fields.value,
}
assert.Equalf(t, tt.want, s.HasNext(), "HasNext()")
})
}
}

func Test_singleRange_Next(t *testing.T) {
type fields struct {
n uint8
value interface{}
}
tests := []struct {
name string
fields fields
want interface{}
}{
{"Next", fields{0, "single_range_next"}, "single_range_next"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &singleRange{
n: tt.fields.n,
value: tt.fields.value,
}
assert.Equalf(t, tt.want, s.Next(), "Next()")
})
}
}

func Test_sliceRange_HasNext(t *testing.T) {
value := make([]interface{}, 0)
value = append(value, "a")
value = append(value, "b")
type fields struct {
cur int
values []interface{}
}
tests := []struct {
name string
fields fields
want bool
}{
{"HasNext_1", fields{0, value}, true},
{"HasNext_2", fields{2, value}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &sliceRange{
cur: tt.fields.cur,
values: tt.fields.values,
}
assert.Equalf(t, tt.want, s.HasNext(), "HasNext()")
})
}
}

func Test_sliceRange_Next(t *testing.T) {
value := make([]interface{}, 0)
value = append(value, "a")
value = append(value, "b")
type fields struct {
cur int
values []interface{}
}
tests := []struct {
name string
fields fields
want interface{}
}{
{"Next_1", fields{0, value}, "a"},
{"Next_2", fields{1, value}, "b"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &sliceRange{
cur: tt.fields.cur,
values: tt.fields.values,
}
assert.Equalf(t, tt.want, s.Next(), "Next()")
})
}
}
119 changes: 119 additions & 0 deletions pkg/runtime/rule/shard_expr_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package rule

import (
"fmt"
"testing"
)

import (
"github.com/stretchr/testify/assert"
)

import (
"github.com/arana-db/arana/pkg/proto/rule"
)

func TestNewExprShardComputer(t *testing.T) {
type args struct {
expr string
column string
}
tests := []struct {
name string
args args
want rule.ShardComputer
wantErr assert.ErrorAssertionFunc
}{
{
"NewExprShardComputer",
args{"hash(toint(substr(#uid#, 1, 2)), 100)", "uid"},
&exprShardComputer{"hash(toint(substr(#uid#, 1, 2)), 100)", "uid"},
assert.NoError,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NewExprShardComputer(tt.args.expr, tt.args.column)
if !tt.wantErr(t, err, fmt.Sprintf("NewExprShardComputer(%v, %v)", tt.args.expr, tt.args.column)) {
return
}
assert.Equalf(t, tt.want, got, "NewExprShardComputer(%v, %v)", tt.args.expr, tt.args.column)
})
}
}

func Test_exprShardComputer_Compute(t *testing.T) {
type fields struct {
expr string
column string
}
type args struct {
value interface{}
}
tests := []struct {
name string
fields fields
args args
want int
wantErr assert.ErrorAssertionFunc
}{
{
"Compute_1",
fields{"hash(toint(substr(#uid#, 1, 2)), 100)", "uid"},
args{87616},
87,
assert.NoError,
},
{
"Compute_2",
fields{"hash(concat(#uid#, '1'), 100)", "uid"},
args{87616},
61,
assert.NoError,
},
{
"Compute_3",
fields{"hash(concat(#uid#, '1'), 100)", "name"},
args{87616},
0,
assert.Error,
},
{
"Compute_4",
fields{"hash(concat(#uid#, '1'), 100)", "uid"},
args{"a"},
0,
assert.Error,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
compute := &exprShardComputer{
expr: tt.fields.expr,
column: tt.fields.column,
}
got, err := compute.Compute(tt.args.value)
if !tt.wantErr(t, err, fmt.Sprintf("Compute(%v)", tt.args.value)) {
return
}
assert.Equalf(t, tt.want, got, "Compute(%v)", tt.args.value)
})
}
}
Loading

0 comments on commit 397e304

Please sign in to comment.