1
0
mirror of https://github.com/rancher/steve.git synced 2025-07-12 22:28:40 +00:00
steve/pkg/sqlcache/informer/indexer_test.go
Silvio Moioli 3350323f91
sql: propagate and use contexts (#465)
Previous SQLite-related code used context.Background() and context.TODO() because it was not developed with context awareness.

This commit propagates the main Steve context so that it can be used when interacting with SQL context-aware functions.

This PR removes all production-code use of context.Background() and context.TODO() and replaces test-code use of TODO with Background.

Contributes to rancher/rancher#47825
2025-02-12 09:46:10 +01:00

657 lines
25 KiB
Go

/*
Copyright 2023 SUSE LLC
Adapted from client-go, Copyright 2014 The Kubernetes Authors.
*/
package informer
import (
"context"
"database/sql"
"fmt"
"reflect"
"testing"
"github.com/rancher/steve/pkg/sqlcache/db"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
"k8s.io/client-go/tools/cache"
)
//go:generate mockgen --build_flags=--mod=mod -package informer -destination ./sql_mocks_test.go github.com/rancher/steve/pkg/sqlcache/informer Store
//go:generate mockgen --build_flags=--mod=mod -package informer -destination ./db_mocks_test.go github.com/rancher/steve/pkg/sqlcache/db Rows,Client
//go:generate mockgen --build_flags=--mod=mod -package informer -destination ./transaction_mocks_test.go -mock_names Client=MockTXClient github.com/rancher/steve/pkg/sqlcache/db/transaction Stmt,Client
type testStoreObject struct {
Id string
Val string
}
func TestNewIndexer(t *testing.T) {
type testCase struct {
description string
test func(t *testing.T)
}
var tests []testCase
tests = append(tests, testCase{description: "NewIndexer() with no errors returned from Store or Client, should return no error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
client := NewMockTXClient(gomock.NewController(t))
objKey := "objKey"
indexers := map[string]cache.IndexFunc{
"a": func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
}
storeName := "someStoreName"
store.EXPECT().GetName().AnyTimes().Return(storeName)
client.EXPECT().Exec(fmt.Sprintf(createTableFmt, storeName, storeName)).Return(nil, nil)
client.EXPECT().Exec(fmt.Sprintf(createIndexFmt, storeName, storeName)).Return(nil, nil)
store.EXPECT().WithTransaction(gomock.Any(), true, gomock.Any()).Return(nil).Do(
func(ctx context.Context, shouldEncrypt bool, f db.WithTransactionFunction) {
err := f(client)
if err != nil {
t.Fail()
}
})
store.EXPECT().RegisterAfterUpsert(gomock.Any())
store.EXPECT().Prepare(fmt.Sprintf(deleteIndicesFmt, storeName))
store.EXPECT().Prepare(fmt.Sprintf(addIndexFmt, storeName))
store.EXPECT().Prepare(fmt.Sprintf(listByIndexFmt, storeName, storeName))
store.EXPECT().Prepare(fmt.Sprintf(listKeyByIndexFmt, storeName))
store.EXPECT().Prepare(fmt.Sprintf(listIndexValuesFmt, storeName))
indexer, err := NewIndexer(context.Background(), indexers, store)
assert.Nil(t, err)
assert.Equal(t, cache.Indexers(indexers), indexer.indexers)
}})
tests = append(tests, testCase{description: "NewIndexer() with WithTransaction() error, should return error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
objKey := "objKey"
indexers := map[string]cache.IndexFunc{
"a": func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
}
store.EXPECT().GetName().AnyTimes().Return("someStoreName")
store.EXPECT().WithTransaction(gomock.Any(), true, gomock.Any()).Return(fmt.Errorf("error"))
_, err := NewIndexer(context.Background(), indexers, store)
assert.NotNil(t, err)
}})
tests = append(tests, testCase{description: "NewIndexer() with Client Exec() error on first call to Exec(), should return error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
client := NewMockTXClient(gomock.NewController(t))
objKey := "objKey"
indexers := map[string]cache.IndexFunc{
"a": func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
}
storeName := "someStoreName"
store.EXPECT().GetName().AnyTimes().Return(storeName)
client.EXPECT().Exec(fmt.Sprintf(createTableFmt, storeName, storeName)).Return(nil, fmt.Errorf("error"))
store.EXPECT().WithTransaction(gomock.Any(), true, gomock.Any()).Return(fmt.Errorf("error")).Do(
func(ctx context.Context, shouldEncrypt bool, f db.WithTransactionFunction) {
err := f(client)
if err == nil {
t.Fail()
}
})
_, err := NewIndexer(context.Background(), indexers, store)
assert.NotNil(t, err)
}})
tests = append(tests, testCase{description: "NewIndexer() with Client Exec() error on second call to Exec(), should return error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
client := NewMockTXClient(gomock.NewController(t))
objKey := "objKey"
indexers := map[string]cache.IndexFunc{
"a": func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
}
storeName := "someStoreName"
store.EXPECT().GetName().AnyTimes().Return(storeName)
client.EXPECT().Exec(fmt.Sprintf(createTableFmt, storeName, storeName)).Return(nil, nil)
client.EXPECT().Exec(fmt.Sprintf(createIndexFmt, storeName, storeName)).Return(nil, fmt.Errorf("error"))
store.EXPECT().WithTransaction(gomock.Any(), true, gomock.Any()).Return(fmt.Errorf("error")).Do(
func(ctx context.Context, shouldEncrypt bool, f db.WithTransactionFunction) {
err := f(client)
if err == nil {
t.Fail()
}
})
_, err := NewIndexer(context.Background(), indexers, store)
assert.NotNil(t, err)
}})
tests = append(tests, testCase{description: "NewIndexer() with Client Commit() error, should return error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
client := NewMockTXClient(gomock.NewController(t))
objKey := "objKey"
indexers := map[string]cache.IndexFunc{
"a": func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
}
storeName := "someStoreName"
store.EXPECT().GetName().AnyTimes().Return(storeName)
client.EXPECT().Exec(fmt.Sprintf(createTableFmt, storeName, storeName)).Return(nil, nil)
client.EXPECT().Exec(fmt.Sprintf(createIndexFmt, storeName, storeName)).Return(nil, nil)
store.EXPECT().WithTransaction(gomock.Any(), true, gomock.Any()).Return(fmt.Errorf("error")).Do(
func(ctx context.Context, shouldEncrypt bool, f db.WithTransactionFunction) {
err := f(client)
if err != nil {
t.Fail()
}
})
_, err := NewIndexer(context.Background(), indexers, store)
assert.NotNil(t, err)
}})
t.Parallel()
for _, test := range tests {
t.Run(test.description, func(t *testing.T) { test.test(t) })
}
}
func TestAfterUpsert(t *testing.T) {
type testCase struct {
description string
test func(t *testing.T)
}
var tests []testCase
tests = append(tests, testCase{description: "AfterUpsert() with no errors returned from Client should return no error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
client := NewMockTXClient(gomock.NewController(t))
objKey := "key"
deleteIndicesStmt := NewMockStmt(gomock.NewController(t))
addIndexStmt := NewMockStmt(gomock.NewController(t))
indexer := &Indexer{
ctx: context.Background(),
Store: store,
indexers: map[string]cache.IndexFunc{
"a": func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
},
}
key := "somekey"
client.EXPECT().Stmt(indexer.deleteIndicesStmt).Return(deleteIndicesStmt)
deleteIndicesStmt.EXPECT().Exec(key).Return(nil, nil)
client.EXPECT().Stmt(indexer.addIndexStmt).Return(addIndexStmt)
addIndexStmt.EXPECT().Exec("a", objKey, key).Return(nil, nil)
testObject := testStoreObject{Id: "something", Val: "a"}
err := indexer.AfterUpsert(key, testObject, client)
assert.Nil(t, err)
}})
tests = append(tests, testCase{description: "AfterUpsert() with error returned from Client StmtExec() should return an error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
client := NewMockTXClient(gomock.NewController(t))
objKey := "key"
deleteIndicesStmt := NewMockStmt(gomock.NewController(t))
indexer := &Indexer{
ctx: context.Background(),
Store: store,
indexers: map[string]cache.IndexFunc{
"a": func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
},
}
key := "somekey"
client.EXPECT().Stmt(indexer.deleteIndicesStmt).Return(deleteIndicesStmt)
deleteIndicesStmt.EXPECT().Exec(key).Return(nil, fmt.Errorf("error"))
testObject := testStoreObject{Id: "something", Val: "a"}
err := indexer.AfterUpsert(key, testObject, client)
assert.NotNil(t, err)
}})
tests = append(tests, testCase{description: "AfterUpsert() with error returned from Client second StmtExec() call should return an error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
client := NewMockTXClient(gomock.NewController(t))
deleteIndicesStmt := NewMockStmt(gomock.NewController(t))
addIndexStmt := NewMockStmt(gomock.NewController(t))
objKey := "key"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
indexers: map[string]cache.IndexFunc{
"a": func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
},
}
key := "somekey"
client.EXPECT().Stmt(indexer.deleteIndicesStmt).Return(deleteIndicesStmt)
deleteIndicesStmt.EXPECT().Exec(key).Return(nil, nil)
client.EXPECT().Stmt(indexer.addIndexStmt).Return(addIndexStmt)
addIndexStmt.EXPECT().Exec("a", objKey, key).Return(nil, fmt.Errorf("error"))
testObject := testStoreObject{Id: "something", Val: "a"}
err := indexer.AfterUpsert(key, testObject, client)
assert.NotNil(t, err)
}})
t.Parallel()
for _, test := range tests {
t.Run(test.description, func(t *testing.T) { test.test(t) })
}
}
func TestIndex(t *testing.T) {
type testCase struct {
description string
test func(t *testing.T)
}
var tests []testCase
tests = append(tests, testCase{description: "Index() with no errors returned from store and 1 object returned by ReadObjects(), should return one obj and no error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
rows := &sql.Rows{}
listStmt := &sql.Stmt{}
objKey := "key"
indexName := "someindexname"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
listByIndexStmt: listStmt,
indexers: map[string]cache.IndexFunc{
indexName: func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
},
}
testObject := testStoreObject{Id: "something", Val: "a"}
store.EXPECT().QueryForRows(context.Background(), indexer.listByIndexStmt, indexName, objKey).Return(rows, nil)
store.EXPECT().GetType().Return(reflect.TypeOf(testObject))
store.EXPECT().GetShouldEncrypt().Return(false)
store.EXPECT().ReadObjects(rows, reflect.TypeOf(testObject), false).Return([]any{testObject}, nil)
objs, err := indexer.Index(indexName, testObject)
assert.Nil(t, err)
assert.Equal(t, []any{testObject}, objs)
}})
tests = append(tests, testCase{description: "Index() with no errors returned from store and multiple objects returned by ReadObjects(), should return multiple objects and no error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
rows := &sql.Rows{}
listStmt := &sql.Stmt{}
objKey := "key"
indexName := "someindexname"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
listByIndexStmt: listStmt,
indexers: map[string]cache.IndexFunc{
indexName: func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
},
}
testObject := testStoreObject{Id: "something", Val: "a"}
store.EXPECT().QueryForRows(context.Background(), indexer.listByIndexStmt, indexName, objKey).Return(rows, nil)
store.EXPECT().GetType().Return(reflect.TypeOf(testObject))
store.EXPECT().GetShouldEncrypt().Return(false)
store.EXPECT().ReadObjects(rows, reflect.TypeOf(testObject), false).Return([]any{testObject, testObject}, nil)
objs, err := indexer.Index(indexName, testObject)
assert.Nil(t, err)
assert.Equal(t, []any{testObject, testObject}, objs)
}})
tests = append(tests, testCase{description: "Index() with no errors returned from store and no objects returned by ReadObjects(), should return no objects and no error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
rows := &sql.Rows{}
listStmt := &sql.Stmt{}
objKey := "key"
indexName := "someindexname"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
listByIndexStmt: listStmt,
indexers: map[string]cache.IndexFunc{
indexName: func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
},
}
testObject := testStoreObject{Id: "something", Val: "a"}
store.EXPECT().QueryForRows(context.Background(), indexer.listByIndexStmt, indexName, objKey).Return(rows, nil)
store.EXPECT().GetType().Return(reflect.TypeOf(testObject))
store.EXPECT().GetShouldEncrypt().Return(false)
store.EXPECT().ReadObjects(rows, reflect.TypeOf(testObject), false).Return([]any{}, nil)
objs, err := indexer.Index(indexName, testObject)
assert.Nil(t, err)
assert.Equal(t, []any{}, objs)
}})
tests = append(tests, testCase{description: "Index() where index name is not in indexers, should return error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
listStmt := &sql.Stmt{}
objKey := "key"
indexName := "someindexname"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
listByIndexStmt: listStmt,
indexers: map[string]cache.IndexFunc{
indexName: func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
},
}
testObject := testStoreObject{Id: "something", Val: "a"}
_, err := indexer.Index("someotherindexname", testObject)
assert.NotNil(t, err)
}})
tests = append(tests, testCase{description: "Index() with an error returned from store QueryForRows, should return an error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
listStmt := &sql.Stmt{}
objKey := "key"
indexName := "someindexname"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
listByIndexStmt: listStmt,
indexers: map[string]cache.IndexFunc{
indexName: func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
},
}
testObject := testStoreObject{Id: "something", Val: "a"}
store.EXPECT().QueryForRows(context.Background(), indexer.listByIndexStmt, indexName, objKey).Return(nil, fmt.Errorf("error"))
_, err := indexer.Index(indexName, testObject)
assert.NotNil(t, err)
}})
tests = append(tests, testCase{description: "Index() with an errors returned from store ReadObjects(), should return an error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
rows := &sql.Rows{}
listStmt := &sql.Stmt{}
objKey := "key"
indexName := "someindexname"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
listByIndexStmt: listStmt,
indexers: map[string]cache.IndexFunc{
indexName: func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
},
}
testObject := testStoreObject{Id: "something", Val: "a"}
store.EXPECT().QueryForRows(context.Background(), indexer.listByIndexStmt, indexName, objKey).Return(rows, nil)
store.EXPECT().GetType().Return(reflect.TypeOf(testObject))
store.EXPECT().GetShouldEncrypt().Return(false)
store.EXPECT().ReadObjects(rows, reflect.TypeOf(testObject), false).Return([]any{testObject}, fmt.Errorf("error"))
_, err := indexer.Index(indexName, testObject)
assert.NotNil(t, err)
}})
tests = append(tests, testCase{description: "Index() with no errors returned from store and multiple keys returned from index func, should return one obj and no error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
rows := &sql.Rows{}
listStmt := &sql.Stmt{}
objKey := "key"
indexName := "someindexname"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
listByIndexStmt: listStmt,
indexers: map[string]cache.IndexFunc{
indexName: func(obj interface{}) ([]string, error) {
return []string{objKey, objKey + "2"}, nil
},
},
}
testObject := testStoreObject{Id: "something", Val: "a"}
store.EXPECT().GetName().Return("name")
stmt := &sql.Stmt{}
store.EXPECT().Prepare(fmt.Sprintf(selectQueryFmt, "name", ", ?")).Return(stmt)
store.EXPECT().QueryForRows(context.Background(), indexer.listByIndexStmt, indexName, objKey, objKey+"2").Return(rows, nil)
store.EXPECT().GetType().Return(reflect.TypeOf(testObject))
store.EXPECT().GetShouldEncrypt().Return(false)
store.EXPECT().ReadObjects(rows, reflect.TypeOf(testObject), false).Return([]any{testObject}, nil)
store.EXPECT().CloseStmt(stmt).Return(nil)
objs, err := indexer.Index(indexName, testObject)
assert.Nil(t, err)
assert.Equal(t, []any{testObject}, objs)
}})
t.Parallel()
for _, test := range tests {
t.Run(test.description, func(t *testing.T) { test.test(t) })
}
}
func TestByIndex(t *testing.T) {
type testCase struct {
description string
test func(t *testing.T)
}
var tests []testCase
tests = append(tests, testCase{description: "IndexBy() with no errors returned from store and 1 object returned by ReadObjects(), should return one obj and no error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
rows := &sql.Rows{}
listStmt := &sql.Stmt{}
objKey := "key"
indexName := "someindexname"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
listByIndexStmt: listStmt,
}
testObject := testStoreObject{Id: "something", Val: "a"}
store.EXPECT().QueryForRows(context.Background(), indexer.listByIndexStmt, indexName, objKey).Return(rows, nil)
store.EXPECT().GetType().Return(reflect.TypeOf(testObject))
store.EXPECT().GetShouldEncrypt().Return(false)
store.EXPECT().ReadObjects(rows, reflect.TypeOf(testObject), false).Return([]any{testObject}, nil)
objs, err := indexer.ByIndex(indexName, objKey)
assert.Nil(t, err)
assert.Equal(t, []any{testObject}, objs)
}})
tests = append(tests, testCase{description: "IndexBy() with no errors returned from store and multiple objects returned by ReadObjects(), should return multiple objects and no error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
rows := &sql.Rows{}
listStmt := &sql.Stmt{}
objKey := "key"
indexName := "someindexname"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
listByIndexStmt: listStmt,
}
testObject := testStoreObject{Id: "something", Val: "a"}
store.EXPECT().QueryForRows(context.Background(), indexer.listByIndexStmt, indexName, objKey).Return(rows, nil)
store.EXPECT().GetType().Return(reflect.TypeOf(testObject))
store.EXPECT().GetShouldEncrypt().Return(false)
store.EXPECT().ReadObjects(rows, reflect.TypeOf(testObject), false).Return([]any{testObject, testObject}, nil)
objs, err := indexer.ByIndex(indexName, objKey)
assert.Nil(t, err)
assert.Equal(t, []any{testObject, testObject}, objs)
}})
tests = append(tests, testCase{description: "IndexBy() with no errors returned from store and no objects returned by ReadObjects(), should return no objects and no error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
rows := &sql.Rows{}
listStmt := &sql.Stmt{}
objKey := "key"
indexName := "someindexname"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
listByIndexStmt: listStmt,
}
testObject := testStoreObject{Id: "something", Val: "a"}
store.EXPECT().QueryForRows(context.Background(), indexer.listByIndexStmt, indexName, objKey).Return(rows, nil)
store.EXPECT().GetType().Return(reflect.TypeOf(testObject))
store.EXPECT().GetShouldEncrypt().Return(false)
store.EXPECT().ReadObjects(rows, reflect.TypeOf(testObject), false).Return([]any{}, nil)
objs, err := indexer.ByIndex(indexName, objKey)
assert.Nil(t, err)
assert.Equal(t, []any{}, objs)
}})
tests = append(tests, testCase{description: "IndexBy() with an error returned from store QueryForRows, should return an error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
listStmt := &sql.Stmt{}
objKey := "key"
indexName := "someindexname"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
listByIndexStmt: listStmt,
}
store.EXPECT().QueryForRows(context.Background(), indexer.listByIndexStmt, indexName, objKey).Return(nil, fmt.Errorf("error"))
_, err := indexer.ByIndex(indexName, objKey)
assert.NotNil(t, err)
}})
tests = append(tests, testCase{description: "IndexBy() with an errors returned from store ReadObjects(), should return an error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
rows := &sql.Rows{}
listStmt := &sql.Stmt{}
objKey := "key"
indexName := "someindexname"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
listByIndexStmt: listStmt,
}
testObject := testStoreObject{Id: "something", Val: "a"}
store.EXPECT().QueryForRows(context.Background(), indexer.listByIndexStmt, indexName, objKey).Return(rows, nil)
store.EXPECT().GetType().Return(reflect.TypeOf(testObject))
store.EXPECT().GetShouldEncrypt().Return(false)
store.EXPECT().ReadObjects(rows, reflect.TypeOf(testObject), false).Return([]any{testObject}, fmt.Errorf("error"))
_, err := indexer.ByIndex(indexName, objKey)
assert.NotNil(t, err)
}})
t.Parallel()
for _, test := range tests {
t.Run(test.description, func(t *testing.T) { test.test(t) })
}
}
func TestListIndexFuncValues(t *testing.T) {
type testCase struct {
description string
test func(t *testing.T)
}
var tests []testCase
tests = append(tests, testCase{description: "ListIndexFuncvalues() with no errors returned from store and 1 object returned by ReadObjects(), should return one obj and no error", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
rows := &sql.Rows{}
listStmt := &sql.Stmt{}
indexName := "someindexname"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
listByIndexStmt: listStmt,
}
store.EXPECT().QueryForRows(context.Background(), indexer.listIndexValuesStmt, indexName).Return(rows, nil)
store.EXPECT().ReadStrings(rows).Return([]string{"somestrings"}, nil)
vals := indexer.ListIndexFuncValues(indexName)
assert.Equal(t, []string{"somestrings"}, vals)
}})
tests = append(tests, testCase{description: "ListIndexFuncvalues() with QueryForRows() error returned from store, should panic", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
listStmt := &sql.Stmt{}
indexName := "someindexname"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
listByIndexStmt: listStmt,
}
store.EXPECT().QueryForRows(context.Background(), indexer.listIndexValuesStmt, indexName).Return(nil, fmt.Errorf("error"))
assert.Panics(t, func() { indexer.ListIndexFuncValues(indexName) })
}})
tests = append(tests, testCase{description: "ListIndexFuncvalues() with ReadStrings() error returned from store, should panic", test: func(t *testing.T) {
store := NewMockStore(gomock.NewController(t))
rows := &sql.Rows{}
listStmt := &sql.Stmt{}
indexName := "someindexname"
indexer := &Indexer{
ctx: context.Background(),
Store: store,
listByIndexStmt: listStmt,
}
store.EXPECT().QueryForRows(context.Background(), indexer.listIndexValuesStmt, indexName).Return(rows, nil)
store.EXPECT().ReadStrings(rows).Return([]string{"somestrings"}, fmt.Errorf("error"))
assert.Panics(t, func() { indexer.ListIndexFuncValues(indexName) })
}})
t.Parallel()
for _, test := range tests {
t.Run(test.description, func(t *testing.T) { test.test(t) })
}
}
func TestGetIndexers(t *testing.T) {
type testCase struct {
description string
test func(t *testing.T)
}
var tests []testCase
tests = append(tests, testCase{description: "GetIndexers() should return indexers fron indexers field", test: func(t *testing.T) {
objKey := "key"
expectedIndexers := map[string]cache.IndexFunc{
"a": func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
}
indexer := &Indexer{
ctx: context.Background(),
indexers: expectedIndexers,
}
indexers := indexer.GetIndexers()
assert.Equal(t, cache.Indexers(expectedIndexers), indexers)
}})
t.Parallel()
for _, test := range tests {
t.Run(test.description, func(t *testing.T) { test.test(t) })
}
}
func TestAddIndexers(t *testing.T) {
type testCase struct {
description string
test func(t *testing.T)
}
var tests []testCase
tests = append(tests, testCase{description: "GetIndexers() should return indexers fron indexers field", test: func(t *testing.T) {
objKey := "key"
expectedIndexers := map[string]cache.IndexFunc{
"a": func(obj interface{}) ([]string, error) {
return []string{objKey}, nil
},
}
indexer := &Indexer{}
err := indexer.AddIndexers(expectedIndexers)
assert.Nil(t, err)
assert.ObjectsAreEqual(cache.Indexers(expectedIndexers), indexer.indexers)
}})
t.Parallel()
for _, test := range tests {
t.Run(test.description, func(t *testing.T) { test.test(t) })
}
}