pkg/genericapiserver/registry/generic/registry: cut off pkg/api dependency

This commit is contained in:
Dr. Stefan Schimanski 2017-02-02 11:01:09 +01:00
parent ef8bb4e7e7
commit 1834013f3e
3 changed files with 170 additions and 124 deletions

View File

@ -25,22 +25,23 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/watch" "k8s.io/apimachinery/pkg/watch"
"k8s.io/apiserver/pkg/apis/example"
) )
func TestDecoratedWatcher(t *testing.T) { func TestDecoratedWatcher(t *testing.T) {
w := watch.NewFake() w := watch.NewFake()
decorator := func(obj runtime.Object) error { decorator := func(obj runtime.Object) error {
pod := obj.(*api.Pod) pod := obj.(*example.Pod)
pod.Annotations = map[string]string{"decorated": "true"} pod.Annotations = map[string]string{"decorated": "true"}
return nil return nil
} }
dw := newDecoratedWatcher(w, decorator) dw := newDecoratedWatcher(w, decorator)
defer dw.Stop() defer dw.Stop()
go w.Add(&api.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}) go w.Add(&example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}})
select { select {
case e := <-dw.ResultChan(): case e := <-dw.ResultChan():
pod, ok := e.Object.(*api.Pod) pod, ok := e.Object.(*example.Pod)
if !ok { if !ok {
t.Errorf("Should received object of type *api.Pod, get type (%T)", e.Object) t.Errorf("Should received object of type *api.Pod, get type (%T)", e.Object)
return return
@ -62,7 +63,7 @@ func TestDecoratedWatcherError(t *testing.T) {
dw := newDecoratedWatcher(w, decorator) dw := newDecoratedWatcher(w, decorator)
defer dw.Stop() defer dw.Stop()
go w.Add(&api.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}) go w.Add(&example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}})
select { select {
case e := <-dw.ResultChan(): case e := <-dw.ResultChan():
if e.Type != watch.Error { if e.Type != watch.Error {

View File

@ -29,28 +29,38 @@ import (
apiequality "k8s.io/apimachinery/pkg/api/equality" apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
apitesting "k8s.io/apimachinery/pkg/api/testing"
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/selection" "k8s.io/apimachinery/pkg/selection"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apiserver/pkg/apis/example"
examplev1 "k8s.io/apiserver/pkg/apis/example/v1"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request" genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/storage" "k8s.io/apiserver/pkg/storage"
"k8s.io/apiserver/pkg/storage/names" "k8s.io/apiserver/pkg/storage/names"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/genericapiserver/registry/generic" "k8s.io/kubernetes/pkg/genericapiserver/registry/generic"
"k8s.io/kubernetes/pkg/genericapiserver/registry/rest" "k8s.io/kubernetes/pkg/genericapiserver/registry/rest"
"k8s.io/kubernetes/pkg/registry/core/pod"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing" etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
"k8s.io/kubernetes/pkg/storage/storagebackend/factory" "k8s.io/kubernetes/pkg/storage/storagebackend/factory"
storagetesting "k8s.io/kubernetes/pkg/storage/testing" storagetesting "k8s.io/kubernetes/pkg/storage/testing"
) )
var scheme = runtime.NewScheme()
var codecs = serializer.NewCodecFactory(scheme)
func init() {
metav1.AddToGroupVersion(scheme, metav1.SchemeGroupVersion)
example.AddToScheme(scheme)
examplev1.AddToScheme(scheme)
}
type testGracefulStrategy struct { type testGracefulStrategy struct {
testRESTStrategy testRESTStrategy
} }
@ -104,11 +114,11 @@ func (t *testRESTStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, ol
func (t *testRESTStrategy) Canonicalize(obj runtime.Object) {} func (t *testRESTStrategy) Canonicalize(obj runtime.Object) {}
func NewTestGenericStoreRegistry(t *testing.T) (factory.DestroyFunc, *Store) { func NewTestGenericStoreRegistry(t *testing.T) (factory.DestroyFunc, *Store) {
return newTestGenericStoreRegistry(t, false) return newTestGenericStoreRegistry(t, scheme, false)
} }
func getPodAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { func getPodAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
pod := obj.(*api.Pod) pod := obj.(*example.Pod)
return labels.Set{"name": pod.ObjectMeta.Name}, nil, nil return labels.Set{"name": pod.ObjectMeta.Name}, nil, nil
} }
@ -139,20 +149,20 @@ func matchEverything() storage.SelectionPredicate {
} }
func TestStoreList(t *testing.T) { func TestStoreList(t *testing.T) {
podA := &api.Pod{ podA := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "bar"}, ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "bar"},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
podB := &api.Pod{ podB := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"}, ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test")
noNamespaceContext := genericapirequest.NewContext() noNamespaceContext := genericapirequest.NewContext()
table := map[string]struct { table := map[string]struct {
in *api.PodList in *example.PodList
m storage.SelectionPredicate m storage.SelectionPredicate
out runtime.Object out runtime.Object
context genericapirequest.Context context genericapirequest.Context
@ -160,28 +170,28 @@ func TestStoreList(t *testing.T) {
"notFound": { "notFound": {
in: nil, in: nil,
m: matchEverything(), m: matchEverything(),
out: &api.PodList{Items: []api.Pod{}}, out: &example.PodList{Items: []example.Pod{}},
}, },
"normal": { "normal": {
in: &api.PodList{Items: []api.Pod{*podA, *podB}}, in: &example.PodList{Items: []example.Pod{*podA, *podB}},
m: matchEverything(), m: matchEverything(),
out: &api.PodList{Items: []api.Pod{*podA, *podB}}, out: &example.PodList{Items: []example.Pod{*podA, *podB}},
}, },
"normalFiltered": { "normalFiltered": {
in: &api.PodList{Items: []api.Pod{*podA, *podB}}, in: &example.PodList{Items: []example.Pod{*podA, *podB}},
m: matchPodName("foo"), m: matchPodName("foo"),
out: &api.PodList{Items: []api.Pod{*podB}}, out: &example.PodList{Items: []example.Pod{*podB}},
}, },
"normalFilteredNoNamespace": { "normalFilteredNoNamespace": {
in: &api.PodList{Items: []api.Pod{*podA, *podB}}, in: &example.PodList{Items: []example.Pod{*podA, *podB}},
m: matchPodName("foo"), m: matchPodName("foo"),
out: &api.PodList{Items: []api.Pod{*podB}}, out: &example.PodList{Items: []example.Pod{*podB}},
context: noNamespaceContext, context: noNamespaceContext,
}, },
"normalFilteredMatchMultiple": { "normalFilteredMatchMultiple": {
in: &api.PodList{Items: []api.Pod{*podA, *podB}}, in: &example.PodList{Items: []example.Pod{*podA, *podB}},
m: matchPodName("foo", "makeMatchSingleReturnFalse"), m: matchPodName("foo", "makeMatchSingleReturnFalse"),
out: &api.PodList{Items: []api.Pod{*podB}}, out: &example.PodList{Items: []example.Pod{*podB}},
}, },
} }
@ -215,17 +225,17 @@ func TestStoreList(t *testing.T) {
// TestStoreListResourceVersion tests that if List with ResourceVersion > 0, it will wait until // TestStoreListResourceVersion tests that if List with ResourceVersion > 0, it will wait until
// the results are as fresh as given version. // the results are as fresh as given version.
func TestStoreListResourceVersion(t *testing.T) { func TestStoreListResourceVersion(t *testing.T) {
fooPod := &api.Pod{ fooPod := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"}, ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
barPod := &api.Pod{ barPod := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "bar"}, ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "bar"},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test")
destroyFunc, registry := newTestGenericStoreRegistry(t, true) destroyFunc, registry := newTestGenericStoreRegistry(t, scheme, true)
defer destroyFunc() defer destroyFunc()
obj, err := registry.Create(ctx, fooPod) obj, err := registry.Create(ctx, fooPod)
@ -269,7 +279,7 @@ func TestStoreListResourceVersion(t *testing.T) {
if !ok { if !ok {
return return
} }
pl := l.(*api.PodList).Items pl := l.(*example.PodList).Items
if len(pl) != 2 { if len(pl) != 2 {
t.Errorf("Expected get 2 items, but got %d", len(pl)) t.Errorf("Expected get 2 items, but got %d", len(pl))
} }
@ -278,20 +288,21 @@ func TestStoreListResourceVersion(t *testing.T) {
func TestStoreCreate(t *testing.T) { func TestStoreCreate(t *testing.T) {
gracefulPeriod := int64(50) gracefulPeriod := int64(50)
podA := &api.Pod{ podA := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test"}, ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test"},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
podB := &api.Pod{ podB := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test"}, ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test"},
Spec: api.PodSpec{NodeName: "machine2"}, Spec: example.PodSpec{NodeName: "machine2"},
} }
testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test")
destroyFunc, registry := NewTestGenericStoreRegistry(t) destroyFunc, registry := NewTestGenericStoreRegistry(t)
defer destroyFunc() defer destroyFunc()
// re-define delete strategy to have graceful delete capability // re-define delete strategy to have graceful delete capability
registry.DeleteStrategy = pod.Strategy defaultDeleteStrategy := testRESTStrategy{scheme, names.SimpleNameGenerator, true, false, true}
registry.DeleteStrategy = testGracefulStrategy{defaultDeleteStrategy}
// create the object // create the object
objA, err := registry.Create(testContext, podA) objA, err := registry.Create(testContext, podA)
@ -342,8 +353,8 @@ func TestStoreCreate(t *testing.T) {
} }
} }
func updateAndVerify(t *testing.T, ctx genericapirequest.Context, registry *Store, pod *api.Pod) bool { func updateAndVerify(t *testing.T, ctx genericapirequest.Context, registry *Store, pod *example.Pod) bool {
obj, _, err := registry.Update(ctx, pod.Name, rest.DefaultUpdatedObjectInfo(pod, api.Scheme)) obj, _, err := registry.Update(ctx, pod.Name, rest.DefaultUpdatedObjectInfo(pod, scheme))
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
return false return false
@ -361,17 +372,17 @@ func updateAndVerify(t *testing.T, ctx genericapirequest.Context, registry *Stor
} }
func TestStoreUpdate(t *testing.T) { func TestStoreUpdate(t *testing.T) {
podA := &api.Pod{ podA := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test"}, ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test"},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
podB := &api.Pod{ podB := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test"}, ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test"},
Spec: api.PodSpec{NodeName: "machine2"}, Spec: example.PodSpec{NodeName: "machine2"},
} }
podAWithResourceVersion := &api.Pod{ podAWithResourceVersion := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "7"}, ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "7"},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test")
@ -379,7 +390,7 @@ func TestStoreUpdate(t *testing.T) {
defer destroyFunc() defer destroyFunc()
// Test1 try to update a non-existing node // Test1 try to update a non-existing node
_, _, err := registry.Update(testContext, podA.Name, rest.DefaultUpdatedObjectInfo(podA, api.Scheme)) _, _, err := registry.Update(testContext, podA.Name, rest.DefaultUpdatedObjectInfo(podA, scheme))
if !errors.IsNotFound(err) { if !errors.IsNotFound(err) {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@ -392,7 +403,7 @@ func TestStoreUpdate(t *testing.T) {
registry.UpdateStrategy.(*testRESTStrategy).allowCreateOnUpdate = false registry.UpdateStrategy.(*testRESTStrategy).allowCreateOnUpdate = false
// Test3 outofDate // Test3 outofDate
_, _, err = registry.Update(testContext, podAWithResourceVersion.Name, rest.DefaultUpdatedObjectInfo(podAWithResourceVersion, api.Scheme)) _, _, err = registry.Update(testContext, podAWithResourceVersion.Name, rest.DefaultUpdatedObjectInfo(podAWithResourceVersion, scheme))
if !errors.IsConflict(err) { if !errors.IsConflict(err) {
t.Errorf("Unexpected error updating podAWithResourceVersion: %v", err) t.Errorf("Unexpected error updating podAWithResourceVersion: %v", err)
} }
@ -416,14 +427,14 @@ func TestNoOpUpdates(t *testing.T) {
destroyFunc, registry := NewTestGenericStoreRegistry(t) destroyFunc, registry := NewTestGenericStoreRegistry(t)
defer destroyFunc() defer destroyFunc()
newPod := func() *api.Pod { newPod := func() *example.Pod {
return &api.Pod{ return &example.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Namespace: metav1.NamespaceDefault, Namespace: metav1.NamespaceDefault,
Name: "foo", Name: "foo",
Labels: map[string]string{"prepare_create": "true"}, Labels: map[string]string{"prepare_create": "true"},
}, },
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
} }
@ -440,7 +451,7 @@ func TestNoOpUpdates(t *testing.T) {
var updateResult runtime.Object var updateResult runtime.Object
p := newPod() p := newPod()
if updateResult, _, err = registry.Update(genericapirequest.NewDefaultContext(), p.Name, rest.DefaultUpdatedObjectInfo(p, api.Scheme)); err != nil { if updateResult, _, err = registry.Update(genericapirequest.NewDefaultContext(), p.Name, rest.DefaultUpdatedObjectInfo(p, scheme)); err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
@ -475,7 +486,7 @@ func TestNoOpUpdates(t *testing.T) {
type testPodExport struct{} type testPodExport struct{}
func (t testPodExport) Export(ctx genericapirequest.Context, obj runtime.Object, exact bool) error { func (t testPodExport) Export(ctx genericapirequest.Context, obj runtime.Object, exact bool) error {
pod := obj.(*api.Pod) pod := obj.(*example.Pod)
if pod.Labels == nil { if pod.Labels == nil {
pod.Labels = map[string]string{} pod.Labels = map[string]string{}
} }
@ -486,13 +497,13 @@ func (t testPodExport) Export(ctx genericapirequest.Context, obj runtime.Object,
} }
func TestStoreCustomExport(t *testing.T) { func TestStoreCustomExport(t *testing.T) {
podA := api.Pod{ podA := example.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Namespace: "test", Namespace: "test",
Name: "foo", Name: "foo",
Labels: map[string]string{}, Labels: map[string]string{},
}, },
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
destroyFunc, registry := NewTestGenericStoreRegistry(t) destroyFunc, registry := NewTestGenericStoreRegistry(t)
@ -510,7 +521,7 @@ func TestStoreCustomExport(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
exportedPod := obj.(*api.Pod) exportedPod := obj.(*example.Pod)
if exportedPod.Labels["exported"] != "true" { if exportedPod.Labels["exported"] != "true" {
t.Errorf("expected: exported->true, found: %s", exportedPod.Labels["exported"]) t.Errorf("expected: exported->true, found: %s", exportedPod.Labels["exported"])
} }
@ -531,14 +542,14 @@ func TestStoreCustomExport(t *testing.T) {
} }
func TestStoreBasicExport(t *testing.T) { func TestStoreBasicExport(t *testing.T) {
podA := api.Pod{ podA := example.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Namespace: "test", Namespace: "test",
Name: "foo", Name: "foo",
Labels: map[string]string{}, Labels: map[string]string{},
}, },
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
Status: api.PodStatus{HostIP: "1.2.3.4"}, Status: example.PodStatus{HostIP: "1.2.3.4"},
} }
destroyFunc, registry := NewTestGenericStoreRegistry(t) destroyFunc, registry := NewTestGenericStoreRegistry(t)
@ -554,7 +565,7 @@ func TestStoreBasicExport(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
exportedPod := obj.(*api.Pod) exportedPod := obj.(*example.Pod)
if exportedPod.Labels["prepare_create"] != "true" { if exportedPod.Labels["prepare_create"] != "true" {
t.Errorf("expected: prepare_create->true, found: %s", exportedPod.Labels["prepare_create"]) t.Errorf("expected: prepare_create->true, found: %s", exportedPod.Labels["prepare_create"])
} }
@ -567,9 +578,9 @@ func TestStoreBasicExport(t *testing.T) {
} }
func TestStoreGet(t *testing.T) { func TestStoreGet(t *testing.T) {
podA := &api.Pod{ podA := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"}, ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test")
@ -588,9 +599,9 @@ func TestStoreGet(t *testing.T) {
} }
func TestStoreDelete(t *testing.T) { func TestStoreDelete(t *testing.T) {
podA := &api.Pod{ podA := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo"}, ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test")
@ -630,20 +641,20 @@ func TestGracefulStoreCanDeleteIfExistingGracePeriodZero(t *testing.T) {
deletionTimestamp := metav1.NewTime(time.Now()) deletionTimestamp := metav1.NewTime(time.Now())
deletionGracePeriodSeconds := int64(0) deletionGracePeriodSeconds := int64(0)
initialGeneration := int64(1) initialGeneration := int64(1)
pod := &api.Pod{ pod := &example.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "foo", Name: "foo",
Generation: initialGeneration, Generation: initialGeneration,
DeletionGracePeriodSeconds: &deletionGracePeriodSeconds, DeletionGracePeriodSeconds: &deletionGracePeriodSeconds,
DeletionTimestamp: &deletionTimestamp, DeletionTimestamp: &deletionTimestamp,
}, },
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test")
destroyFunc, registry := NewTestGenericStoreRegistry(t) destroyFunc, registry := NewTestGenericStoreRegistry(t)
registry.EnableGarbageCollection = false registry.EnableGarbageCollection = false
defaultDeleteStrategy := testRESTStrategy{api.Scheme, names.SimpleNameGenerator, true, false, true} defaultDeleteStrategy := testRESTStrategy{scheme, names.SimpleNameGenerator, true, false, true}
registry.DeleteStrategy = testGracefulStrategy{defaultDeleteStrategy} registry.DeleteStrategy = testGracefulStrategy{defaultDeleteStrategy}
defer destroyFunc() defer destroyFunc()
@ -661,15 +672,15 @@ func TestGracefulStoreCanDeleteIfExistingGracePeriodZero(t *testing.T) {
func TestGracefulStoreHandleFinalizers(t *testing.T) { func TestGracefulStoreHandleFinalizers(t *testing.T) {
initialGeneration := int64(1) initialGeneration := int64(1)
podWithFinalizer := &api.Pod{ podWithFinalizer := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Finalizers: []string{"foo.com/x"}, Generation: initialGeneration}, ObjectMeta: metav1.ObjectMeta{Name: "foo", Finalizers: []string{"foo.com/x"}, Generation: initialGeneration},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test")
destroyFunc, registry := NewTestGenericStoreRegistry(t) destroyFunc, registry := NewTestGenericStoreRegistry(t)
registry.EnableGarbageCollection = true registry.EnableGarbageCollection = true
defaultDeleteStrategy := testRESTStrategy{api.Scheme, names.SimpleNameGenerator, true, false, true} defaultDeleteStrategy := testRESTStrategy{scheme, names.SimpleNameGenerator, true, false, true}
registry.DeleteStrategy = testGracefulStrategy{defaultDeleteStrategy} registry.DeleteStrategy = testGracefulStrategy{defaultDeleteStrategy}
defer destroyFunc() defer destroyFunc()
// create pod // create pod
@ -688,11 +699,11 @@ func TestGracefulStoreHandleFinalizers(t *testing.T) {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
updatedPodWithFinalizer := &api.Pod{ updatedPodWithFinalizer := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Finalizers: []string{"foo.com/x"}, ResourceVersion: podWithFinalizer.ObjectMeta.ResourceVersion}, ObjectMeta: metav1.ObjectMeta{Name: "foo", Finalizers: []string{"foo.com/x"}, ResourceVersion: podWithFinalizer.ObjectMeta.ResourceVersion},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
_, _, err = registry.Update(testContext, updatedPodWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(updatedPodWithFinalizer, api.Scheme)) _, _, err = registry.Update(testContext, updatedPodWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(updatedPodWithFinalizer, scheme))
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
@ -703,11 +714,11 @@ func TestGracefulStoreHandleFinalizers(t *testing.T) {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
podWithNoFinalizer := &api.Pod{ podWithNoFinalizer := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: podWithFinalizer.ObjectMeta.ResourceVersion}, ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: podWithFinalizer.ObjectMeta.ResourceVersion},
Spec: api.PodSpec{NodeName: "anothermachine"}, Spec: example.PodSpec{NodeName: "anothermachine"},
} }
_, _, err = registry.Update(testContext, podWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(podWithNoFinalizer, api.Scheme)) _, _, err = registry.Update(testContext, podWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(podWithNoFinalizer, scheme))
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
@ -720,9 +731,9 @@ func TestGracefulStoreHandleFinalizers(t *testing.T) {
func TestNonGracefulStoreHandleFinalizers(t *testing.T) { func TestNonGracefulStoreHandleFinalizers(t *testing.T) {
initialGeneration := int64(1) initialGeneration := int64(1)
podWithFinalizer := &api.Pod{ podWithFinalizer := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Finalizers: []string{"foo.com/x"}, Generation: initialGeneration}, ObjectMeta: metav1.ObjectMeta{Name: "foo", Finalizers: []string{"foo.com/x"}, Generation: initialGeneration},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test")
@ -746,7 +757,7 @@ func TestNonGracefulStoreHandleFinalizers(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
podWithFinalizer, ok := obj.(*api.Pod) podWithFinalizer, ok := obj.(*example.Pod)
if !ok { if !ok {
t.Errorf("Unexpected object: %#v", obj) t.Errorf("Unexpected object: %#v", obj)
} }
@ -760,11 +771,11 @@ func TestNonGracefulStoreHandleFinalizers(t *testing.T) {
t.Errorf("Deletion didn't increase Generation.") t.Errorf("Deletion didn't increase Generation.")
} }
updatedPodWithFinalizer := &api.Pod{ updatedPodWithFinalizer := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Finalizers: []string{"foo.com/x"}, ResourceVersion: podWithFinalizer.ObjectMeta.ResourceVersion}, ObjectMeta: metav1.ObjectMeta{Name: "foo", Finalizers: []string{"foo.com/x"}, ResourceVersion: podWithFinalizer.ObjectMeta.ResourceVersion},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
_, _, err = registry.Update(testContext, updatedPodWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(updatedPodWithFinalizer, api.Scheme)) _, _, err = registry.Update(testContext, updatedPodWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(updatedPodWithFinalizer, scheme))
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@ -774,16 +785,16 @@ func TestNonGracefulStoreHandleFinalizers(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
podWithFinalizer, ok = obj.(*api.Pod) podWithFinalizer, ok = obj.(*example.Pod)
if !ok { if !ok {
t.Errorf("Unexpected object: %#v", obj) t.Errorf("Unexpected object: %#v", obj)
} }
podWithNoFinalizer := &api.Pod{ podWithNoFinalizer := &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: podWithFinalizer.ObjectMeta.ResourceVersion}, ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: podWithFinalizer.ObjectMeta.ResourceVersion},
Spec: api.PodSpec{NodeName: "anothermachine"}, Spec: example.PodSpec{NodeName: "anothermachine"},
} }
_, _, err = registry.Update(testContext, podWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(podWithNoFinalizer, api.Scheme)) _, _, err = registry.Update(testContext, podWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(podWithNoFinalizer, scheme))
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@ -796,28 +807,28 @@ func TestNonGracefulStoreHandleFinalizers(t *testing.T) {
func TestStoreDeleteWithOrphanDependents(t *testing.T) { func TestStoreDeleteWithOrphanDependents(t *testing.T) {
initialGeneration := int64(1) initialGeneration := int64(1)
podWithOrphanFinalizer := func(name string) *api.Pod { podWithOrphanFinalizer := func(name string) *example.Pod {
return &api.Pod{ return &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: name, Finalizers: []string{"foo.com/x", metav1.FinalizerOrphan, "bar.com/y"}, Generation: initialGeneration}, ObjectMeta: metav1.ObjectMeta{Name: name, Finalizers: []string{"foo.com/x", metav1.FinalizerOrphan, "bar.com/y"}, Generation: initialGeneration},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
} }
podWithOtherFinalizers := func(name string) *api.Pod { podWithOtherFinalizers := func(name string) *example.Pod {
return &api.Pod{ return &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: name, Finalizers: []string{"foo.com/x", "bar.com/y"}, Generation: initialGeneration}, ObjectMeta: metav1.ObjectMeta{Name: name, Finalizers: []string{"foo.com/x", "bar.com/y"}, Generation: initialGeneration},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
} }
podWithNoFinalizer := func(name string) *api.Pod { podWithNoFinalizer := func(name string) *example.Pod {
return &api.Pod{ return &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: name, Generation: initialGeneration}, ObjectMeta: metav1.ObjectMeta{Name: name, Generation: initialGeneration},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
} }
podWithOnlyOrphanFinalizer := func(name string) *api.Pod { podWithOnlyOrphanFinalizer := func(name string) *example.Pod {
return &api.Pod{ return &example.Pod{
ObjectMeta: metav1.ObjectMeta{Name: name, Finalizers: []string{metav1.FinalizerOrphan}, Generation: initialGeneration}, ObjectMeta: metav1.ObjectMeta{Name: name, Finalizers: []string{metav1.FinalizerOrphan}, Generation: initialGeneration},
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
} }
trueVar, falseVar := true, false trueVar, falseVar := true, false
@ -826,13 +837,13 @@ func TestStoreDeleteWithOrphanDependents(t *testing.T) {
nilOrphanOptions := &metav1.DeleteOptions{} nilOrphanOptions := &metav1.DeleteOptions{}
// defaultDeleteStrategy doesn't implement rest.GarbageCollectionDeleteStrategy. // defaultDeleteStrategy doesn't implement rest.GarbageCollectionDeleteStrategy.
defaultDeleteStrategy := &testRESTStrategy{api.Scheme, names.SimpleNameGenerator, true, false, true} defaultDeleteStrategy := &testRESTStrategy{scheme, names.SimpleNameGenerator, true, false, true}
// orphanDeleteStrategy indicates the default garbage collection policy is // orphanDeleteStrategy indicates the default garbage collection policy is
// to orphan dependentes. // to orphan dependentes.
orphanDeleteStrategy := &testOrphanDeleteStrategy{defaultDeleteStrategy} orphanDeleteStrategy := &testOrphanDeleteStrategy{defaultDeleteStrategy}
testcases := []struct { testcases := []struct {
pod *api.Pod pod *example.Pod
options *metav1.DeleteOptions options *metav1.DeleteOptions
strategy rest.RESTDeleteStrategy strategy rest.RESTDeleteStrategy
expectNotFound bool expectNotFound bool
@ -1044,7 +1055,7 @@ func TestStoreDeleteWithOrphanDependents(t *testing.T) {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
if !tc.expectNotFound { if !tc.expectNotFound {
pod, ok := obj.(*api.Pod) pod, ok := obj.(*example.Pod)
if !ok { if !ok {
t.Fatalf("Expect the object to be a pod, but got %#v", obj) t.Fatalf("Expect the object to be a pod, but got %#v", obj)
} }
@ -1065,8 +1076,8 @@ func TestStoreDeleteWithOrphanDependents(t *testing.T) {
} }
func TestStoreDeleteCollection(t *testing.T) { func TestStoreDeleteCollection(t *testing.T) {
podA := &api.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}} podA := &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
podB := &api.Pod{ObjectMeta: metav1.ObjectMeta{Name: "bar"}} podB := &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "bar"}}
testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test")
destroyFunc, registry := NewTestGenericStoreRegistry(t) destroyFunc, registry := NewTestGenericStoreRegistry(t)
@ -1084,7 +1095,7 @@ func TestStoreDeleteCollection(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
deletedPods := deleted.(*api.PodList) deletedPods := deleted.(*example.PodList)
if len(deletedPods.Items) != 2 { if len(deletedPods.Items) != 2 {
t.Errorf("Unexpected number of pods deleted: %d, expected: 2", len(deletedPods.Items)) t.Errorf("Unexpected number of pods deleted: %d, expected: 2", len(deletedPods.Items))
} }
@ -1103,8 +1114,8 @@ func TestStoreDeleteCollectionNotFound(t *testing.T) {
testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test")
podA := &api.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}} podA := &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
podB := &api.Pod{ObjectMeta: metav1.ObjectMeta{Name: "bar"}} podB := &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "bar"}}
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
// Setup // Setup
@ -1141,7 +1152,7 @@ func TestStoreDeleteCollectionNotFound(t *testing.T) {
// Test whether objects deleted with DeleteCollection are correctly delivered // Test whether objects deleted with DeleteCollection are correctly delivered
// to watchers. // to watchers.
func TestStoreDeleteCollectionWithWatch(t *testing.T) { func TestStoreDeleteCollectionWithWatch(t *testing.T) {
podA := &api.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}} podA := &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test")
destroyFunc, registry := NewTestGenericStoreRegistry(t) destroyFunc, registry := NewTestGenericStoreRegistry(t)
@ -1151,7 +1162,7 @@ func TestStoreDeleteCollectionWithWatch(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
podCreated := objCreated.(*api.Pod) podCreated := objCreated.(*example.Pod)
watcher, err := registry.WatchPredicate(testContext, matchPodName("foo"), podCreated.ResourceVersion) watcher, err := registry.WatchPredicate(testContext, matchPodName("foo"), podCreated.ResourceVersion)
if err != nil { if err != nil {
@ -1170,7 +1181,7 @@ func TestStoreDeleteCollectionWithWatch(t *testing.T) {
if got.Type != "DELETED" { if got.Type != "DELETED" {
t.Errorf("Unexpected event type: %s", got.Type) t.Errorf("Unexpected event type: %s", got.Type)
} }
gotObject := got.Object.(*api.Pod) gotObject := got.Object.(*example.Pod)
gotObject.ResourceVersion = podCreated.ResourceVersion gotObject.ResourceVersion = podCreated.ResourceVersion
if e, a := podCreated, gotObject; !reflect.DeepEqual(e, a) { if e, a := podCreated, gotObject; !reflect.DeepEqual(e, a) {
t.Errorf("Expected: %#v, got: %#v", e, a) t.Errorf("Expected: %#v, got: %#v", e, a)
@ -1203,12 +1214,12 @@ func TestStoreWatch(t *testing.T) {
if m.context != nil { if m.context != nil {
ctx = m.context ctx = m.context
} }
podA := &api.Pod{ podA := &example.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: "test", Namespace: "test",
}, },
Spec: api.PodSpec{NodeName: "machine"}, Spec: example.PodSpec{NodeName: "machine"},
} }
destroyFunc, registry := NewTestGenericStoreRegistry(t) destroyFunc, registry := NewTestGenericStoreRegistry(t)
@ -1233,12 +1244,12 @@ func TestStoreWatch(t *testing.T) {
} }
} }
func newTestGenericStoreRegistry(t *testing.T, hasCacheEnabled bool) (factory.DestroyFunc, *Store) { func newTestGenericStoreRegistry(t *testing.T, scheme *runtime.Scheme, hasCacheEnabled bool) (factory.DestroyFunc, *Store) {
podPrefix := "/pods" podPrefix := "/pods"
server, sc := etcdtesting.NewUnsecuredEtcd3TestClientServer(t, api.Scheme) server, sc := etcdtesting.NewUnsecuredEtcd3TestClientServer(t, scheme)
strategy := &testRESTStrategy{api.Scheme, names.SimpleNameGenerator, true, false, true} strategy := &testRESTStrategy{scheme, names.SimpleNameGenerator, true, false, true}
sc.Codec = testapi.Default.StorageCodec() sc.Codec = apitesting.TestStorageCodec(codecs, examplev1.SchemeGroupVersion)
s, dFunc, err := factory.Create(*sc) s, dFunc, err := factory.Create(*sc)
if err != nil { if err != nil {
t.Fatalf("Error creating storage: %v", err) t.Fatalf("Error creating storage: %v", err)
@ -1252,12 +1263,12 @@ func newTestGenericStoreRegistry(t *testing.T, hasCacheEnabled bool) (factory.De
CacheCapacity: 10, CacheCapacity: 10,
Storage: s, Storage: s,
Versioner: etcdstorage.APIObjectVersioner{}, Versioner: etcdstorage.APIObjectVersioner{},
Copier: api.Scheme, Copier: scheme,
Type: &api.Pod{}, Type: &example.Pod{},
ResourcePrefix: podPrefix, ResourcePrefix: podPrefix,
KeyFunc: func(obj runtime.Object) (string, error) { return storage.NoNamespaceKeyFunc(podPrefix, obj) }, KeyFunc: func(obj runtime.Object) (string, error) { return storage.NoNamespaceKeyFunc(podPrefix, obj) },
GetAttrsFunc: getPodAttrs, GetAttrsFunc: getPodAttrs,
NewListFunc: func() runtime.Object { return &api.PodList{} }, NewListFunc: func() runtime.Object { return &example.PodList{} },
Codec: sc.Codec, Codec: sc.Codec,
} }
cacher := storage.NewCacherFromConfig(config) cacher := storage.NewCacherFromConfig(config)
@ -1270,10 +1281,10 @@ func newTestGenericStoreRegistry(t *testing.T, hasCacheEnabled bool) (factory.De
} }
return destroyFunc, &Store{ return destroyFunc, &Store{
Copier: api.Scheme, Copier: scheme,
NewFunc: func() runtime.Object { return &api.Pod{} }, NewFunc: func() runtime.Object { return &example.Pod{} },
NewListFunc: func() runtime.Object { return &api.PodList{} }, NewListFunc: func() runtime.Object { return &example.PodList{} },
QualifiedResource: api.Resource("pods"), QualifiedResource: example.Resource("pods"),
CreateStrategy: strategy, CreateStrategy: strategy,
UpdateStrategy: strategy, UpdateStrategy: strategy,
DeleteStrategy: strategy, DeleteStrategy: strategy,
@ -1286,13 +1297,13 @@ func newTestGenericStoreRegistry(t *testing.T, hasCacheEnabled bool) (factory.De
} }
return path.Join(podPrefix, id), nil return path.Join(podPrefix, id), nil
}, },
ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.Pod).Name, nil }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*example.Pod).Name, nil },
PredicateFunc: func(label labels.Selector, field fields.Selector) storage.SelectionPredicate { PredicateFunc: func(label labels.Selector, field fields.Selector) storage.SelectionPredicate {
return storage.SelectionPredicate{ return storage.SelectionPredicate{
Label: label, Label: label,
Field: field, Field: field,
GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
pod, ok := obj.(*api.Pod) pod, ok := obj.(*example.Pod)
if !ok { if !ok {
return nil, nil, fmt.Errorf("not a pod") return nil, nil, fmt.Errorf("not a pod")
} }

View File

@ -24,29 +24,63 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/recognizer"
) )
var testCodecMediaType string var (
testCodecMediaType string
testStorageCodecMediaType string
)
// TestCodec returns the codec for the API version to test against, as set by the // TestCodec returns the codec for the API version to test against, as set by the
// KUBE_TEST_API_TYPE env var. // KUBE_TEST_API_TYPE env var.
func TestCodec(codecs runtimeserializer.CodecFactory, gvs ...schema.GroupVersion) runtime.Codec { func TestCodec(codecs runtimeserializer.CodecFactory, gvs ...schema.GroupVersion) runtime.Codec {
if len(testCodecMediaType) != 0 { if len(testCodecMediaType) != 0 {
serializer, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), testCodecMediaType) serializerInfo, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), testCodecMediaType)
if !ok { if !ok {
panic(fmt.Sprintf("no serializer for %s", testCodecMediaType)) panic(fmt.Sprintf("no serializer for %s", testCodecMediaType))
} }
return codecs.CodecForVersions(serializer.Serializer, codecs.UniversalDeserializer(), schema.GroupVersions(gvs), nil) return codecs.CodecForVersions(serializerInfo.Serializer, codecs.UniversalDeserializer(), schema.GroupVersions(gvs), nil)
}
return codecs.LegacyCodec(gvs...)
}
// TestStorageCodec returns the codec for the API version to test against used in storage, as set by the
// KUBE_TEST_API_STORAGE_TYPE env var.
func TestStorageCodec(codecs runtimeserializer.CodecFactory, gvs ...schema.GroupVersion) runtime.Codec {
if len(testStorageCodecMediaType) != 0 {
serializerInfo, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), testStorageCodecMediaType)
if !ok {
panic(fmt.Sprintf("no serializer for %s", testStorageCodecMediaType))
}
// etcd2 only supports string data - we must wrap any result before returning
// TODO: remove for etcd3 / make parameterizable
serializer := serializerInfo.Serializer
if !serializerInfo.EncodesAsText {
serializer = runtime.NewBase64Serializer(serializer)
}
decoder := recognizer.NewDecoder(serializer, codecs.UniversalDeserializer())
return codecs.CodecForVersions(serializer, decoder, schema.GroupVersions(gvs), nil)
} }
return codecs.LegacyCodec(gvs...) return codecs.LegacyCodec(gvs...)
} }
func init() { func init() {
if apiMediaType := os.Getenv("KUBE_TEST_API_TYPE"); len(apiMediaType) > 0 {
var err error var err error
if apiMediaType := os.Getenv("KUBE_TEST_API_TYPE"); len(apiMediaType) > 0 {
testCodecMediaType, _, err = mime.ParseMediaType(apiMediaType) testCodecMediaType, _, err = mime.ParseMediaType(apiMediaType)
if err != nil { if err != nil {
panic(err) panic(err)
} }
} }
if storageMediaType := os.Getenv("KUBE_TEST_API_STORAGE_TYPE"); len(storageMediaType) > 0 {
testStorageCodecMediaType, _, err = mime.ParseMediaType(storageMediaType)
if err != nil {
panic(err)
}
}
} }