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
expectNotFoundErr bool
expectRVTooLarge bool
expectedOut []*example.Pod
expectedOut *example.Pod
expectedAlternatives []*example.Pod
rv string
}{{
name: "get existing",
key: key,
ignoreNotFound: false,
expectNotFoundErr: false,
expectedOut: []*example.Pod{storedObj},
expectedOut: storedObj,
}, {
// For RV=0 arbitrarily old version is allowed, including from the moment
// 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",
key: key,
ignoreNotFound: true,
expectedOut: []*example.Pod{{}, createdObj, storedObj},
expectedAlternatives: []*example.Pod{{}, createdObj, storedObj},
rv: "0",
}, {
// Given that Get with set ResourceVersion is effectively always
// NotOlderThan semantic, both versions of object are allowed.
name: "object created resource version",
key: key,
expectedOut: []*example.Pod{createdObj, storedObj},
expectedAlternatives: []*example.Pod{createdObj, storedObj},
rv: createdObj.ResourceVersion,
}, {
name: "current object resource version, match=NotOlderThan",
key: key,
expectedOut: []*example.Pod{storedObj},
expectedOut: storedObj,
rv: fmt.Sprintf("%d", currentRV),
}, {
name: "latest resource version",
key: key,
expectedOut: []*example.Pod{storedObj},
expectedOut: storedObj,
rv: fmt.Sprintf("%d", lastUpdatedCurrentRV),
}, {
name: "too high resource version",
@ -179,7 +180,7 @@ func RunTestGet(ctx context.Context, t *testing.T, store storage.Interface) {
key: "/non-existing",
ignoreNotFound: true,
expectNotFoundErr: false,
expectedOut: []*example.Pod{{}},
expectedOut: &example.Pod{},
}}
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)
}
if len(tt.expectedOut) == 1 {
ExpectNoDiff(t, fmt.Sprintf("%s: incorrect pod", tt.name), tt.expectedOut[0], out)
if tt.expectedAlternatives == nil {
ExpectNoDiff(t, fmt.Sprintf("%s: incorrect pod", tt.name), tt.expectedOut, out)
} else {
toInterfaceSlice := func(pods []*example.Pod) []interface{} {
result := make([]interface{}, 0, len(pods))
@ -212,7 +213,7 @@ func RunTestGet(ctx context.Context, t *testing.T, store storage.Interface) {
}
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) {
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)
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)
tests := []struct {
name string
key string
pred storage.SelectionPredicate
expectedOut []*example.Pod
expectedOut []example.Pod
expectedAlternatives [][]example.Pod
rv string
rvMatch metav1.ResourceVersionMatch
expectRVTooLarge bool
@ -1066,59 +1076,59 @@ func RunTestGetListNonRecursive(ctx context.Context, t *testing.T, store storage
name: "existing key",
key: key,
pred: storage.Everything,
expectedOut: []*example.Pod{storedObj},
expectedOut: []example.Pod{*storedObj},
}, {
name: "existing key, resourceVersion=0",
key: key,
pred: storage.Everything,
expectedOut: []*example.Pod{storedObj},
expectedAlternatives: [][]example.Pod{nil, {*storedObj}},
rv: "0",
}, {
name: "existing key, resourceVersion=0, resourceVersionMatch=notOlderThan",
key: key,
pred: storage.Everything,
expectedOut: []*example.Pod{storedObj},
expectedAlternatives: [][]example.Pod{nil, {*storedObj}},
rv: "0",
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",
key: key,
pred: storage.Everything,
expectedOut: []*example.Pod{storedObj},
expectedAlternatives: [][]example.Pod{{*prevStoredObj}, {*storedObj}},
rv: fmt.Sprintf("%d", prevRV),
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",
key: key,
pred: storage.Everything,
expectedOut: []*example.Pod{storedObj},
expectedOut: []example.Pod{*storedObj},
rv: fmt.Sprintf("%d", currentRV),
rvMatch: metav1.ResourceVersionMatchExact,
}, {
name: "existing key, resourceVersion=current, resourceVersionMatch=exact",
key: prevKey,
name: "existing key, resourceVersion=previous, resourceVersionMatch=exact",
key: key,
pred: storage.Everything,
expectedOut: []*example.Pod{prevStoredObj},
expectedOut: []example.Pod{*prevStoredObj},
rv: fmt.Sprintf("%d", prevRV),
rvMatch: metav1.ResourceVersionMatchExact,
}, {
name: "existing key, resourceVersion=too high",
key: key,
pred: storage.Everything,
expectedOut: []*example.Pod{storedObj},
expectedOut: []example.Pod{*storedObj},
rv: strconv.FormatInt(math.MaxInt64, 10),
expectRVTooLarge: true,
}, {
@ -1164,13 +1174,18 @@ func RunTestGetListNonRecursive(ctx context.Context, t *testing.T, store storage
if len(out.ResourceVersion) == 0 {
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))
return
if tt.expectedAlternatives == nil {
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 {
getPod := &out.Items[j]
ExpectNoDiff(t, fmt.Sprintf("%s: incorrect pod", tt.name), wantPod, getPod)
return result
}
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) {
server, etcdStorage := newEtcdTestStorage(t, etcd3testing.PathPrefix())
defer server.Terminate(t)
cacher, _, err := newTestCacher(etcdStorage)
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)
}
}
}
ctx, cacher, terminate := testSetup(t)
defer terminate()
storagetesting.RunTestGetListNonRecursive(ctx, t, cacher)
}
func TestList(t *testing.T) {