Skip to content

Commit c48ac64

Browse files
moiotomleb
andauthored
[v2.10] SQL cache backports (#435)
Co-authored-by: Tom Lebreux <[email protected]>
1 parent a672f2f commit c48ac64

File tree

6 files changed

+158
-24
lines changed

6 files changed

+158
-24
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ require (
2222
github.com/rancher/apiserver v0.0.0-20241009200134-5a4ecca7b988
2323
github.com/rancher/dynamiclistener v0.6.1-rc.2
2424
github.com/rancher/kubernetes-provider-detector v0.1.5
25-
github.com/rancher/lasso v0.0.0-20240924233157-8f384efc8813
25+
github.com/rancher/lasso v0.0.0-20241202185148-04649f379358
2626
github.com/rancher/norman v0.0.0-20241001183610-78a520c160ab
2727
github.com/rancher/remotedialer v0.3.2
2828
github.com/rancher/wrangler/v3 v3.0.1-rc.2

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,8 @@ github.com/rancher/dynamiclistener v0.6.1-rc.2 h1:PTKNKcYXZjc/lo40EivRcXuEbCXwjp
230230
github.com/rancher/dynamiclistener v0.6.1-rc.2/go.mod h1:0KhUMHy3VcGMGavTY3i1/Mr8rVM02wFqNlUzjc+Cplg=
231231
github.com/rancher/kubernetes-provider-detector v0.1.5 h1:hWRAsWuJOemzGjz/XrbTlM7QmfO4OedvFE3QwXiH60I=
232232
github.com/rancher/kubernetes-provider-detector v0.1.5/go.mod h1:ypuJS7kP7rUiAn330xG46mj+Nhvym05GM8NqMVekpH0=
233-
github.com/rancher/lasso v0.0.0-20240924233157-8f384efc8813 h1:V/LY8pUHZG9Kc+xEDWDOryOnCU6/Q+Lsr9QQEQnshpU=
234-
github.com/rancher/lasso v0.0.0-20240924233157-8f384efc8813/go.mod h1:IxgTBO55lziYhTEETyVKiT8/B5Rg92qYiRmcIIYoPgI=
233+
github.com/rancher/lasso v0.0.0-20241202185148-04649f379358 h1:pJwgJXPt4fi0ysXsJcl28rvxhx/Z/9SNCDwFOEyeGu0=
234+
github.com/rancher/lasso v0.0.0-20241202185148-04649f379358/go.mod h1:IxgTBO55lziYhTEETyVKiT8/B5Rg92qYiRmcIIYoPgI=
235235
github.com/rancher/norman v0.0.0-20241001183610-78a520c160ab h1:ihK6See3y/JilqZlc0CG7NXPN+ue5nY9U7xUZUA8M7I=
236236
github.com/rancher/norman v0.0.0-20241001183610-78a520c160ab/go.mod h1:qX/OG/4wY27xSAcSdRilUBxBumV6Ey2CWpAeaKnBQDs=
237237
github.com/rancher/remotedialer v0.3.2 h1:kstZbRwPS5gPWpGg8VjEHT2poHtArs+Fc317YM8JCzU=

pkg/controllers/schema/schemas.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func isListOrGetable(schema *types.APISchema) bool {
108108
return false
109109
}
110110

111-
func isListWatchable(schema *types.APISchema) bool {
111+
func IsListWatchable(schema *types.APISchema) bool {
112112
var (
113113
canList bool
114114
canWatch bool
@@ -163,7 +163,7 @@ func (h *handler) refreshAll(ctx context.Context) error {
163163

164164
filteredSchemas := map[string]*types.APISchema{}
165165
for _, schema := range schemas {
166-
if isListWatchable(schema) {
166+
if IsListWatchable(schema) {
167167
if preferredTypeExists(schema, schemas) {
168168
continue
169169
}

pkg/stores/sqlproxy/proxy_mocks_test.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/stores/sqlproxy/proxy_store.go

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
"github.com/rancher/wrangler/v3/pkg/summary"
4242

4343
"github.com/rancher/steve/pkg/attributes"
44+
controllerschema "github.com/rancher/steve/pkg/controllers/schema"
4445
"github.com/rancher/steve/pkg/resources/common"
4546
"github.com/rancher/steve/pkg/resources/virtual"
4647
virtualCommon "github.com/rancher/steve/pkg/resources/virtual/common"
@@ -59,6 +60,8 @@ var (
5960
paramScheme = runtime.NewScheme()
6061
paramCodec = runtime.NewParameterCodec(paramScheme)
6162
typeSpecificIndexedFields = map[string][][]string{
63+
gvkKey("", "v1", "ConfigMap"): {
64+
{"metadata", "labels[harvesterhci.io/cloud-init-template]"}},
6265
gvkKey("", "v1", "Event"): {
6366
{"_type"},
6467
{"involvedObject", "kind"},
@@ -70,11 +73,43 @@ var (
7073
gvkKey("", "v1", "Node"): {
7174
{"status", "nodeInfo", "kubeletVersion"},
7275
{"status", "nodeInfo", "operatingSystem"}},
76+
gvkKey("", "v1", "PersistentVolume"): {
77+
{"status", "reason"},
78+
{"spec", "persistentVolumeReclaimPolicy"},
79+
},
80+
gvkKey("", "v1", "PersistentVolumeClaim"): {
81+
{"spec", "volumeName"}},
7382
gvkKey("", "v1", "Pod"): {
7483
{"spec", "containers", "image"},
7584
{"spec", "nodeName"}},
76-
gvkKey("", "v1", "ConfigMap"): {
77-
{"metadata", "labels[harvesterhci.io/cloud-init-template]"}},
85+
gvkKey("", "v1", "Service"): {
86+
{"spec", "clusterIP"},
87+
{"spec", "type"},
88+
},
89+
gvkKey("apps", "v1", "DaemonSet"): {
90+
{"metadata", "annotations[field.cattle.io/publicEndpoints]"},
91+
},
92+
gvkKey("apps", "v1", "Deployment"): {
93+
{"metadata", "annotations[field.cattle.io/publicEndpoints]"},
94+
},
95+
gvkKey("apps", "v1", "StatefulSet"): {
96+
{"metadata", "annotations[field.cattle.io/publicEndpoints]"},
97+
},
98+
gvkKey("autoscaling", "v2", "HorizontalPodAutoscaler"): {
99+
{"spec", "scaleTargetRef", "name"},
100+
{"spec", "minReplicas"},
101+
{"spec", "maxReplicas"},
102+
{"status", "currentReplicas"},
103+
},
104+
gvkKey("batch", "v1", "CronJob"): {
105+
{"metadata", "annotations[field.cattle.io/publicEndpoints]"},
106+
},
107+
gvkKey("batch", "v1", "Job"): {
108+
{"metadata", "annotations[field.cattle.io/publicEndpoints]"},
109+
},
110+
gvkKey("catalog.cattle.io", "v1", "App"): {
111+
{"spec", "chart", "metadata", "name"},
112+
},
78113
gvkKey("catalog.cattle.io", "v1", "ClusterRepo"): {
79114
{"metadata", "annotations[clusterrepo.cattle.io/hidden]"},
80115
{"spec", "gitBranch"},
@@ -87,18 +122,30 @@ var (
87122
},
88123
gvkKey("cluster.x-k8s.io", "v1beta1", "Machine"): {
89124
{"spec", "clusterName"}},
125+
gvkKey("management.cattle.io", "v3", "Cluster"): {
126+
{"metadata", "labels[provider.cattle.io]"},
127+
{"spec", "internal"},
128+
{"spec", "displayName"},
129+
{"status", "provider"},
130+
},
90131
gvkKey("management.cattle.io", "v3", "Node"): {
91132
{"status", "nodeName"}},
92133
gvkKey("management.cattle.io", "v3", "NodePool"): {
93134
{"spec", "clusterName"}},
94135
gvkKey("management.cattle.io", "v3", "NodeTemplate"): {
95136
{"spec", "clusterName"}},
137+
gvkKey("networking.k8s.io", "v1", "Ingress"): {
138+
{"spec", "rules", "host"},
139+
{"spec", "ingressClassName"},
140+
},
96141
gvkKey("provisioning.cattle.io", "v1", "Cluster"): {
97142
{"metadata", "labels[provider.cattle.io]"},
143+
{"status", "clusterName"},
98144
{"status", "provider"},
99-
{"status", "allocatable", "cpu"},
100-
{"status", "allocatable", "memory"},
101-
{"status", "allocatable", "pods"},
145+
},
146+
gvkKey("storage.k8s.io", "v1", "StorageClass"): {
147+
{"provisioner"},
148+
{"metadata", "annotations[storageclass.kubernetes.io/is-default-class]"},
102149
},
103150
}
104151
commonIndexFields = [][]string{
@@ -184,7 +231,7 @@ type Store struct {
184231
type CacheFactoryInitializer func() (CacheFactory, error)
185232

186233
type CacheFactory interface {
187-
CacheFor(fields [][]string, transform cache.TransformFunc, client dynamic.ResourceInterface, gvk schema.GroupVersionKind, namespaced bool) (factory.Cache, error)
234+
CacheFor(fields [][]string, transform cache.TransformFunc, client dynamic.ResourceInterface, gvk schema.GroupVersionKind, namespaced bool, watchable bool) (factory.Cache, error)
188235
Reset() error
189236
}
190237

@@ -262,7 +309,7 @@ func (s *Store) initializeNamespaceCache() error {
262309
transformFunc := s.transformBuilder.GetTransformFunc(gvk)
263310

264311
// get the ns informer
265-
nsInformer, err := s.cacheFactory.CacheFor(fields, transformFunc, &tablelistconvert.Client{ResourceInterface: client}, attributes.GVK(&nsSchema), false)
312+
nsInformer, err := s.cacheFactory.CacheFor(fields, transformFunc, &tablelistconvert.Client{ResourceInterface: client}, attributes.GVK(&nsSchema), false, true)
266313
if err != nil {
267314
return err
268315
}
@@ -702,7 +749,7 @@ func (s *Store) ListByPartitions(apiOp *types.APIRequest, schema *types.APISchem
702749
fields = append(fields, getFieldForGVK(gvk)...)
703750
transformFunc := s.transformBuilder.GetTransformFunc(gvk)
704751

705-
inf, err := s.cacheFactory.CacheFor(fields, transformFunc, &tablelistconvert.Client{ResourceInterface: client}, attributes.GVK(schema), attributes.Namespaced(schema))
752+
inf, err := s.cacheFactory.CacheFor(fields, transformFunc, &tablelistconvert.Client{ResourceInterface: client}, attributes.GVK(schema), attributes.Namespaced(schema), controllerschema.IsListWatchable(schema))
706753
if err != nil {
707754
return nil, 0, "", err
708755
}

pkg/stores/sqlproxy/proxy_store_test.go

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func TestNewProxyStore(t *testing.T) {
8282
nsSchema := baseNSSchema
8383
scc.EXPECT().SetColumns(context.Background(), &nsSchema).Return(nil)
8484
cg.EXPECT().TableAdminClient(nil, &nsSchema, "", &WarningBuffer{}).Return(ri, nil)
85-
cf.EXPECT().CacheFor([][]string{{`id`}, {`metadata`, `state`, `name`}, {"metadata", "labels[field.cattle.io/projectId]"}}, gomock.Any(), &tablelistconvert.Client{ResourceInterface: ri}, attributes.GVK(&nsSchema), false).Return(c, nil)
85+
cf.EXPECT().CacheFor([][]string{{`id`}, {`metadata`, `state`, `name`}, {"metadata", "labels[field.cattle.io/projectId]"}}, gomock.Any(), &tablelistconvert.Client{ResourceInterface: ri}, attributes.GVK(&nsSchema), false, true).Return(c, nil)
8686

8787
s, err := NewProxyStore(scc, cg, rn, nil, cf)
8888
assert.Nil(t, err)
@@ -149,7 +149,7 @@ func TestNewProxyStore(t *testing.T) {
149149
nsSchema := baseNSSchema
150150
scc.EXPECT().SetColumns(context.Background(), &nsSchema).Return(nil)
151151
cg.EXPECT().TableAdminClient(nil, &nsSchema, "", &WarningBuffer{}).Return(ri, nil)
152-
cf.EXPECT().CacheFor([][]string{{`id`}, {`metadata`, `state`, `name`}, {"metadata", "labels[field.cattle.io/projectId]"}}, gomock.Any(), &tablelistconvert.Client{ResourceInterface: ri}, attributes.GVK(&nsSchema), false).Return(factory.Cache{}, fmt.Errorf("error"))
152+
cf.EXPECT().CacheFor([][]string{{`id`}, {`metadata`, `state`, `name`}, {"metadata", "labels[field.cattle.io/projectId]"}}, gomock.Any(), &tablelistconvert.Client{ResourceInterface: ri}, attributes.GVK(&nsSchema), false, true).Return(factory.Cache{}, fmt.Errorf("error"))
153153

154154
s, err := NewProxyStore(scc, cg, rn, nil, cf)
155155
assert.Nil(t, err)
@@ -207,6 +207,7 @@ func TestListByPartitions(t *testing.T) {
207207
Field: "some.field",
208208
},
209209
},
210+
"verbs": []string{"list", "watch"},
210211
}},
211212
}
212213
expectedItems := []unstructured.Unstructured{
@@ -240,7 +241,7 @@ func TestListByPartitions(t *testing.T) {
240241
assert.Nil(t, err)
241242
cg.EXPECT().TableAdminClient(req, schema, "", &WarningBuffer{}).Return(ri, nil)
242243
// This tests that fields are being extracted from schema columns and the type specific fields map
243-
cf.EXPECT().CacheFor([][]string{{"some", "field"}, {`id`}, {`metadata`, `state`, `name`}, {"gvk", "specific", "fields"}}, gomock.Any(), &tablelistconvert.Client{ResourceInterface: ri}, attributes.GVK(schema), attributes.Namespaced(schema)).Return(c, nil)
244+
cf.EXPECT().CacheFor([][]string{{"some", "field"}, {`id`}, {`metadata`, `state`, `name`}, {"gvk", "specific", "fields"}}, gomock.Any(), &tablelistconvert.Client{ResourceInterface: ri}, attributes.GVK(schema), attributes.Namespaced(schema), true).Return(c, nil)
244245
tb.EXPECT().GetTransformFunc(attributes.GVK(schema)).Return(func(obj interface{}) (interface{}, error) { return obj, nil })
245246
bloi.EXPECT().ListByOptions(req.Context(), opts, partitions, req.Namespace).Return(listToReturn, len(listToReturn.Items), "", nil)
246247
list, total, contToken, err := s.ListByPartitions(req, schema, partitions)
@@ -277,6 +278,7 @@ func TestListByPartitions(t *testing.T) {
277278
Field: "some.field",
278279
},
279280
},
281+
"verbs": []string{"list", "watch"},
280282
}},
281283
}
282284
expectedItems := []unstructured.Unstructured{
@@ -343,6 +345,7 @@ func TestListByPartitions(t *testing.T) {
343345
Field: "some.field",
344346
},
345347
},
348+
"verbs": []string{"list", "watch"},
346349
}},
347350
}
348351
expectedItems := []unstructured.Unstructured{
@@ -380,6 +383,88 @@ func TestListByPartitions(t *testing.T) {
380383
assert.NotNil(t, err)
381384
},
382385
})
386+
tests = append(tests, testCase{
387+
description: "client ListByPartitions() should detect listable-but-unwatchable schema, still work normally",
388+
test: func(t *testing.T) {
389+
nsi := NewMockCache(gomock.NewController(t))
390+
cg := NewMockClientGetter(gomock.NewController(t))
391+
cf := NewMockCacheFactory(gomock.NewController(t))
392+
ri := NewMockResourceInterface(gomock.NewController(t))
393+
bloi := NewMockByOptionsLister(gomock.NewController(t))
394+
tb := NewMockTransformBuilder(gomock.NewController(t))
395+
inf := &informer.Informer{
396+
ByOptionsLister: bloi,
397+
}
398+
c := factory.Cache{
399+
ByOptionsLister: inf,
400+
}
401+
s := &Store{
402+
namespaceCache: nsi,
403+
clientGetter: cg,
404+
cacheFactory: cf,
405+
transformBuilder: tb,
406+
}
407+
var partitions []partition.Partition
408+
req := &types.APIRequest{
409+
Request: &http.Request{
410+
URL: &url.URL{},
411+
},
412+
}
413+
schema := &types.APISchema{
414+
Schema: &schemas.Schema{Attributes: map[string]interface{}{
415+
"columns": []common.ColumnDefinition{
416+
{
417+
Field: "some.field",
418+
},
419+
},
420+
// note: no watch here
421+
"verbs": []string{"list"},
422+
}},
423+
}
424+
expectedItems := []unstructured.Unstructured{
425+
{
426+
Object: map[string]interface{}{
427+
"kind": "apple",
428+
"metadata": map[string]interface{}{
429+
"name": "fuji",
430+
},
431+
"data": map[string]interface{}{
432+
"color": "pink",
433+
},
434+
},
435+
},
436+
}
437+
listToReturn := &unstructured.UnstructuredList{
438+
Items: make([]unstructured.Unstructured, len(expectedItems), len(expectedItems)),
439+
}
440+
gvk := schema2.GroupVersionKind{
441+
Group: "some",
442+
Version: "test",
443+
Kind: "gvk",
444+
}
445+
typeSpecificIndexedFields["some_test_gvk"] = [][]string{{"gvk", "specific", "fields"}}
446+
447+
attributes.SetGVK(schema, gvk)
448+
// ListByPartitions copies point so we need some original record of items to ensure as asserting listToReturn's
449+
// items is equal to the list returned by ListByParititons doesn't ensure no mutation happened
450+
copy(listToReturn.Items, expectedItems)
451+
opts, err := listprocessor.ParseQuery(req, nil)
452+
assert.Nil(t, err)
453+
cg.EXPECT().TableAdminClient(req, schema, "", &WarningBuffer{}).Return(ri, nil)
454+
455+
// This tests that fields are being extracted from schema columns and the type specific fields map
456+
// note also the watchable bool is expected to be false
457+
cf.EXPECT().CacheFor([][]string{{"some", "field"}, {`id`}, {`metadata`, `state`, `name`}, {"gvk", "specific", "fields"}}, gomock.Any(), &tablelistconvert.Client{ResourceInterface: ri}, attributes.GVK(schema), attributes.Namespaced(schema), false).Return(c, nil)
458+
459+
tb.EXPECT().GetTransformFunc(attributes.GVK(schema)).Return(func(obj interface{}) (interface{}, error) { return obj, nil })
460+
bloi.EXPECT().ListByOptions(req.Context(), opts, partitions, req.Namespace).Return(listToReturn, len(listToReturn.Items), "", nil)
461+
list, total, contToken, err := s.ListByPartitions(req, schema, partitions)
462+
assert.Nil(t, err)
463+
assert.Equal(t, expectedItems, list)
464+
assert.Equal(t, len(expectedItems), total)
465+
assert.Equal(t, "", contToken)
466+
},
467+
})
383468
tests = append(tests, testCase{
384469
description: "client ListByPartitions() with CacheFor() error returned should returned an errors. Should pass fields",
385470
test: func(t *testing.T) {
@@ -408,6 +493,7 @@ func TestListByPartitions(t *testing.T) {
408493
Field: "some.field",
409494
},
410495
},
496+
"verbs": []string{"list", "watch"},
411497
}},
412498
}
413499
expectedItems := []unstructured.Unstructured{
@@ -442,7 +528,7 @@ func TestListByPartitions(t *testing.T) {
442528
cg.EXPECT().TableAdminClient(req, schema, "", &WarningBuffer{}).Return(ri, nil)
443529
// This tests that fields are being extracted from schema columns and the type specific fields map
444530
tb.EXPECT().GetTransformFunc(attributes.GVK(schema)).Return(func(obj interface{}) (interface{}, error) { return obj, nil })
445-
cf.EXPECT().CacheFor([][]string{{"some", "field"}, {`id`}, {`metadata`, `state`, `name`}, {"gvk", "specific", "fields"}}, gomock.Any(), &tablelistconvert.Client{ResourceInterface: ri}, attributes.GVK(schema), attributes.Namespaced(schema)).Return(factory.Cache{}, fmt.Errorf("error"))
531+
cf.EXPECT().CacheFor([][]string{{"some", "field"}, {`id`}, {`metadata`, `state`, `name`}, {"gvk", "specific", "fields"}}, gomock.Any(), &tablelistconvert.Client{ResourceInterface: ri}, attributes.GVK(schema), attributes.Namespaced(schema), true).Return(factory.Cache{}, fmt.Errorf("error"))
446532

447533
_, _, _, err = s.ListByPartitions(req, schema, partitions)
448534
assert.NotNil(t, err)
@@ -483,6 +569,7 @@ func TestListByPartitions(t *testing.T) {
483569
Field: "some.field",
484570
},
485571
},
572+
"verbs": []string{"list", "watch"},
486573
}},
487574
}
488575
expectedItems := []unstructured.Unstructured{
@@ -516,7 +603,7 @@ func TestListByPartitions(t *testing.T) {
516603
assert.Nil(t, err)
517604
cg.EXPECT().TableAdminClient(req, schema, "", &WarningBuffer{}).Return(ri, nil)
518605
// This tests that fields are being extracted from schema columns and the type specific fields map
519-
cf.EXPECT().CacheFor([][]string{{"some", "field"}, {`id`}, {`metadata`, `state`, `name`}, {"gvk", "specific", "fields"}}, gomock.Any(), &tablelistconvert.Client{ResourceInterface: ri}, attributes.GVK(schema), attributes.Namespaced(schema)).Return(c, nil)
606+
cf.EXPECT().CacheFor([][]string{{"some", "field"}, {`id`}, {`metadata`, `state`, `name`}, {"gvk", "specific", "fields"}}, gomock.Any(), &tablelistconvert.Client{ResourceInterface: ri}, attributes.GVK(schema), attributes.Namespaced(schema), true).Return(c, nil)
520607
bloi.EXPECT().ListByOptions(req.Context(), opts, partitions, req.Namespace).Return(nil, 0, "", fmt.Errorf("error"))
521608
tb.EXPECT().GetTransformFunc(attributes.GVK(schema)).Return(func(obj interface{}) (interface{}, error) { return obj, nil })
522609

@@ -558,7 +645,7 @@ func TestReset(t *testing.T) {
558645
cf.EXPECT().Reset().Return(nil)
559646
cs.EXPECT().SetColumns(gomock.Any(), gomock.Any()).Return(nil)
560647
cg.EXPECT().TableAdminClient(nil, &nsSchema, "", &WarningBuffer{}).Return(ri, nil)
561-
cf.EXPECT().CacheFor([][]string{{`id`}, {`metadata`, `state`, `name`}, {"metadata", "labels[field.cattle.io/projectId]"}}, gomock.Any(), &tablelistconvert.Client{ResourceInterface: ri}, attributes.GVK(&nsSchema), false).Return(nsc2, nil)
648+
cf.EXPECT().CacheFor([][]string{{`id`}, {`metadata`, `state`, `name`}, {"metadata", "labels[field.cattle.io/projectId]"}}, gomock.Any(), &tablelistconvert.Client{ResourceInterface: ri}, attributes.GVK(&nsSchema), false, true).Return(nsc2, nil)
562649
tb.EXPECT().GetTransformFunc(attributes.GVK(&nsSchema)).Return(func(obj interface{}) (interface{}, error) { return obj, nil })
563650
err := s.Reset()
564651
assert.Nil(t, err)
@@ -661,7 +748,7 @@ func TestReset(t *testing.T) {
661748
cf.EXPECT().Reset().Return(nil)
662749
cs.EXPECT().SetColumns(gomock.Any(), gomock.Any()).Return(nil)
663750
cg.EXPECT().TableAdminClient(nil, &nsSchema, "", &WarningBuffer{}).Return(ri, nil)
664-
cf.EXPECT().CacheFor([][]string{{`id`}, {`metadata`, `state`, `name`}, {"metadata", "labels[field.cattle.io/projectId]"}}, gomock.Any(), &tablelistconvert.Client{ResourceInterface: ri}, attributes.GVK(&nsSchema), false).Return(factory.Cache{}, fmt.Errorf("error"))
751+
cf.EXPECT().CacheFor([][]string{{`id`}, {`metadata`, `state`, `name`}, {"metadata", "labels[field.cattle.io/projectId]"}}, gomock.Any(), &tablelistconvert.Client{ResourceInterface: ri}, attributes.GVK(&nsSchema), false, true).Return(factory.Cache{}, fmt.Errorf("error"))
665752
tb.EXPECT().GetTransformFunc(attributes.GVK(&nsSchema)).Return(func(obj interface{}) (interface{}, error) { return obj, nil })
666753
err := s.Reset()
667754
assert.NotNil(t, err)

0 commit comments

Comments
 (0)