storage/etcd3: factor tests to accept storage.Interface

This commit simply factors the test functionality into functions that
accept `storage.Interface`.

Signed-off-by: Steve Kuznetsov <skuznets@redhat.com>
This commit is contained in:
Steve Kuznetsov
2022-05-05 09:18:08 -07:00
parent 99de67958d
commit 117f674cab
2 changed files with 83 additions and 15 deletions

View File

@@ -41,7 +41,6 @@ import (
"k8s.io/apimachinery/pkg/api/apitesting"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
@@ -167,7 +166,10 @@ func checkStorageInvariants(ctx context.Context, t *testing.T, etcdClient *clien
func TestCreateWithTTL(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestCreateWithTTL(ctx, t, store)
}
func RunTestCreateWithTTL(ctx context.Context, t *testing.T, store storage.Interface) {
input := &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
key := "/somekey"
@@ -185,6 +187,10 @@ func TestCreateWithTTL(t *testing.T) {
func TestCreateWithKeyExist(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestCreateWithKeyExist(ctx, t, store)
}
func RunTestCreateWithKeyExist(ctx context.Context, t *testing.T, store storage.Interface) {
obj := &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
key, _ := testPropogateStore(ctx, t, store, obj)
out := &example.Pod{}
@@ -196,6 +202,10 @@ func TestCreateWithKeyExist(t *testing.T) {
func TestGet(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestGet(ctx, t, store)
}
func RunTestGet(ctx context.Context, t *testing.T, store storage.Interface) {
// create an object to test
key, createdObj := testPropogateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}})
// update the object once to allow get by exact resource version to be tested
@@ -298,6 +308,10 @@ func TestGet(t *testing.T) {
func TestUnconditionalDelete(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestUnconditionalDelete(ctx, t, store)
}
func RunTestUnconditionalDelete(ctx context.Context, t *testing.T, store storage.Interface) {
key, storedObj := testPropogateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}})
tests := []struct {
@@ -337,6 +351,10 @@ func TestUnconditionalDelete(t *testing.T) {
func TestConditionalDelete(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestConditionalDelete(ctx, t, store)
}
func RunTestConditionalDelete(ctx context.Context, t *testing.T, store storage.Interface) {
key, storedObj := testPropogateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "A"}})
tests := []struct {
@@ -399,6 +417,10 @@ func TestConditionalDelete(t *testing.T) {
func TestDeleteWithSuggestion(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestDeleteWithSuggestion(ctx, t, store)
}
func RunTestDeleteWithSuggestion(ctx context.Context, t *testing.T, store storage.Interface) {
key, originalPod := testPropogateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "name"}})
@@ -414,6 +436,10 @@ func TestDeleteWithSuggestion(t *testing.T) {
func TestDeleteWithSuggestionAndConflict(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestDeleteWithSuggestionAndConflict(ctx, t, store)
}
func RunTestDeleteWithSuggestionAndConflict(ctx context.Context, t *testing.T, store storage.Interface) {
key, originalPod := testPropogateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "name"}})
@@ -440,6 +466,10 @@ func TestDeleteWithSuggestionAndConflict(t *testing.T) {
func TestDeleteWithSuggestionOfDeletedObject(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestDeleteWithSuggestionOfDeletedObject(ctx, t, store)
}
func RunTestDeleteWithSuggestionOfDeletedObject(ctx context.Context, t *testing.T, store storage.Interface) {
key, originalPod := testPropogateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "name"}})
@@ -458,6 +488,10 @@ func TestDeleteWithSuggestionOfDeletedObject(t *testing.T) {
func TestValidateDeletionWithSuggestion(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestValidateDeletionWithSuggestion(ctx, t, store)
}
func RunTestValidateDeletionWithSuggestion(ctx context.Context, t *testing.T, store storage.Interface) {
key, originalPod := testPropogateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "name"}})
@@ -512,6 +546,10 @@ func TestValidateDeletionWithSuggestion(t *testing.T) {
func TestPreconditionalDeleteWithSuggestion(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestPreconditionalDeleteWithSuggestion(ctx, t, store)
}
func RunTestPreconditionalDeleteWithSuggestion(ctx context.Context, t *testing.T, store storage.Interface) {
key, originalPod := testPropogateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "name"}})
@@ -540,6 +578,10 @@ func TestPreconditionalDeleteWithSuggestion(t *testing.T) {
func TestGetListNonRecursive(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestGetListNonRecursive(ctx, t, store)
}
func RunTestGetListNonRecursive(ctx context.Context, t *testing.T, store storage.Interface) {
prevKey, prevStoredObj := testPropogateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "prev"}})
prevRV, _ := strconv.Atoi(prevStoredObj.ResourceVersion)
@@ -825,6 +867,10 @@ func TestGuaranteedUpdate(t *testing.T) {
func TestGuaranteedUpdateWithTTL(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestGuaranteedUpdateWithTTL(ctx, t, store)
}
func RunTestGuaranteedUpdateWithTTL(ctx context.Context, t *testing.T, store storage.Interface) {
input := &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
key := "/somekey"
@@ -848,7 +894,6 @@ func TestGuaranteedUpdateWithTTL(t *testing.T) {
func TestGuaranteedUpdateChecksStoredData(t *testing.T) {
ctx, store, _ := testSetup(t)
input := &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
key := "/somekey"
@@ -912,6 +957,10 @@ func TestGuaranteedUpdateChecksStoredData(t *testing.T) {
func TestGuaranteedUpdateWithConflict(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestGuaranteedUpdateWithConflict(ctx, t, store)
}
func RunTestGuaranteedUpdateWithConflict(ctx context.Context, t *testing.T, store storage.Interface) {
key, _ := testPropogateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}})
errChan := make(chan error, 1)
@@ -958,6 +1007,10 @@ func TestGuaranteedUpdateWithConflict(t *testing.T) {
func TestGuaranteedUpdateWithSuggestionAndConflict(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestGuaranteedUpdateWithSuggestionAndConflict(ctx, t, store)
}
func RunTestGuaranteedUpdateWithSuggestionAndConflict(ctx context.Context, t *testing.T, store storage.Interface) {
key, originalPod := testPropogateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}})
// First, update without a suggestion so originalPod is outdated
@@ -2228,20 +2281,16 @@ func testSetup(t *testing.T, opts ...setupOption) (context.Context, *store, *cli
// testPropogateStore helps propagates store with objects, automates key generation, and returns
// keys and stored objects.
func testPropogateStore(ctx context.Context, t *testing.T, store *store, obj *example.Pod) (string, *example.Pod) {
func testPropogateStore(ctx context.Context, t *testing.T, store storage.Interface, obj *example.Pod) (string, *example.Pod) {
// Setup store with a key and grab the output for returning.
key := "/testkey"
return key, testPropogateStoreWithKey(ctx, t, store, key, obj)
}
// testPropogateStoreWithKey helps propagate store with objects, the given object will be stored at the specified key.
func testPropogateStoreWithKey(ctx context.Context, t *testing.T, store *store, key string, obj *example.Pod) *example.Pod {
func testPropogateStoreWithKey(ctx context.Context, t *testing.T, store storage.Interface, key string, obj *example.Pod) *example.Pod {
// Setup store with the specified key and grab the output for returning.
v, err := conversion.EnforcePtr(obj)
if err != nil {
panic("unable to convert output object to pointer")
}
err = store.conditionalDelete(ctx, key, &example.Pod{}, v, nil, storage.ValidateAllObjectFunc, nil)
err := store.Delete(ctx, key, &example.Pod{}, nil, storage.ValidateAllObjectFunc, nil)
if err != nil && !storage.IsNotFound(err) {
t.Fatalf("Cleanup failed: %v", err)
}
@@ -2488,6 +2537,10 @@ func TestConsistentList(t *testing.T) {
func TestCount(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestCount(ctx, t, store)
}
func RunTestCount(ctx context.Context, t *testing.T, store storage.Interface) {
resourceA := "/foo.bar.io/abc"

View File

@@ -42,16 +42,20 @@ import (
)
func TestWatch(t *testing.T) {
testWatch(t, false)
testWatch(t, true)
ctx, store, _ := testSetup(t)
RunTestWatch(ctx, t, store)
}
func RunTestWatch(ctx context.Context, t *testing.T, store storage.Interface) {
testWatch(ctx, t, store, false)
testWatch(ctx, t, store, true)
}
// It tests that
// - first occurrence of objects should notify Add event
// - update should trigger Modified event
// - update that gets filtered should trigger Deleted event
func testWatch(t *testing.T, recursive bool) {
ctx, store, _ := testSetup(t)
func testWatch(ctx context.Context, t *testing.T, store storage.Interface, recursive bool) {
podFoo := &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
podBar := &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "bar"}}
@@ -133,6 +137,10 @@ func testWatch(t *testing.T, recursive bool) {
func TestDeleteTriggerWatch(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestDeleteTriggerWatch(ctx, t, store)
}
func RunTestDeleteTriggerWatch(ctx context.Context, t *testing.T, store storage.Interface) {
key, storedObj := testPropogateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}})
w, err := store.Watch(ctx, key, storage.ListOptions{ResourceVersion: storedObj.ResourceVersion, Predicate: storage.Everything})
if err != nil {
@@ -208,6 +216,10 @@ func TestWatchFromZero(t *testing.T) {
// - watch from non-0 should just watch changes after given version
func TestWatchFromNoneZero(t *testing.T) {
ctx, store, _ := testSetup(t)
RunTestWatchFromNoneZero(ctx, t, store)
}
func RunTestWatchFromNoneZero(ctx context.Context, t *testing.T, store storage.Interface) {
key, storedObj := testPropogateStore(ctx, t, store, &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}})
w, err := store.Watch(ctx, key, storage.ListOptions{ResourceVersion: storedObj.ResourceVersion, Predicate: storage.Everything})
@@ -341,9 +353,12 @@ func deletedRevision(ctx context.Context, watch <-chan clientv3.WatchResponse) (
}
func TestWatchInitializationSignal(t *testing.T) {
_, store, _ := testSetup(t)
ctx, store, _ := testSetup(t)
RunTestWatchInitializationSignal(ctx, t, store)
}
ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
func RunTestWatchInitializationSignal(ctx context.Context, t *testing.T, store storage.Interface) {
ctx, _ = context.WithTimeout(ctx, 5*time.Second)
initSignal := utilflowcontrol.NewInitializationSignal()
ctx = utilflowcontrol.WithInitializationSignal(ctx, initSignal)