Eliminate parallel and unnecessary embedded etcd instances

This commit is contained in:
Jordan Liggitt 2021-06-04 00:41:09 -04:00
parent 52b629efbc
commit 068e4c55a8
4 changed files with 90 additions and 70 deletions

View File

@ -21,6 +21,7 @@ import (
"fmt"
"net/http"
"reflect"
"strings"
"sync"
"testing"
@ -321,8 +322,6 @@ func TestStatusUpdate(t *testing.T) {
}
func TestEtcdCreateDeploymentRollback(t *testing.T) {
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), namespace)
testCases := map[string]struct {
rollback apps.DeploymentRollback
errOK func(error) bool
@ -350,11 +349,16 @@ func TestEtcdCreateDeploymentRollback(t *testing.T) {
errOK: func(err error) bool { return err != nil },
},
}
storage, server := newStorage(t)
defer server.Terminate(t)
defer storage.Deployment.Store.DestroyFunc()
for k, test := range testCases {
storage, server := newStorage(t)
rollbackStorage := storage.Rollback
deployment := validNewDeployment()
deployment.Namespace = fmt.Sprintf("namespace-%s", strings.ToLower(k))
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), deployment.Namespace)
if _, err := storage.Deployment.Create(ctx, validNewDeployment(), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil {
if _, err := storage.Deployment.Create(ctx, deployment, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil {
t.Fatalf("%s: unexpected error: %v", k, err)
}
rollbackRespStatus, err := rollbackStorage.Create(ctx, test.rollback.Name, &test.rollback, rest.ValidateAllObjectFunc, &metav1.CreateOptions{})
@ -369,15 +373,13 @@ func TestEtcdCreateDeploymentRollback(t *testing.T) {
if status.Code != http.StatusOK || status.Status != metav1.StatusSuccess {
t.Errorf("%s: unexpected response, code: %d, status: %s", k, status.Code, status.Status)
}
d, err := storage.Deployment.Get(ctx, validNewDeployment().ObjectMeta.Name, &metav1.GetOptions{})
d, err := storage.Deployment.Get(ctx, deployment.ObjectMeta.Name, &metav1.GetOptions{})
if err != nil {
t.Errorf("%s: unexpected error: %v", k, err)
} else if !reflect.DeepEqual(*d.(*apps.Deployment).Spec.RollbackTo, test.rollback.RollbackTo) {
t.Errorf("%s: expected: %v, got: %v", k, *d.(*apps.Deployment).Spec.RollbackTo, test.rollback.RollbackTo)
}
}
storage.Deployment.Store.DestroyFunc()
server.Terminate(t)
}
}

View File

@ -18,6 +18,7 @@ package storage
import (
"context"
"fmt"
"net/url"
"strings"
"testing"
@ -384,16 +385,18 @@ func TestResourceLocation(t *testing.T) {
},
}
ctx := genericapirequest.NewDefaultContext()
for _, tc := range testCases {
storage, _, _, server := newStorage(t)
storage, _, _, server := newStorage(t)
defer server.Terminate(t)
for i, tc := range testCases {
// unique namespace/storage location per test
ctx := genericapirequest.WithNamespace(genericapirequest.NewDefaultContext(), fmt.Sprintf("namespace-%d", i))
key, _ := storage.KeyFunc(ctx, tc.pod.Name)
if err := storage.Storage.Create(ctx, key, &tc.pod, nil, 0, false); err != nil {
t.Fatalf("unexpected error: %v", err)
}
redirector := rest.Redirector(storage)
location, _, err := redirector.ResourceLocation(genericapirequest.NewDefaultContext(), tc.query)
location, _, err := redirector.ResourceLocation(ctx, tc.query)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
@ -411,7 +414,6 @@ func TestResourceLocation(t *testing.T) {
t.Errorf("could not parse returned location %s: %v", location.String(), err)
}
server.Terminate(t)
}
}
@ -768,8 +770,6 @@ func TestEtcdCreateWithExistingContainers(t *testing.T) {
}
func TestEtcdCreateBinding(t *testing.T) {
ctx := genericapirequest.NewDefaultContext()
testCases := map[string]struct {
binding api.Binding
badNameInURL bool
@ -812,10 +812,15 @@ func TestEtcdCreateBinding(t *testing.T) {
errOK: func(err error) bool { return err == nil },
},
}
for k, test := range testCases {
storage, bindingStorage, _, server := newStorage(t)
storage, bindingStorage, _, server := newStorage(t)
defer server.Terminate(t)
defer storage.Store.DestroyFunc()
if _, err := storage.Create(ctx, validNewPod(), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil {
for k, test := range testCases {
pod := validNewPod()
pod.Namespace = fmt.Sprintf("namespace-%s", strings.ToLower(k))
ctx := genericapirequest.WithNamespace(genericapirequest.NewDefaultContext(), pod.Namespace)
if _, err := storage.Create(ctx, pod, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil {
t.Fatalf("%s: unexpected error: %v", k, err)
}
name := test.binding.Name
@ -826,15 +831,13 @@ func TestEtcdCreateBinding(t *testing.T) {
t.Errorf("%s: unexpected error: %v", k, err)
} else if err == nil {
// If bind succeeded, verify Host field in pod's Spec.
pod, err := storage.Get(ctx, validNewPod().ObjectMeta.Name, &metav1.GetOptions{})
pod, err := storage.Get(ctx, pod.ObjectMeta.Name, &metav1.GetOptions{})
if err != nil {
t.Errorf("%s: unexpected error: %v", k, err)
} else if pod.(*api.Pod).Spec.NodeName != test.binding.Target.Name {
t.Errorf("%s: expected: %v, got: %v", k, pod.(*api.Pod).Spec.NodeName, test.binding.Target.Name)
}
}
storage.Store.DestroyFunc()
server.Terminate(t)
}
}

View File

@ -1411,6 +1411,10 @@ func TestServiceRegistryDeleteDryRun(t *testing.T) {
if !storage.serviceNodePorts.Has(30030) {
t.Errorf("unexpected side effect: NodePort unallocated")
}
}
func TestDualStackServiceRegistryDeleteDryRun(t *testing.T) {
ctx := genericapirequest.NewDefaultContext()
// dry run for non dualstack
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)()
@ -1436,7 +1440,7 @@ func TestServiceRegistryDeleteDryRun(t *testing.T) {
},
}
_, err = dualstack_storage.Create(ctx, dualstack_svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{})
_, err := dualstack_storage.Create(ctx, dualstack_svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{})
if err != nil {
t.Fatalf("Expected no error: %v", err)
}
@ -3662,7 +3666,11 @@ func TestDefaultingValidation(t *testing.T) {
}
fnMakeDualStackStackIPv4IPv6Allocator := func(rest *REST) {
// default is v4,v6 rest storage
rest.defaultServiceIPFamily = api.IPv4Protocol
rest.serviceIPAllocatorsByFamily = map[api.IPFamily]ipallocator.Interface{
api.IPv6Protocol: rest.serviceIPAllocatorsByFamily[api.IPv6Protocol],
api.IPv4Protocol: rest.serviceIPAllocatorsByFamily[api.IPv4Protocol],
}
}
fnMakeDualStackStackIPv6IPv4Allocator := func(rest *REST) {
@ -5091,11 +5099,15 @@ func TestDefaultingValidation(t *testing.T) {
// This func only runs when feature gate is on
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)()
storage, _, server := NewTestREST(t, nil, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol})
defer server.Terminate(t)
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
storage, _, server := NewTestREST(t, nil, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) // all tests start with dual stack (v4,v6), then modification func takes care of whatever needed
defer server.Terminate(t)
// reset to defaults
fnMakeDualStackStackIPv4IPv6Allocator(storage)
// optionally apply test-specific changes
if testCase.modifyRest != nil {
testCase.modifyRest(storage)
}

View File

@ -209,29 +209,30 @@ func TestStoreList(t *testing.T) {
}
for name, item := range table {
ctx := testContext
if item.context != nil {
ctx = item.context
}
destroyFunc, registry := NewTestGenericStoreRegistry(t)
if item.in != nil {
if err := storagetesting.CreateList("/pods", registry.Storage.Storage, item.in); err != nil {
t.Errorf("Unexpected error %v", err)
t.Run(name, func(t *testing.T) {
ctx := testContext
if item.context != nil {
ctx = item.context
}
}
destroyFunc, registry := NewTestGenericStoreRegistry(t)
defer destroyFunc()
list, err := registry.ListPredicate(ctx, item.m, nil)
if err != nil {
t.Errorf("Unexpected error %v", err)
continue
}
if item.in != nil {
if err := storagetesting.CreateList("/pods", registry.Storage.Storage, item.in); err != nil {
t.Fatalf("Unexpected error %v", err)
}
}
// DeepDerivative e,a is needed here b/c the storage layer sets ResourceVersion
if e, a := item.out, list; !apiequality.Semantic.DeepDerivative(e, a) {
t.Errorf("%v: Expected %#v, got %#v", name, e, a)
}
destroyFunc()
list, err := registry.ListPredicate(ctx, item.m, nil)
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
// DeepDerivative e,a is needed here b/c the storage layer sets ResourceVersion
if e, a := item.out, list; !apiequality.Semantic.DeepDerivative(e, a) {
t.Fatalf("%v: Expected %#v, got %#v", name, e, a)
}
})
}
}
@ -2142,37 +2143,39 @@ func TestStoreWatch(t *testing.T) {
}
for name, m := range table {
ctx := testContext
if m.context != nil {
ctx = m.context
}
podA := &example.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
Namespace: "test",
},
Spec: example.PodSpec{NodeName: "machine"},
}
t.Run(name, func(t *testing.T) {
ctx := testContext
if m.context != nil {
ctx = m.context
}
podA := &example.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
Namespace: "test",
},
Spec: example.PodSpec{NodeName: "machine"},
}
destroyFunc, registry := NewTestGenericStoreRegistry(t)
wi, err := registry.WatchPredicate(ctx, m.selectPred, "0")
if err != nil {
t.Errorf("%v: unexpected error: %v", name, err)
} else {
obj, err := registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{})
destroyFunc, registry := NewTestGenericStoreRegistry(t)
defer destroyFunc()
wi, err := registry.WatchPredicate(ctx, m.selectPred, "0")
if err != nil {
got, open := <-wi.ResultChan()
if !open {
t.Errorf("%v: unexpected channel close", name)
} else {
if e, a := obj, got.Object; !reflect.DeepEqual(e, a) {
t.Errorf("Expected %#v, got %#v", e, a)
t.Errorf("%v: unexpected error: %v", name, err)
} else {
obj, err := registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{})
if err != nil {
got, open := <-wi.ResultChan()
if !open {
t.Errorf("%v: unexpected channel close", name)
} else {
if e, a := obj, got.Object; !reflect.DeepEqual(e, a) {
t.Errorf("Expected %#v, got %#v", e, a)
}
}
}
wi.Stop()
}
wi.Stop()
}
destroyFunc()
})
}
}