Reuse generic ListNonRecurisve test for cacher

This commit is contained in:
Wojciech Tyczyński 2022-11-03 14:58:34 +01:00
parent 37db332298
commit e301306d89
2 changed files with 88 additions and 126 deletions

View File

@ -129,14 +129,15 @@ func RunTestGet(ctx context.Context, t *testing.T, store storage.Interface) {
ignoreNotFound bool ignoreNotFound bool
expectNotFoundErr bool expectNotFoundErr bool
expectRVTooLarge bool expectRVTooLarge bool
expectedOut []*example.Pod expectedOut *example.Pod
expectedAlternatives []*example.Pod
rv string rv string
}{{ }{{
name: "get existing", name: "get existing",
key: key, key: key,
ignoreNotFound: false, ignoreNotFound: false,
expectNotFoundErr: false, expectNotFoundErr: false,
expectedOut: []*example.Pod{storedObj}, expectedOut: storedObj,
}, { }, {
// For RV=0 arbitrarily old version is allowed, including from the moment // For RV=0 arbitrarily old version is allowed, including from the moment
// when the object didn't yet exist. // when the object didn't yet exist.
@ -145,24 +146,24 @@ func RunTestGet(ctx context.Context, t *testing.T, store storage.Interface) {
name: "resource version 0", name: "resource version 0",
key: key, key: key,
ignoreNotFound: true, ignoreNotFound: true,
expectedOut: []*example.Pod{{}, createdObj, storedObj}, expectedAlternatives: []*example.Pod{{}, createdObj, storedObj},
rv: "0", rv: "0",
}, { }, {
// Given that Get with set ResourceVersion is effectively always // Given that Get with set ResourceVersion is effectively always
// NotOlderThan semantic, both versions of object are allowed. // NotOlderThan semantic, both versions of object are allowed.
name: "object created resource version", name: "object created resource version",
key: key, key: key,
expectedOut: []*example.Pod{createdObj, storedObj}, expectedAlternatives: []*example.Pod{createdObj, storedObj},
rv: createdObj.ResourceVersion, rv: createdObj.ResourceVersion,
}, { }, {
name: "current object resource version, match=NotOlderThan", name: "current object resource version, match=NotOlderThan",
key: key, key: key,
expectedOut: []*example.Pod{storedObj}, expectedOut: storedObj,
rv: fmt.Sprintf("%d", currentRV), rv: fmt.Sprintf("%d", currentRV),
}, { }, {
name: "latest resource version", name: "latest resource version",
key: key, key: key,
expectedOut: []*example.Pod{storedObj}, expectedOut: storedObj,
rv: fmt.Sprintf("%d", lastUpdatedCurrentRV), rv: fmt.Sprintf("%d", lastUpdatedCurrentRV),
}, { }, {
name: "too high resource version", name: "too high resource version",
@ -179,7 +180,7 @@ func RunTestGet(ctx context.Context, t *testing.T, store storage.Interface) {
key: "/non-existing", key: "/non-existing",
ignoreNotFound: true, ignoreNotFound: true,
expectNotFoundErr: false, expectNotFoundErr: false,
expectedOut: []*example.Pod{{}}, expectedOut: &example.Pod{},
}} }}
for _, tt := range tests { for _, tt := range tests {
@ -202,8 +203,8 @@ func RunTestGet(ctx context.Context, t *testing.T, store storage.Interface) {
t.Fatalf("Get failed: %v", err) t.Fatalf("Get failed: %v", err)
} }
if len(tt.expectedOut) == 1 { if tt.expectedAlternatives == nil {
ExpectNoDiff(t, fmt.Sprintf("%s: incorrect pod", tt.name), tt.expectedOut[0], out) ExpectNoDiff(t, fmt.Sprintf("%s: incorrect pod", tt.name), tt.expectedOut, out)
} else { } else {
toInterfaceSlice := func(pods []*example.Pod) []interface{} { toInterfaceSlice := func(pods []*example.Pod) []interface{} {
result := make([]interface{}, 0, len(pods)) result := make([]interface{}, 0, len(pods))
@ -212,7 +213,7 @@ func RunTestGet(ctx context.Context, t *testing.T, store storage.Interface) {
} }
return result return result
} }
ExpectContains(t, fmt.Sprintf("%s: incorrect pod", tt.name), toInterfaceSlice(tt.expectedOut), out) ExpectContains(t, fmt.Sprintf("%s: incorrect pod", tt.name), toInterfaceSlice(tt.expectedAlternatives), out)
} }
}) })
} }
@ -1048,17 +1049,26 @@ func seedMultiLevelData(ctx context.Context, store storage.Interface) (string, [
} }
func RunTestGetListNonRecursive(ctx context.Context, t *testing.T, store storage.Interface) { func RunTestGetListNonRecursive(ctx context.Context, t *testing.T, store storage.Interface) {
prevKey, prevStoredObj := testPropagateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "prev"}}) key, prevStoredObj := testPropagateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}})
prevRV, _ := strconv.Atoi(prevStoredObj.ResourceVersion) prevRV, _ := strconv.Atoi(prevStoredObj.ResourceVersion)
key, storedObj := testPropagateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}})
storedObj := &example.Pod{}
if err := store.GuaranteedUpdate(ctx, key, storedObj, false, nil,
func(_ runtime.Object, _ storage.ResponseMeta) (runtime.Object, *uint64, error) {
newPod := prevStoredObj.DeepCopy()
newPod.Annotations = map[string]string{"version": "second"}
return newPod, nil, nil
}, nil); err != nil {
t.Fatalf("update failed: %v", err)
}
currentRV, _ := strconv.Atoi(storedObj.ResourceVersion) currentRV, _ := strconv.Atoi(storedObj.ResourceVersion)
tests := []struct { tests := []struct {
name string name string
key string key string
pred storage.SelectionPredicate pred storage.SelectionPredicate
expectedOut []*example.Pod expectedOut []example.Pod
expectedAlternatives [][]example.Pod
rv string rv string
rvMatch metav1.ResourceVersionMatch rvMatch metav1.ResourceVersionMatch
expectRVTooLarge bool expectRVTooLarge bool
@ -1066,59 +1076,59 @@ func RunTestGetListNonRecursive(ctx context.Context, t *testing.T, store storage
name: "existing key", name: "existing key",
key: key, key: key,
pred: storage.Everything, pred: storage.Everything,
expectedOut: []*example.Pod{storedObj}, expectedOut: []example.Pod{*storedObj},
}, { }, {
name: "existing key, resourceVersion=0", name: "existing key, resourceVersion=0",
key: key, key: key,
pred: storage.Everything, pred: storage.Everything,
expectedOut: []*example.Pod{storedObj}, expectedAlternatives: [][]example.Pod{nil, {*storedObj}},
rv: "0", rv: "0",
}, { }, {
name: "existing key, resourceVersion=0, resourceVersionMatch=notOlderThan", name: "existing key, resourceVersion=0, resourceVersionMatch=notOlderThan",
key: key, key: key,
pred: storage.Everything, pred: storage.Everything,
expectedOut: []*example.Pod{storedObj}, expectedAlternatives: [][]example.Pod{nil, {*storedObj}},
rv: "0", rv: "0",
rvMatch: metav1.ResourceVersionMatchNotOlderThan, rvMatch: metav1.ResourceVersionMatchNotOlderThan,
}, {
name: "existing key, resourceVersion=current",
key: key,
pred: storage.Everything,
expectedOut: []*example.Pod{storedObj},
rv: fmt.Sprintf("%d", currentRV),
}, {
name: "existing key, resourceVersion=current, resourceVersionMatch=notOlderThan",
key: key,
pred: storage.Everything,
expectedOut: []*example.Pod{storedObj},
rv: fmt.Sprintf("%d", currentRV),
rvMatch: metav1.ResourceVersionMatchNotOlderThan,
}, { }, {
name: "existing key, resourceVersion=previous, resourceVersionMatch=notOlderThan", name: "existing key, resourceVersion=previous, resourceVersionMatch=notOlderThan",
key: key, key: key,
pred: storage.Everything, pred: storage.Everything,
expectedOut: []*example.Pod{storedObj}, expectedAlternatives: [][]example.Pod{{*prevStoredObj}, {*storedObj}},
rv: fmt.Sprintf("%d", prevRV), rv: fmt.Sprintf("%d", prevRV),
rvMatch: metav1.ResourceVersionMatchNotOlderThan, rvMatch: metav1.ResourceVersionMatchNotOlderThan,
}, {
name: "existing key, resourceVersion=current, resourceVersionMatch=notOlderThan",
key: key,
pred: storage.Everything,
expectedOut: []example.Pod{*storedObj},
rv: fmt.Sprintf("%d", currentRV),
rvMatch: metav1.ResourceVersionMatchNotOlderThan,
}, {
name: "existing key, resourceVersion=current",
key: key,
pred: storage.Everything,
expectedOut: []example.Pod{*storedObj},
rv: fmt.Sprintf("%d", currentRV),
}, { }, {
name: "existing key, resourceVersion=current, resourceVersionMatch=exact", name: "existing key, resourceVersion=current, resourceVersionMatch=exact",
key: key, key: key,
pred: storage.Everything, pred: storage.Everything,
expectedOut: []*example.Pod{storedObj}, expectedOut: []example.Pod{*storedObj},
rv: fmt.Sprintf("%d", currentRV), rv: fmt.Sprintf("%d", currentRV),
rvMatch: metav1.ResourceVersionMatchExact, rvMatch: metav1.ResourceVersionMatchExact,
}, { }, {
name: "existing key, resourceVersion=current, resourceVersionMatch=exact", name: "existing key, resourceVersion=previous, resourceVersionMatch=exact",
key: prevKey, key: key,
pred: storage.Everything, pred: storage.Everything,
expectedOut: []*example.Pod{prevStoredObj}, expectedOut: []example.Pod{*prevStoredObj},
rv: fmt.Sprintf("%d", prevRV), rv: fmt.Sprintf("%d", prevRV),
rvMatch: metav1.ResourceVersionMatchExact, rvMatch: metav1.ResourceVersionMatchExact,
}, { }, {
name: "existing key, resourceVersion=too high", name: "existing key, resourceVersion=too high",
key: key, key: key,
pred: storage.Everything, pred: storage.Everything,
expectedOut: []*example.Pod{storedObj}, expectedOut: []example.Pod{*storedObj},
rv: strconv.FormatInt(math.MaxInt64, 10), rv: strconv.FormatInt(math.MaxInt64, 10),
expectRVTooLarge: true, expectRVTooLarge: true,
}, { }, {
@ -1164,13 +1174,18 @@ func RunTestGetListNonRecursive(ctx context.Context, t *testing.T, store storage
if len(out.ResourceVersion) == 0 { if len(out.ResourceVersion) == 0 {
t.Errorf("%s: unset resourceVersion", tt.name) t.Errorf("%s: unset resourceVersion", tt.name)
} }
if len(out.Items) != len(tt.expectedOut) {
t.Errorf("%s: length of list want=%d, get=%d", tt.name, len(tt.expectedOut), len(out.Items)) if tt.expectedAlternatives == nil {
return ExpectNoDiff(t, "incorrect list pods", tt.expectedOut, out.Items)
} else {
toInterfaceSlice := func(podLists [][]example.Pod) []interface{} {
result := make([]interface{}, 0, len(podLists))
for i := range podLists {
result = append(result, podLists[i])
} }
for j, wantPod := range tt.expectedOut { return result
getPod := &out.Items[j] }
ExpectNoDiff(t, fmt.Sprintf("%s: incorrect pod", tt.name), wantPod, getPod) ExpectContains(t, "incorrect list pods", toInterfaceSlice(tt.expectedAlternatives), out.Items)
} }
}) })
} }

View File

@ -170,62 +170,9 @@ func TestGet(t *testing.T) {
} }
func TestGetListNonRecursive(t *testing.T) { func TestGetListNonRecursive(t *testing.T) {
server, etcdStorage := newEtcdTestStorage(t, etcd3testing.PathPrefix()) ctx, cacher, terminate := testSetup(t)
defer server.Terminate(t) defer terminate()
cacher, _, err := newTestCacher(etcdStorage) storagetesting.RunTestGetListNonRecursive(ctx, t, cacher)
if err != nil {
t.Fatalf("Couldn't create cacher: %v", err)
}
defer cacher.Stop()
storedObj := updatePod(t, etcdStorage, makeTestPod("foo"), nil)
key := "pods/" + storedObj.Namespace + "/" + storedObj.Name
tests := []struct {
key string
pred storage.SelectionPredicate
expectedOut []*example.Pod
}{{ // test non-recursive GetList on existing key
key: key,
pred: storage.Everything,
expectedOut: []*example.Pod{storedObj},
}, { // test non-recursive GetList on non-existing key
key: "/non-existing",
pred: storage.Everything,
expectedOut: nil,
}, { // test non-recursive GetList with matching pod name
key: "/non-existing",
pred: storage.SelectionPredicate{
Label: labels.Everything(),
Field: fields.ParseSelectorOrDie("metadata.name!=" + storedObj.Name),
GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
pod := obj.(*example.Pod)
return nil, fields.Set{"metadata.name": pod.Name}, nil
},
},
expectedOut: nil,
}}
for i, tt := range tests {
out := &example.PodList{}
err := cacher.GetList(context.TODO(), tt.key, storage.ListOptions{Predicate: tt.pred, Recursive: false}, out)
if err != nil {
t.Fatalf("GetList failed: %v", err)
}
if len(out.ResourceVersion) == 0 {
t.Errorf("#%d: unset resourceVersion", i)
}
if len(out.Items) != len(tt.expectedOut) {
t.Errorf("#%d: length of list want=%d, get=%d", i, len(tt.expectedOut), len(out.Items))
continue
}
for j, wantPod := range tt.expectedOut {
getPod := &out.Items[j]
if !reflect.DeepEqual(wantPod, getPod) {
t.Errorf("#%d: pod want=%#v, get=%#v", i, wantPod, getPod)
}
}
}
} }
func TestList(t *testing.T) { func TestList(t *testing.T) {