Add permits index test#3735
Conversation
| opts := DefaultTestOptions() | ||
| opts = opts.SetClockOptions(opts.ClockOptions().SetNowFn(nowFn)) | ||
|
|
||
| permitOpts := opts.PermitsOptions() |
There was a problem hiding this comment.
Hm, instead of adding this purely to an existing test. Could we refactor this test to just have the setup and teardown pieces extracted into helper methods?
i.e.
func TestNamespaceIndexBlockQuery(t *testing.T) {
ctrl := xtest.NewController(t)
defer ctrl.Finish()
test := newNamespaceIndexBlockQueryTest(t, ctrl)
for _, testCase := range []struct {
name string
requireExhaustive bool
}{
{"allow non-exhaustive", false},
{"require exhaustive", true},
} {
t.Run(testCase.name, func(t *testing.T) {
test.run(namespaceIndexBlockQueryTestOptions{
requireExhaustive: testCase.requireExhaustive,
})
})
}
}
func TestNamespaceIndexBlockQueryWithPermits(t *testing.T) {
ctrl := xtest.NewController(t)
defer ctrl.Finish()
test := newNamespaceIndexBlockQueryTest(t, ctrl)
// Add permits related code here
for _, testCase := range []struct {
name string
requireExhaustive bool
}{
{"allow non-exhaustive", false},
{"require exhaustive", true},
} {
t.Run(testCase.name, func(t *testing.T) {
test.run(t, namespaceIndexBlockQueryTestOptions{
requireExhaustive: testCase.requireExhaustive,
})
})
}
}
type namespaceIndexBlockQueryTest struct {
// things that are returned during a common setup method
}
func newNamespaceIndexBlockQueryTest(t *testing.T, ctrl *gomock.Controller) namespaceIndexBlockQueryTest {
// do things and setup common used mocks like mock blocks, segment, results, etc
return namespaceIndexBlockQueryTest{ /* things used by test */ }
}
type namespaceIndexBlockQueryTestOptions struct {
requireExhaustive bool
}
func (test namespaceIndexBlockQueryTest) run(t *testing.T, opts namespaceIndexBlockQueryTestOptions) {
// only queries as much as is needed (wrt to time)
ctx := context.NewBackground()
q := defaultQuery
qOpts := index.QueryOptions{
StartInclusive: t0,
EndExclusive: now.Add(time.Minute),
}
// Lock to prevent race given these blocks are processed concurrently.
var resultLock sync.Mutex
// create initial span from a mock tracer and get ctx
mtr := mocktracer.New()
sp := mtr.StartSpan("root")
ctx.SetGoContext(opentracing.ContextWithSpan(stdlibctx.Background(), sp))
mockIterActive := index.NewMockQueryIterator(ctrl)
mockIter0 := index.NewMockQueryIterator(ctrl)
bActive.EXPECT().QueryIter(gomock.Any(), q).Return(mockIterActive, nil)
mockIterActive.EXPECT().Done().Return(true)
mockIterActive.EXPECT().Close().Return(nil)
b0.EXPECT().QueryIter(gomock.Any(), q).Return(mockIter0, nil)
mockIter0.EXPECT().Done().Return(true)
mockIter0.EXPECT().Close().Return(nil)
result, err := idx.Query(ctx, q, qOpts)
require.NoError(t, err)
require.True(t, result.Exhaustive)
// queries multiple blocks if needed
qOpts = index.QueryOptions{
StartInclusive: t0,
EndExclusive: t2.Add(time.Minute),
RequireExhaustive: test.requireExhaustive,
}
bActive.EXPECT().QueryIter(gomock.Any(), q).Return(mockIterActive, nil)
mockIterActive.EXPECT().Done().Return(true)
mockIterActive.EXPECT().Close().Return(nil)
b0.EXPECT().QueryIter(gomock.Any(), q).Return(mockIter0, nil)
mockIter0.EXPECT().Done().Return(true)
mockIter0.EXPECT().Close().Return(nil)
mockIter1 := index.NewMockQueryIterator(ctrl)
b1.EXPECT().QueryIter(gomock.Any(), q).Return(mockIter1, nil)
mockIter1.EXPECT().Done().Return(true)
mockIter1.EXPECT().Close().Return(nil)
result, err = idx.Query(ctx, q, qOpts)
require.NoError(t, err)
require.True(t, result.Exhaustive)
// stops querying once a block returns non-exhaustive
qOpts = index.QueryOptions{
StartInclusive: t0,
EndExclusive: t0.Add(time.Minute),
RequireExhaustive: test.requireExhaustive,
SeriesLimit: 1,
}
docs := []doc.Document{
doc.NewDocumentFromMetadata(doc.Metadata{ID: []byte("A")}),
doc.NewDocumentFromMetadata(doc.Metadata{ID: []byte("B")}),
}
mockQueryWithIter(t, mockIterActive, bActive, q, qOpts, &resultLock, docs)
mockQueryWithIter(t, mockIter0, b0, q, qOpts, &resultLock, docs)
result, err = idx.Query(ctx, q, qOpts)
if test.requireExhaustive {
require.Error(t, err)
require.False(t, xerrors.IsRetryableError(err))
} else {
require.NoError(t, err)
require.False(t, result.Exhaustive)
}
sp.Finish()
spans := mtr.FinishedSpans()
require.Len(t, spans, 9)
}| "testing" | ||
| "time" | ||
|
|
||
| "github.com/m3db/m3/src/dbnode/storage/limits/permits" |
There was a problem hiding this comment.
These imports need fixing up yeah? 1. stdlib 2. external imports 3. internal imports I believe these days?
robskillington
left a comment
There was a problem hiding this comment.
LGTM other than comment about refactoring the test into two pieces
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3735 +/- ##
========================================
- Coverage 57.0% 56.9% -0.2%
========================================
Files 552 552
Lines 62933 62933
========================================
- Hits 35908 35834 -74
- Misses 23832 23908 +76
+ Partials 3193 3191 -2
Flags with carried forward coverage won't be shown. Click here to find out more. Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
What this PR does / why we need it:
Adds test to the permits in index path.
Special notes for your reviewer:
Does this PR introduce a user-facing and/or backwards incompatible change?:
Does this PR require updating code package or user-facing documentation?: