Skip to content

Commit

Permalink
[enhance:#1021]: add more test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
joyant committed Apr 30, 2024
1 parent 919f3a4 commit cd28e60
Show file tree
Hide file tree
Showing 8 changed files with 311 additions and 52 deletions.
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ header: ## check and add license header.
import: ## opt go imports format.
sh scripts/imports.sh

format: ## go format
format: ## go format
go fmt ./...

lint: ## run lint
Expand Down Expand Up @@ -104,7 +104,10 @@ gen-sql-grammar: ## generate lin query language gen-sql-grammar
antlr4 -Dlanguage=Go -listener -visitor -package grammar ./sql/grammar/SQL.g4

key-words: ## print all key words for lin query language
go run github.com/lindb/lindb/cmd/tools keywords
go run github.com/lindb/lindb/cmd/tools keywords

html: ## convert coverage.out to html
go tool cover -html=coverage.out -o coverage.html

clean-mock: ## remove all mock files
find ./ -name "*_mock.go" | xargs rm
Expand Down
12 changes: 7 additions & 5 deletions index/metric_index_segment.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type metricIndexSegment struct {
dir string
metaDB MetricMetaDatabase
indices map[int]MetricIndexDatabase
lock sync.Mutex
lock sync.RWMutex
}

// NewMetricIndexSegment creates a metric index segment store.
Expand All @@ -61,7 +61,7 @@ func NewMetricIndexSegment(dir string, metaDB MetricMetaDatabase) (segment Metri
continue
}
segment := t.Year()*100 + int(t.Month())
database, err0 := NewMetricIndexDatabase(path.Join(dir, d), metaDB)
database, err0 := newIndexDBFunc(path.Join(dir, d), metaDB)
if err0 != nil {
return nil, err0
}
Expand Down Expand Up @@ -224,18 +224,20 @@ func (m *metricIndexSegment) GetGroupingContext(ctx *flow.ShardExecuteContext) e
// GetOrCreateIndex returns MetricIndexDatabase as familyTime
func (m *metricIndexSegment) GetOrCreateIndex(familyTime int64) (MetricIndexDatabase, error) {
segment := timeutil.GetSegment(familyTime)
m.lock.RLock()
index, ok := m.indices[segment]
m.lock.RUnlock()
if ok {
return index, nil
}

m.lock.Lock()
defer m.lock.Unlock()

index, ok = m.indices[segment]
if ok {
m.lock.Unlock()
return index, nil
}
defer m.lock.Unlock()

index, err := newIndexDBFunc(path.Join(m.dir, strconv.Itoa(segment)), m.metaDB)
if err != nil {
return nil, err
Expand Down
211 changes: 206 additions & 5 deletions index/metric_index_segment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@
package index

import (
"fmt"

"github.com/lindb/common/pkg/fileutil"
"github.com/lindb/roaring"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"

"github.com/lindb/lindb/flow"
"github.com/lindb/lindb/pkg/timeutil"
"github.com/lindb/lindb/series/metric"
"github.com/lindb/lindb/series/tag"
"github.com/lindb/lindb/sql/stmt"

"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"

"fmt"
"os"
"path"
"strconv"
"sync"
"testing"
"time"
)
Expand Down Expand Up @@ -281,6 +281,7 @@ func TestMetricIndexSegment_Flush_err(t *testing.T) {
})
_, err = indexSegment.GetOrCreateIndex(time.Now().UnixMilli())
assert.NoError(t, err)
indexSegment.PrepareFlush()
assert.Error(t, indexSegment.Flush())
}

Expand All @@ -300,6 +301,7 @@ func TestMetricIndexSegment_Flush(t *testing.T) {
metaDB := NewMockMetricMetaDatabase(ctrl)
indexSegment, err := NewMetricIndexSegment(name, metaDB)
assert.NoError(t, err)
assert.NoError(t, indexSegment.Flush())
indexDB.EXPECT().Notify(gomock.Any()).Do(func(n Notifier) {
mn := n.(*FlushNotifier)
mn.Callback(nil)
Expand All @@ -325,6 +327,7 @@ func TestMetricIndexSegment_Close_err(t *testing.T) {
metaDB := NewMockMetricMetaDatabase(ctrl)
indexSegment, err := NewMetricIndexSegment(name, metaDB)
assert.NoError(t, err)
assert.NoError(t, indexSegment.Close())
indexDB.EXPECT().Close().Return(fmt.Errorf("err"))
_, err = indexSegment.GetOrCreateIndex(time.Now().UnixMilli())
assert.NoError(t, err)
Expand Down Expand Up @@ -370,3 +373,201 @@ func TestMetricIndexSegment_getSegment(t *testing.T) {
assert.Equal(t, start, gotStart)
assert.Equal(t, end, gotEnd)
}

func TestMetricIndexSegment_NewMetricIndexSegment(t *testing.T) {
ctrl := gomock.NewController(t)
defer func() {
mkDirFunc = fileutil.MkDirIfNotExist
getDirectoryListFunc = fileutil.GetDirectoryList
newIndexDBFunc = NewMetricIndexDatabase
ctrl.Finish()
}()

cases := []struct {
name string
prepare func()
wantErr bool
}{
{
name: "mkDirFunc error",
prepare: func() {
mkDirFunc = func(path string) error {
return fmt.Errorf("err")
}
},
wantErr: true,
},
{
name: "getDirectoryListFunc error",
prepare: func() {
getDirectoryListFunc = func(path string) ([]string, error) {
return nil, fmt.Errorf("err")
}
},
wantErr: true,
},
{
name: "newIndexDBFunc error",
prepare: func() {
mkDirFunc = func(path string) error {
return nil
}
getDirectoryListFunc = func(path string) ([]string, error) {
return []string{"test", "202401"}, nil
}
newIndexDBFunc = func(dir string, metaDB MetricMetaDatabase) (MetricIndexDatabase, error) {
return nil, fmt.Errorf("err")
}
},
wantErr: true,
},
}

for i := range cases {
c := cases[i]
t.Run(c.name, func(t *testing.T) {
c.prepare()
_, err := NewMetricIndexSegment("test", nil)
if (err != nil) != c.wantErr {
t.Fatal(c.name)
}
})
}
}

func TestMetricIndexSegment_GetSeriesIDsByTagValueIDs_err(t *testing.T) {
ctrl := gomock.NewController(t)
defer func() {
ctrl.Finish()
}()

indexDB := NewMockMetricIndexDatabase(ctrl)
segment := 202401
indexSegment := &metricIndexSegment{
indices: map[int]MetricIndexDatabase{segment: indexDB},
}
tm, err := time.Parse("200601", strconv.Itoa(segment))
assert.NoError(t, err)
timeRange := timeutil.TimeRange{Start: tm.UnixMilli(), End: tm.UnixMilli()}
doAndReturn := func(tagKeyID tag.KeyID, tagValueIDs *roaring.Bitmap) (*roaring.Bitmap, error) {
return nil, fmt.Errorf("err")
}
indexDB.EXPECT().GetSeriesIDsByTagValueIDs(gomock.Any(), gomock.Any()).DoAndReturn(doAndReturn)
_, err = indexSegment.GetSeriesIDsByTagValueIDs(0, nil, timeRange)
assert.Error(t, err)
}

func TestMetricIndexSegment_GetSeriesIDsForTag_err(t *testing.T) {
ctrl := gomock.NewController(t)
defer func() {
ctrl.Finish()
}()

indexDB := NewMockMetricIndexDatabase(ctrl)
segment := 202401
indexSegment := &metricIndexSegment{
indices: map[int]MetricIndexDatabase{segment: indexDB},
}
tm, err := time.Parse("200601", strconv.Itoa(segment))
assert.NoError(t, err)
timeRange := timeutil.TimeRange{Start: tm.UnixMilli(), End: tm.UnixMilli()}
doAndReturn := func(tagKeyID tag.KeyID) (*roaring.Bitmap, error) {
return nil, fmt.Errorf("err")
}
indexDB.EXPECT().GetSeriesIDsForTag(gomock.Any()).DoAndReturn(doAndReturn)
_, err = indexSegment.GetSeriesIDsForTag(0, timeRange)
assert.Error(t, err)
}

func TestMetricIndexSegment_GetSeriesIDsForMetric_err(t *testing.T) {
ctrl := gomock.NewController(t)
defer func() {
ctrl.Finish()
}()

indexDB := NewMockMetricIndexDatabase(ctrl)
segment := 202401
indexSegment := &metricIndexSegment{
indices: map[int]MetricIndexDatabase{segment: indexDB},
}
tm, err := time.Parse("200601", strconv.Itoa(segment))
assert.NoError(t, err)
timeRange := timeutil.TimeRange{Start: tm.UnixMilli(), End: tm.UnixMilli()}
doAndReturn := func(_ metric.ID) (*roaring.Bitmap, error) {
return nil, fmt.Errorf("err")
}
indexDB.EXPECT().GetSeriesIDsForMetric(gomock.Any()).DoAndReturn(doAndReturn)
_, err = indexSegment.GetSeriesIDsForMetric(0, timeRange)
assert.Error(t, err)
}

func TestMetricIndexSegment_GetGroupingContext_err(t *testing.T) {
ctrl := gomock.NewController(t)
defer func() {
ctrl.Finish()
}()

indexDB := NewMockMetricIndexDatabase(ctrl)
segment := 202401
indexSegment := &metricIndexSegment{
indices: map[int]MetricIndexDatabase{segment: indexDB},
}
tm, err := time.Parse("200601", strconv.Itoa(segment))
assert.NoError(t, err)
timeRange := timeutil.TimeRange{Start: tm.UnixMilli(), End: tm.UnixMilli()}
ctx := &flow.ShardExecuteContext{
StorageExecuteCtx: &flow.StorageExecuteContext{
Query: &stmt.Query{
TimeRange: timeRange,
},
},
}
doAndReturn := func(_ *flow.ShardExecuteContext) (*roaring.Bitmap, error) {
return nil, fmt.Errorf("err")
}
indexDB.EXPECT().GetGroupingContext(gomock.Any()).DoAndReturn(doAndReturn)
err = indexSegment.GetGroupingContext(ctx)
assert.NoError(t, err)
}

func TestMetricIndexSegment_GetOrCreateIndex_err(t *testing.T) {
ctrl := gomock.NewController(t)
defer func() {
newIndexDBFunc = NewMetricIndexDatabase
ctrl.Finish()
}()

indexDB := NewMockMetricIndexDatabase(ctrl)
var segment = 202401
tm, err := time.Parse("200601", strconv.Itoa(segment))
assert.NoError(t, err)
familyTime := tm.UnixMilli()

indexSegment := &metricIndexSegment{
indices: map[int]MetricIndexDatabase{},
}

newIndexDBFunc = func(dir string, metaDB MetricMetaDatabase) (MetricIndexDatabase, error) {
return indexDB, nil
}
n := 10
g := sync.WaitGroup{}
g.Add(n)
for i := 0; i < n; i++ {
go func() {
defer g.Done()
db, err0 := indexSegment.GetOrCreateIndex(familyTime)
assert.NoError(t, err0)
assert.Equal(t, db, indexDB)
}()
}
g.Wait()

newIndexDBFunc = func(dir string, metaDB MetricMetaDatabase) (MetricIndexDatabase, error) {
return nil, fmt.Errorf("err")
}
clear(indexSegment.indices)
db, err := indexSegment.GetOrCreateIndex(familyTime)
assert.Error(t, err)
assert.Nil(t, db)
}
Loading

0 comments on commit cd28e60

Please sign in to comment.