apiserver: simplify deepcopy calls

Kubernetes-commit: b2442224e79f480409806c2ccfa24a9acb708162
This commit is contained in:
Dr. Stefan Schimanski 2017-08-15 14:09:00 +02:00 committed by Kubernetes Publisher
parent f05a9d559d
commit 1e4465a8e7
9 changed files with 92 additions and 159 deletions

View File

@ -490,11 +490,7 @@ func (storage *SimpleRESTStorage) Get(ctx request.Context, id string, options *m
if id == "binary" { if id == "binary" {
return storage.stream, storage.errors["get"] return storage.stream, storage.errors["get"]
} }
copied, err := scheme.Copy(&storage.item) return storage.item.DeepCopy(), storage.errors["get"]
if err != nil {
panic(err)
}
return copied, storage.errors["get"]
} }
func (storage *SimpleRESTStorage) checkContext(ctx request.Context) { func (storage *SimpleRESTStorage) checkContext(ctx request.Context) {
@ -748,11 +744,7 @@ func (storage *SimpleTypedStorage) New() runtime.Object {
func (storage *SimpleTypedStorage) Get(ctx request.Context, id string, options *metav1.GetOptions) (runtime.Object, error) { func (storage *SimpleTypedStorage) Get(ctx request.Context, id string, options *metav1.GetOptions) (runtime.Object, error) {
storage.checkContext(ctx) storage.checkContext(ctx)
copied, err := scheme.Copy(storage.item) return storage.item.DeepCopyObject(), storage.errors["get"]
if err != nil {
panic(err)
}
return copied, storage.errors["get"]
} }
func (storage *SimpleTypedStorage) checkContext(ctx request.Context) { func (storage *SimpleTypedStorage) checkContext(ctx request.Context) {
@ -3876,11 +3868,7 @@ func (storage *SimpleXGSubresourceRESTStorage) New() runtime.Object {
} }
func (storage *SimpleXGSubresourceRESTStorage) Get(ctx request.Context, id string, options *metav1.GetOptions) (runtime.Object, error) { func (storage *SimpleXGSubresourceRESTStorage) Get(ctx request.Context, id string, options *metav1.GetOptions) (runtime.Object, error) {
copied, err := scheme.Copy(&storage.item) return storage.item.DeepCopyObject(), nil
if err != nil {
panic(err)
}
return copied, nil
} }
func TestXGSubresource(t *testing.T) { func TestXGSubresource(t *testing.T) {

View File

@ -16,4 +16,4 @@ limitations under the License.
// +k8s:deepcopy-gen=package // +k8s:deepcopy-gen=package
package testing // import "k8s.io/apiserver/pkg/endpoints/testing" package testing

View File

@ -1048,18 +1048,6 @@ func (e *Store) Delete(ctx genericapirequest.Context, name string, options *meta
return out, true, err return out, true, err
} }
// copyListOptions copies list options for mutation.
func copyListOptions(options *metainternalversion.ListOptions) *metainternalversion.ListOptions {
if options == nil {
return &metainternalversion.ListOptions{}
}
copied, err := metainternalversion.Copier.Copy(options)
if err != nil {
panic(err)
}
return copied.(*metainternalversion.ListOptions)
}
// DeleteCollection removes all items returned by List with a given ListOptions from storage. // DeleteCollection removes all items returned by List with a given ListOptions from storage.
// //
// DeleteCollection is currently NOT atomic. It can happen that only subset of objects // DeleteCollection is currently NOT atomic. It can happen that only subset of objects
@ -1071,10 +1059,15 @@ func copyListOptions(options *metainternalversion.ListOptions) *metainternalvers
// possibly with storage API, but watch is not delivered correctly then). // possibly with storage API, but watch is not delivered correctly then).
// It will be possible to fix it with v3 etcd API. // It will be possible to fix it with v3 etcd API.
func (e *Store) DeleteCollection(ctx genericapirequest.Context, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) { func (e *Store) DeleteCollection(ctx genericapirequest.Context, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) {
if listOptions == nil {
listOptions = &metainternalversion.ListOptions{}
} else {
listOptions = listOptions.DeepCopy()
}
// DeleteCollection must remain backwards compatible with old clients that expect it to // DeleteCollection must remain backwards compatible with old clients that expect it to
// remove all resources, initialized or not, within the type. It is also consistent with // remove all resources, initialized or not, within the type. It is also consistent with
// Delete which does not require IncludeUninitialized // Delete which does not require IncludeUninitialized
listOptions = copyListOptions(listOptions)
listOptions.IncludeUninitialized = true listOptions.IncludeUninitialized = true
listObj, err := e.List(ctx, listOptions) listObj, err := e.List(ctx, listOptions)

View File

@ -128,14 +128,6 @@ func (t *Tester) setObjectMeta(obj runtime.Object, name string) {
meta.SetGeneration(1) meta.SetGeneration(1)
} }
func copyOrDie(obj runtime.Object, copier runtime.ObjectCopier) runtime.Object {
out, err := copier.Copy(obj)
if err != nil {
panic(err)
}
return out
}
type AssignFunc func([]runtime.Object) []runtime.Object type AssignFunc func([]runtime.Object) []runtime.Object
type EmitFunc func(runtime.Object, string) error type EmitFunc func(runtime.Object, string) error
type GetFunc func(genericapirequest.Context, runtime.Object) (runtime.Object, error) type GetFunc func(genericapirequest.Context, runtime.Object) (runtime.Object, error)
@ -148,81 +140,81 @@ type UpdateFunc func(runtime.Object) runtime.Object
// Test creating an object. // Test creating an object.
func (t *Tester) TestCreate(valid runtime.Object, createFn CreateFunc, getFn GetFunc, invalid ...runtime.Object) { func (t *Tester) TestCreate(valid runtime.Object, createFn CreateFunc, getFn GetFunc, invalid ...runtime.Object) {
t.testCreateHasMetadata(copyOrDie(valid, t.scheme)) t.testCreateHasMetadata(valid.DeepCopyObject())
if !t.generatesName { if !t.generatesName {
t.testCreateGeneratesName(copyOrDie(valid, t.scheme)) t.testCreateGeneratesName(valid.DeepCopyObject())
} }
t.testCreateEquals(copyOrDie(valid, t.scheme), getFn) t.testCreateEquals(valid.DeepCopyObject(), getFn)
t.testCreateAlreadyExisting(copyOrDie(valid, t.scheme), createFn) t.testCreateAlreadyExisting(valid.DeepCopyObject(), createFn)
if t.clusterScope { if t.clusterScope {
t.testCreateDiscardsObjectNamespace(copyOrDie(valid, t.scheme)) t.testCreateDiscardsObjectNamespace(valid.DeepCopyObject())
t.testCreateIgnoresContextNamespace(copyOrDie(valid, t.scheme)) t.testCreateIgnoresContextNamespace(valid.DeepCopyObject())
t.testCreateIgnoresMismatchedNamespace(copyOrDie(valid, t.scheme)) t.testCreateIgnoresMismatchedNamespace(valid.DeepCopyObject())
t.testCreateResetsUserData(copyOrDie(valid, t.scheme)) t.testCreateResetsUserData(valid.DeepCopyObject())
} else { } else {
t.testCreateRejectsMismatchedNamespace(copyOrDie(valid, t.scheme)) t.testCreateRejectsMismatchedNamespace(valid.DeepCopyObject())
} }
t.testCreateInvokesValidation(invalid...) t.testCreateInvokesValidation(invalid...)
t.testCreateValidatesNames(copyOrDie(valid, t.scheme)) t.testCreateValidatesNames(valid.DeepCopyObject())
t.testCreateIgnoreClusterName(copyOrDie(valid, t.scheme)) t.testCreateIgnoreClusterName(valid.DeepCopyObject())
} }
// Test updating an object. // Test updating an object.
func (t *Tester) TestUpdate(valid runtime.Object, createFn CreateFunc, getFn GetFunc, updateFn UpdateFunc, invalidUpdateFn ...UpdateFunc) { func (t *Tester) TestUpdate(valid runtime.Object, createFn CreateFunc, getFn GetFunc, updateFn UpdateFunc, invalidUpdateFn ...UpdateFunc) {
t.testUpdateEquals(copyOrDie(valid, t.scheme), createFn, getFn, updateFn) t.testUpdateEquals(valid.DeepCopyObject(), createFn, getFn, updateFn)
t.testUpdateFailsOnVersionTooOld(copyOrDie(valid, t.scheme), createFn, getFn) t.testUpdateFailsOnVersionTooOld(valid.DeepCopyObject(), createFn, getFn)
t.testUpdateOnNotFound(copyOrDie(valid, t.scheme)) t.testUpdateOnNotFound(valid.DeepCopyObject())
if !t.clusterScope { if !t.clusterScope {
t.testUpdateRejectsMismatchedNamespace(copyOrDie(valid, t.scheme), createFn, getFn) t.testUpdateRejectsMismatchedNamespace(valid.DeepCopyObject(), createFn, getFn)
} }
t.testUpdateInvokesValidation(copyOrDie(valid, t.scheme), createFn, invalidUpdateFn...) t.testUpdateInvokesValidation(valid.DeepCopyObject(), createFn, invalidUpdateFn...)
t.testUpdateWithWrongUID(copyOrDie(valid, t.scheme), createFn, getFn) t.testUpdateWithWrongUID(valid.DeepCopyObject(), createFn, getFn)
t.testUpdateRetrievesOldObject(copyOrDie(valid, t.scheme), createFn, getFn) t.testUpdateRetrievesOldObject(valid.DeepCopyObject(), createFn, getFn)
t.testUpdatePropagatesUpdatedObjectError(copyOrDie(valid, t.scheme), createFn, getFn) t.testUpdatePropagatesUpdatedObjectError(valid.DeepCopyObject(), createFn, getFn)
t.testUpdateIgnoreGenerationUpdates(copyOrDie(valid, t.scheme), createFn, getFn) t.testUpdateIgnoreGenerationUpdates(valid.DeepCopyObject(), createFn, getFn)
t.testUpdateIgnoreClusterName(copyOrDie(valid, t.scheme), createFn, getFn) t.testUpdateIgnoreClusterName(valid.DeepCopyObject(), createFn, getFn)
} }
// Test deleting an object. // Test deleting an object.
func (t *Tester) TestDelete(valid runtime.Object, createFn CreateFunc, getFn GetFunc, isNotFoundFn IsErrorFunc) { func (t *Tester) TestDelete(valid runtime.Object, createFn CreateFunc, getFn GetFunc, isNotFoundFn IsErrorFunc) {
t.testDeleteNonExist(copyOrDie(valid, t.scheme)) t.testDeleteNonExist(valid.DeepCopyObject())
t.testDeleteNoGraceful(copyOrDie(valid, t.scheme), createFn, getFn, isNotFoundFn) t.testDeleteNoGraceful(valid.DeepCopyObject(), createFn, getFn, isNotFoundFn)
t.testDeleteWithUID(copyOrDie(valid, t.scheme), createFn, getFn, isNotFoundFn) t.testDeleteWithUID(valid.DeepCopyObject(), createFn, getFn, isNotFoundFn)
} }
// Test gracefully deleting an object. // Test gracefully deleting an object.
func (t *Tester) TestDeleteGraceful(valid runtime.Object, createFn CreateFunc, getFn GetFunc, expectedGrace int64) { func (t *Tester) TestDeleteGraceful(valid runtime.Object, createFn CreateFunc, getFn GetFunc, expectedGrace int64) {
t.testDeleteGracefulHasDefault(copyOrDie(valid, t.scheme), createFn, getFn, expectedGrace) t.testDeleteGracefulHasDefault(valid.DeepCopyObject(), createFn, getFn, expectedGrace)
t.testDeleteGracefulWithValue(copyOrDie(valid, t.scheme), createFn, getFn, expectedGrace) t.testDeleteGracefulWithValue(valid.DeepCopyObject(), createFn, getFn, expectedGrace)
t.testDeleteGracefulUsesZeroOnNil(copyOrDie(valid, t.scheme), createFn, expectedGrace) t.testDeleteGracefulUsesZeroOnNil(valid.DeepCopyObject(), createFn, expectedGrace)
t.testDeleteGracefulExtend(copyOrDie(valid, t.scheme), createFn, getFn, expectedGrace) t.testDeleteGracefulExtend(valid.DeepCopyObject(), createFn, getFn, expectedGrace)
t.testDeleteGracefulShorten(copyOrDie(valid, t.scheme), createFn, getFn, expectedGrace) t.testDeleteGracefulShorten(valid.DeepCopyObject(), createFn, getFn, expectedGrace)
t.testDeleteGracefulImmediate(copyOrDie(valid, t.scheme), createFn, getFn, expectedGrace) t.testDeleteGracefulImmediate(valid.DeepCopyObject(), createFn, getFn, expectedGrace)
} }
// Test getting object. // Test getting object.
func (t *Tester) TestGet(valid runtime.Object) { func (t *Tester) TestGet(valid runtime.Object) {
t.testGetFound(copyOrDie(valid, t.scheme)) t.testGetFound(valid.DeepCopyObject())
t.testGetNotFound(copyOrDie(valid, t.scheme)) t.testGetNotFound(valid.DeepCopyObject())
t.testGetMimatchedNamespace(copyOrDie(valid, t.scheme)) t.testGetMimatchedNamespace(valid.DeepCopyObject())
if !t.clusterScope { if !t.clusterScope {
t.testGetDifferentNamespace(copyOrDie(valid, t.scheme)) t.testGetDifferentNamespace(valid.DeepCopyObject())
} }
} }
// Test listing objects. // Test listing objects.
func (t *Tester) TestList(valid runtime.Object, assignFn AssignFunc) { func (t *Tester) TestList(valid runtime.Object, assignFn AssignFunc) {
t.testListNotFound(assignFn) t.testListNotFound(assignFn)
t.testListFound(copyOrDie(valid, t.scheme), assignFn) t.testListFound(valid.DeepCopyObject(), assignFn)
t.testListMatchLabels(copyOrDie(valid, t.scheme), assignFn) t.testListMatchLabels(valid.DeepCopyObject(), assignFn)
} }
// Test watching objects. // Test watching objects.
func (t *Tester) TestWatch( func (t *Tester) TestWatch(
valid runtime.Object, emitFn EmitFunc, valid runtime.Object, emitFn EmitFunc,
labelsPass, labelsFail []labels.Set, fieldsPass, fieldsFail []fields.Set, actions []string) { labelsPass, labelsFail []labels.Set, fieldsPass, fieldsFail []fields.Set, actions []string) {
t.testWatchLabels(copyOrDie(valid, t.scheme), emitFn, labelsPass, labelsFail, actions) t.testWatchLabels(valid.DeepCopyObject(), emitFn, labelsPass, labelsFail, actions)
t.testWatchFields(copyOrDie(valid, t.scheme), emitFn, fieldsPass, fieldsFail, actions) t.testWatchFields(valid.DeepCopyObject(), emitFn, fieldsPass, fieldsFail, actions)
} }
// ============================================================================= // =============================================================================
@ -244,7 +236,7 @@ func (t *Tester) delete(ctx genericapirequest.Context, obj runtime.Object) error
func (t *Tester) testCreateAlreadyExisting(obj runtime.Object, createFn CreateFunc) { func (t *Tester) testCreateAlreadyExisting(obj runtime.Object, createFn CreateFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, t.namer(1)) t.setObjectMeta(foo, t.namer(1))
if err := createFn(ctx, foo); err != nil { if err := createFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -260,7 +252,7 @@ func (t *Tester) testCreateAlreadyExisting(obj runtime.Object, createFn CreateFu
func (t *Tester) testCreateEquals(obj runtime.Object, getFn GetFunc) { func (t *Tester) testCreateEquals(obj runtime.Object, getFn GetFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, t.namer(2)) t.setObjectMeta(foo, t.namer(2))
created, err := t.storage.(rest.Creater).Create(ctx, foo, false) created, err := t.storage.(rest.Creater).Create(ctx, foo, false)
@ -291,7 +283,7 @@ func (t *Tester) testCreateDiscardsObjectNamespace(valid runtime.Object) {
objectMeta.SetNamespace("not-default") objectMeta.SetNamespace("not-default")
// Ideally, we'd get an error back here, but at least verify the namespace wasn't persisted // Ideally, we'd get an error back here, but at least verify the namespace wasn't persisted
created, err := t.storage.(rest.Creater).Create(t.TestContext(), copyOrDie(valid, t.scheme), false) created, err := t.storage.(rest.Creater).Create(t.TestContext(), valid.DeepCopyObject(), false)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
@ -340,7 +332,7 @@ func (t *Tester) testCreateIgnoresContextNamespace(valid runtime.Object) {
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), "not-default2") ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), "not-default2")
// Ideally, we'd get an error back here, but at least verify the namespace wasn't persisted // Ideally, we'd get an error back here, but at least verify the namespace wasn't persisted
created, err := t.storage.(rest.Creater).Create(ctx, copyOrDie(valid, t.scheme), false) created, err := t.storage.(rest.Creater).Create(ctx, valid.DeepCopyObject(), false)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
@ -359,7 +351,7 @@ func (t *Tester) testCreateIgnoresMismatchedNamespace(valid runtime.Object) {
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), "not-default2") ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), "not-default2")
// Ideally, we'd get an error back here, but at least verify the namespace wasn't persisted // Ideally, we'd get an error back here, but at least verify the namespace wasn't persisted
created, err := t.storage.(rest.Creater).Create(ctx, copyOrDie(valid, t.scheme), false) created, err := t.storage.(rest.Creater).Create(ctx, valid.DeepCopyObject(), false)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
@ -372,7 +364,7 @@ func (t *Tester) testCreateIgnoresMismatchedNamespace(valid runtime.Object) {
func (t *Tester) testCreateValidatesNames(valid runtime.Object) { func (t *Tester) testCreateValidatesNames(valid runtime.Object) {
for _, invalidName := range path.NameMayNotBe { for _, invalidName := range path.NameMayNotBe {
objCopy := copyOrDie(valid, t.scheme) objCopy := valid.DeepCopyObject()
objCopyMeta := t.getObjectMetaOrFail(objCopy) objCopyMeta := t.getObjectMetaOrFail(objCopy)
objCopyMeta.SetName(invalidName) objCopyMeta.SetName(invalidName)
@ -384,7 +376,7 @@ func (t *Tester) testCreateValidatesNames(valid runtime.Object) {
} }
for _, invalidSuffix := range path.NameMayNotContain { for _, invalidSuffix := range path.NameMayNotContain {
objCopy := copyOrDie(valid, t.scheme) objCopy := valid.DeepCopyObject()
objCopyMeta := t.getObjectMetaOrFail(objCopy) objCopyMeta := t.getObjectMetaOrFail(objCopy)
objCopyMeta.SetName(objCopyMeta.GetName() + invalidSuffix) objCopyMeta.SetName(objCopyMeta.GetName() + invalidSuffix)
@ -442,7 +434,7 @@ func (t *Tester) testCreateIgnoreClusterName(valid runtime.Object) {
objectMeta.SetName(t.namer(3)) objectMeta.SetName(t.namer(3))
objectMeta.SetClusterName("clustername-to-ignore") objectMeta.SetClusterName("clustername-to-ignore")
obj, err := t.storage.(rest.Creater).Create(t.TestContext(), copyOrDie(valid, t.scheme), false) obj, err := t.storage.(rest.Creater).Create(t.TestContext(), valid.DeepCopyObject(), false)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
@ -459,7 +451,7 @@ func (t *Tester) testCreateIgnoreClusterName(valid runtime.Object) {
func (t *Tester) testUpdateEquals(obj runtime.Object, createFn CreateFunc, getFn GetFunc, updateFn UpdateFunc) { func (t *Tester) testUpdateEquals(obj runtime.Object, createFn CreateFunc, getFn GetFunc, updateFn UpdateFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, t.namer(2)) t.setObjectMeta(foo, t.namer(2))
if err := createFn(ctx, foo); err != nil { if err := createFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -495,7 +487,7 @@ func (t *Tester) testUpdateEquals(obj runtime.Object, createFn CreateFunc, getFn
func (t *Tester) testUpdateFailsOnVersionTooOld(obj runtime.Object, createFn CreateFunc, getFn GetFunc) { func (t *Tester) testUpdateFailsOnVersionTooOld(obj runtime.Object, createFn CreateFunc, getFn GetFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, t.namer(3)) t.setObjectMeta(foo, t.namer(3))
if err := createFn(ctx, foo); err != nil { if err := createFn(ctx, foo); err != nil {
@ -507,7 +499,7 @@ func (t *Tester) testUpdateFailsOnVersionTooOld(obj runtime.Object, createFn Cre
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
older := copyOrDie(storedFoo, t.scheme) older := storedFoo.DeepCopyObject()
olderMeta := t.getObjectMetaOrFail(older) olderMeta := t.getObjectMetaOrFail(older)
olderMeta.SetResourceVersion("1") olderMeta.SetResourceVersion("1")
@ -522,14 +514,14 @@ func (t *Tester) testUpdateFailsOnVersionTooOld(obj runtime.Object, createFn Cre
func (t *Tester) testUpdateInvokesValidation(obj runtime.Object, createFn CreateFunc, invalidUpdateFn ...UpdateFunc) { func (t *Tester) testUpdateInvokesValidation(obj runtime.Object, createFn CreateFunc, invalidUpdateFn ...UpdateFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, t.namer(4)) t.setObjectMeta(foo, t.namer(4))
if err := createFn(ctx, foo); err != nil { if err := createFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
for _, update := range invalidUpdateFn { for _, update := range invalidUpdateFn {
toUpdate := update(copyOrDie(foo, t.scheme)) toUpdate := update(foo.DeepCopyObject())
toUpdateMeta := t.getObjectMetaOrFail(toUpdate) toUpdateMeta := t.getObjectMetaOrFail(toUpdate)
got, created, err := t.storage.(rest.Updater).Update(t.TestContext(), toUpdateMeta.GetName(), rest.DefaultUpdatedObjectInfo(toUpdate, t.scheme)) got, created, err := t.storage.(rest.Updater).Update(t.TestContext(), toUpdateMeta.GetName(), rest.DefaultUpdatedObjectInfo(toUpdate, t.scheme))
if got != nil || created { if got != nil || created {
@ -543,7 +535,7 @@ func (t *Tester) testUpdateInvokesValidation(obj runtime.Object, createFn Create
func (t *Tester) testUpdateWithWrongUID(obj runtime.Object, createFn CreateFunc, getFn GetFunc) { func (t *Tester) testUpdateWithWrongUID(obj runtime.Object, createFn CreateFunc, getFn GetFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, t.namer(5)) t.setObjectMeta(foo, t.namer(5))
objectMeta := t.getObjectMetaOrFail(foo) objectMeta := t.getObjectMetaOrFail(foo)
objectMeta.SetUID(types.UID("UID0000")) objectMeta.SetUID(types.UID("UID0000"))
@ -563,7 +555,7 @@ func (t *Tester) testUpdateWithWrongUID(obj runtime.Object, createFn CreateFunc,
func (t *Tester) testUpdateRetrievesOldObject(obj runtime.Object, createFn CreateFunc, getFn GetFunc) { func (t *Tester) testUpdateRetrievesOldObject(obj runtime.Object, createFn CreateFunc, getFn GetFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, t.namer(6)) t.setObjectMeta(foo, t.namer(6))
objectMeta := t.getObjectMetaOrFail(foo) objectMeta := t.getObjectMetaOrFail(foo)
objectMeta.SetAnnotations(map[string]string{"A": "1"}) objectMeta.SetAnnotations(map[string]string{"A": "1"})
@ -578,7 +570,7 @@ func (t *Tester) testUpdateRetrievesOldObject(obj runtime.Object, createFn Creat
return return
} }
storedFooWithUpdates := copyOrDie(storedFoo, t.scheme) storedFooWithUpdates := storedFoo.DeepCopyObject()
objectMeta = t.getObjectMetaOrFail(storedFooWithUpdates) objectMeta = t.getObjectMetaOrFail(storedFooWithUpdates)
objectMeta.SetAnnotations(map[string]string{"A": "2"}) objectMeta.SetAnnotations(map[string]string{"A": "2"})
@ -617,7 +609,7 @@ func (t *Tester) testUpdateRetrievesOldObject(obj runtime.Object, createFn Creat
func (t *Tester) testUpdatePropagatesUpdatedObjectError(obj runtime.Object, createFn CreateFunc, getFn GetFunc) { func (t *Tester) testUpdatePropagatesUpdatedObjectError(obj runtime.Object, createFn CreateFunc, getFn GetFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
name := t.namer(7) name := t.namer(7)
t.setObjectMeta(foo, name) t.setObjectMeta(foo, name)
if err := createFn(ctx, foo); err != nil { if err := createFn(ctx, foo); err != nil {
@ -640,7 +632,7 @@ func (t *Tester) testUpdatePropagatesUpdatedObjectError(obj runtime.Object, crea
func (t *Tester) testUpdateIgnoreGenerationUpdates(obj runtime.Object, createFn CreateFunc, getFn GetFunc) { func (t *Tester) testUpdateIgnoreGenerationUpdates(obj runtime.Object, createFn CreateFunc, getFn GetFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
name := t.namer(8) name := t.namer(8)
t.setObjectMeta(foo, name) t.setObjectMeta(foo, name)
@ -653,7 +645,7 @@ func (t *Tester) testUpdateIgnoreGenerationUpdates(obj runtime.Object, createFn
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
older := copyOrDie(storedFoo, t.scheme) older := storedFoo.DeepCopyObject()
olderMeta := t.getObjectMetaOrFail(older) olderMeta := t.getObjectMetaOrFail(older)
olderMeta.SetGeneration(2) olderMeta.SetGeneration(2)
@ -693,7 +685,7 @@ func (t *Tester) testUpdateOnNotFound(obj runtime.Object) {
func (t *Tester) testUpdateRejectsMismatchedNamespace(obj runtime.Object, createFn CreateFunc, getFn GetFunc) { func (t *Tester) testUpdateRejectsMismatchedNamespace(obj runtime.Object, createFn CreateFunc, getFn GetFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, t.namer(1)) t.setObjectMeta(foo, t.namer(1))
if err := createFn(ctx, foo); err != nil { if err := createFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -722,7 +714,7 @@ func (t *Tester) testUpdateRejectsMismatchedNamespace(obj runtime.Object, create
func (t *Tester) testUpdateIgnoreClusterName(obj runtime.Object, createFn CreateFunc, getFn GetFunc) { func (t *Tester) testUpdateIgnoreClusterName(obj runtime.Object, createFn CreateFunc, getFn GetFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
name := t.namer(9) name := t.namer(9)
t.setObjectMeta(foo, name) t.setObjectMeta(foo, name)
@ -735,7 +727,7 @@ func (t *Tester) testUpdateIgnoreClusterName(obj runtime.Object, createFn Create
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
older := copyOrDie(storedFoo, t.scheme) older := storedFoo.DeepCopyObject()
olderMeta := t.getObjectMetaOrFail(older) olderMeta := t.getObjectMetaOrFail(older)
olderMeta.SetClusterName("clustername-to-ignore") olderMeta.SetClusterName("clustername-to-ignore")
@ -760,7 +752,7 @@ func (t *Tester) testUpdateIgnoreClusterName(obj runtime.Object, createFn Create
func (t *Tester) testDeleteNoGraceful(obj runtime.Object, createFn CreateFunc, getFn GetFunc, isNotFoundFn IsErrorFunc) { func (t *Tester) testDeleteNoGraceful(obj runtime.Object, createFn CreateFunc, getFn GetFunc, isNotFoundFn IsErrorFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, t.namer(1)) t.setObjectMeta(foo, t.namer(1))
if err := createFn(ctx, foo); err != nil { if err := createFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -802,7 +794,7 @@ func (t *Tester) testDeleteNonExist(obj runtime.Object) {
func (t *Tester) testDeleteWithUID(obj runtime.Object, createFn CreateFunc, getFn GetFunc, isNotFoundFn IsErrorFunc) { func (t *Tester) testDeleteWithUID(obj runtime.Object, createFn CreateFunc, getFn GetFunc, isNotFoundFn IsErrorFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, t.namer(1)) t.setObjectMeta(foo, t.namer(1))
objectMeta := t.getObjectMetaOrFail(foo) objectMeta := t.getObjectMetaOrFail(foo)
objectMeta.SetUID(types.UID("UID0000")) objectMeta.SetUID(types.UID("UID0000"))
@ -839,7 +831,7 @@ func (t *Tester) testDeleteWithUID(obj runtime.Object, createFn CreateFunc, getF
func (t *Tester) testDeleteGracefulHasDefault(obj runtime.Object, createFn CreateFunc, getFn GetFunc, expectedGrace int64) { func (t *Tester) testDeleteGracefulHasDefault(obj runtime.Object, createFn CreateFunc, getFn GetFunc, expectedGrace int64) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, t.namer(1)) t.setObjectMeta(foo, t.namer(1))
if err := createFn(ctx, foo); err != nil { if err := createFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -873,7 +865,7 @@ func (t *Tester) testDeleteGracefulHasDefault(obj runtime.Object, createFn Creat
func (t *Tester) testDeleteGracefulWithValue(obj runtime.Object, createFn CreateFunc, getFn GetFunc, expectedGrace int64) { func (t *Tester) testDeleteGracefulWithValue(obj runtime.Object, createFn CreateFunc, getFn GetFunc, expectedGrace int64) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, t.namer(2)) t.setObjectMeta(foo, t.namer(2))
if err := createFn(ctx, foo); err != nil { if err := createFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -907,7 +899,7 @@ func (t *Tester) testDeleteGracefulWithValue(obj runtime.Object, createFn Create
func (t *Tester) testDeleteGracefulExtend(obj runtime.Object, createFn CreateFunc, getFn GetFunc, expectedGrace int64) { func (t *Tester) testDeleteGracefulExtend(obj runtime.Object, createFn CreateFunc, getFn GetFunc, expectedGrace int64) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, t.namer(3)) t.setObjectMeta(foo, t.namer(3))
if err := createFn(ctx, foo); err != nil { if err := createFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -949,7 +941,7 @@ func (t *Tester) testDeleteGracefulExtend(obj runtime.Object, createFn CreateFun
func (t *Tester) testDeleteGracefulImmediate(obj runtime.Object, createFn CreateFunc, getFn GetFunc, expectedGrace int64) { func (t *Tester) testDeleteGracefulImmediate(obj runtime.Object, createFn CreateFunc, getFn GetFunc, expectedGrace int64) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, "foo4") t.setObjectMeta(foo, "foo4")
if err := createFn(ctx, foo); err != nil { if err := createFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -992,7 +984,7 @@ func (t *Tester) testDeleteGracefulImmediate(obj runtime.Object, createFn Create
func (t *Tester) testDeleteGracefulUsesZeroOnNil(obj runtime.Object, createFn CreateFunc, expectedGrace int64) { func (t *Tester) testDeleteGracefulUsesZeroOnNil(obj runtime.Object, createFn CreateFunc, expectedGrace int64) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, t.namer(5)) t.setObjectMeta(foo, t.namer(5))
if err := createFn(ctx, foo); err != nil { if err := createFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -1014,7 +1006,7 @@ func (t *Tester) testDeleteGracefulUsesZeroOnNil(obj runtime.Object, createFn Cr
func (t *Tester) testDeleteGracefulShorten(obj runtime.Object, createFn CreateFunc, getFn GetFunc, expectedGrace int64) { func (t *Tester) testDeleteGracefulShorten(obj runtime.Object, createFn CreateFunc, getFn GetFunc, expectedGrace int64) {
ctx := t.TestContext() ctx := t.TestContext()
foo := copyOrDie(obj, t.scheme) foo := obj.DeepCopyObject()
t.setObjectMeta(foo, t.namer(6)) t.setObjectMeta(foo, t.namer(6))
if err := createFn(ctx, foo); err != nil { if err := createFn(ctx, foo); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -1189,9 +1181,9 @@ func listToItems(listObj runtime.Object) ([]runtime.Object, error) {
func (t *Tester) testListFound(obj runtime.Object, assignFn AssignFunc) { func (t *Tester) testListFound(obj runtime.Object, assignFn AssignFunc) {
ctx := t.TestContext() ctx := t.TestContext()
foo1 := copyOrDie(obj, t.scheme) foo1 := obj.DeepCopyObject()
t.setObjectMeta(foo1, t.namer(1)) t.setObjectMeta(foo1, t.namer(1))
foo2 := copyOrDie(obj, t.scheme) foo2 := obj.DeepCopyObject()
t.setObjectMeta(foo2, t.namer(2)) t.setObjectMeta(foo2, t.namer(2))
existing := assignFn([]runtime.Object{foo1, foo2}) existing := assignFn([]runtime.Object{foo1, foo2})
@ -1216,9 +1208,9 @@ func (t *Tester) testListMatchLabels(obj runtime.Object, assignFn AssignFunc) {
ctx := t.TestContext() ctx := t.TestContext()
testLabels := map[string]string{"key": "value"} testLabels := map[string]string{"key": "value"}
foo3 := copyOrDie(obj, t.scheme) foo3 := obj.DeepCopyObject()
t.setObjectMeta(foo3, "foo3") t.setObjectMeta(foo3, "foo3")
foo4 := copyOrDie(obj, t.scheme) foo4 := obj.DeepCopyObject()
foo4Meta := t.getObjectMetaOrFail(foo4) foo4Meta := t.getObjectMetaOrFail(foo4)
foo4Meta.SetName("foo4") foo4Meta.SetName("foo4")
foo4Meta.SetNamespace(genericapirequest.NamespaceValue(ctx)) foo4Meta.SetNamespace(genericapirequest.NamespaceValue(ctx))

View File

@ -172,10 +172,7 @@ func (i *defaultUpdatedObjectInfo) UpdatedObject(ctx genericapirequest.Context,
// so we don't return the original. BeforeUpdate can mutate the returned object, doing things like clearing ResourceVersion. // so we don't return the original. BeforeUpdate can mutate the returned object, doing things like clearing ResourceVersion.
// If we're re-called, we need to be able to return the pristine version. // If we're re-called, we need to be able to return the pristine version.
if newObj != nil { if newObj != nil {
newObj, err = i.copier.Copy(newObj) newObj = newObj.DeepCopyObject()
if err != nil {
return nil, err
}
} }
// Allow any configured transformers to update the new object // Allow any configured transformers to update the new object

View File

@ -543,11 +543,8 @@ func (c *Cacher) GuaranteedUpdate(
if elem, exists, err := c.watchCache.GetByKey(key); err != nil { if elem, exists, err := c.watchCache.GetByKey(key); err != nil {
glog.Errorf("GetByKey returned error: %v", err) glog.Errorf("GetByKey returned error: %v", err)
} else if exists { } else if exists {
currObj, copyErr := c.copier.Copy(elem.(*storeElement).Object) currObj := elem.(*storeElement).Object.DeepCopyObject()
if copyErr == nil { return c.storage.GuaranteedUpdate(ctx, key, ptrToType, ignoreNotFound, preconditions, tryUpdate, currObj)
return c.storage.GuaranteedUpdate(ctx, key, ptrToType, ignoreNotFound, preconditions, tryUpdate, currObj)
}
glog.Errorf("couldn't copy object: %v", copyErr)
} }
// If we couldn't get the object, fallback to no-suggestion. // If we couldn't get the object, fallback to no-suggestion.
return c.storage.GuaranteedUpdate(ctx, key, ptrToType, ignoreNotFound, preconditions, tryUpdate) return c.storage.GuaranteedUpdate(ctx, key, ptrToType, ignoreNotFound, preconditions, tryUpdate)
@ -877,26 +874,11 @@ func (c *cacheWatcher) sendWatchCacheEvent(event *watchCacheEvent) {
var watchEvent watch.Event var watchEvent watch.Event
switch { switch {
case curObjPasses && !oldObjPasses: case curObjPasses && !oldObjPasses:
object, err := c.copier.Copy(event.Object) watchEvent = watch.Event{Type: watch.Added, Object: event.Object.DeepCopyObject()}
if err != nil {
utilruntime.HandleError(fmt.Errorf("unexpected copy error: %v", err))
return
}
watchEvent = watch.Event{Type: watch.Added, Object: object}
case curObjPasses && oldObjPasses: case curObjPasses && oldObjPasses:
object, err := c.copier.Copy(event.Object) watchEvent = watch.Event{Type: watch.Modified, Object: event.Object.DeepCopyObject()}
if err != nil {
utilruntime.HandleError(fmt.Errorf("unexpected copy error: %v", err))
return
}
watchEvent = watch.Event{Type: watch.Modified, Object: object}
case !curObjPasses && oldObjPasses: case !curObjPasses && oldObjPasses:
object, err := c.copier.Copy(event.PrevObject) watchEvent = watch.Event{Type: watch.Deleted, Object: event.PrevObject.DeepCopyObject()}
if err != nil {
utilruntime.HandleError(fmt.Errorf("unexpected copy error: %v", err))
return
}
watchEvent = watch.Event{Type: watch.Deleted, Object: object}
} }
// We need to ensure that if we put event X to the c.result, all // We need to ensure that if we put event X to the c.result, all

View File

@ -612,12 +612,7 @@ func (h *etcdHelper) getFromCache(index uint64, filter storage.FilterFunc) (runt
} }
// We should not return the object itself to avoid polluting the cache if someone // We should not return the object itself to avoid polluting the cache if someone
// modifies returned values. // modifies returned values.
objCopy, err := h.copier.Copy(obj.(runtime.Object)) objCopy := obj.(runtime.Object).DeepCopyObject()
if err != nil {
glog.Errorf("Error during DeepCopy of cached object: %q", err)
// We can't return a copy, thus we report the object as not found.
return nil, false
}
metrics.ObserveCacheHit() metrics.ObserveCacheHit()
return objCopy.(runtime.Object), true return objCopy.(runtime.Object), true
} }
@ -630,11 +625,7 @@ func (h *etcdHelper) addToCache(index uint64, obj runtime.Object) {
defer func() { defer func() {
metrics.ObserveAddCache(startTime) metrics.ObserveAddCache(startTime)
}() }()
objCopy, err := h.copier.Copy(obj) objCopy := obj.DeepCopyObject()
if err != nil {
glog.Errorf("Error during DeepCopy of cached object: %q", err)
return
}
isOverwrite := h.cache.Add(index, objCopy) isOverwrite := h.cache.Add(index, objCopy)
if !isOverwrite { if !isOverwrite {
metrics.ObserveNewEntry() metrics.ObserveNewEntry()

View File

@ -373,12 +373,7 @@ func TestWatchEtcdState(t *testing.T) {
// CAS the previous value // CAS the previous value
updateFn := func(input runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { updateFn := func(input runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) {
newObj, err := scheme.DeepCopy(pod) return pod.DeepCopyObject(), nil, nil
if err != nil {
t.Errorf("unexpected error: %v", err)
return nil, nil, err
}
return newObj.(*example.Pod), nil, nil
} }
err = h.GuaranteedUpdate(context.TODO(), key, &example.Pod{}, false, nil, updateFn) err = h.GuaranteedUpdate(context.TODO(), key, &example.Pod{}, false, nil, updateFn)
if err != nil { if err != nil {

View File

@ -123,12 +123,7 @@ func makeTestPod(name string) *example.Pod {
func updatePod(t *testing.T, s storage.Interface, obj, old *example.Pod) *example.Pod { func updatePod(t *testing.T, s storage.Interface, obj, old *example.Pod) *example.Pod {
updateFn := func(input runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { updateFn := func(input runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) {
newObj, err := scheme.DeepCopy(obj) return obj.DeepCopyObject(), nil, nil
if err != nil {
t.Errorf("unexpected error: %v", err)
return nil, nil, err
}
return newObj.(*example.Pod), nil, nil
} }
key := "pods/" + obj.Namespace + "/" + obj.Name key := "pods/" + obj.Namespace + "/" + obj.Name
if err := s.GuaranteedUpdate(context.TODO(), key, &example.Pod{}, old == nil, nil, updateFn); err != nil { if err := s.GuaranteedUpdate(context.TODO(), key, &example.Pod{}, old == nil, nil, updateFn); err != nil {