func TestGracefulStoreHandleFinalizers(t *testing.T) { EnableGarbageCollector = true initialGeneration := int64(1) defer func() { EnableGarbageCollector = false }() podWithFinalizer := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo", Finalizers: []string{"foo.com/x"}, Generation: initialGeneration}, Spec: api.PodSpec{NodeName: "machine"}, } testContext := api.WithNamespace(api.NewContext(), "test") destroyFunc, registry := NewTestGenericStoreRegistry(t) defaultDeleteStrategy := testRESTStrategy{api.Scheme, api.SimpleNameGenerator, true, false, true} registry.DeleteStrategy = testGracefulStrategy{defaultDeleteStrategy} defer destroyFunc() // create pod _, err := registry.Create(testContext, podWithFinalizer) if err != nil { t.Errorf("Unexpected error: %v", err) } // delete the pod with grace period=0, the pod should still exist because it has a finalizer _, err = registry.Delete(testContext, podWithFinalizer.Name, api.NewDeleteOptions(0)) if err != nil { t.Fatalf("Unexpected error: %v", err) } _, err = registry.Get(testContext, podWithFinalizer.Name) if err != nil { t.Fatalf("Unexpected error: %v", err) } updatedPodWithFinalizer := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo", Finalizers: []string{"foo.com/x"}, ResourceVersion: podWithFinalizer.ObjectMeta.ResourceVersion}, Spec: api.PodSpec{NodeName: "machine"}, } _, _, err = registry.Update(testContext, updatedPodWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(updatedPodWithFinalizer, api.Scheme)) if err != nil { t.Fatalf("Unexpected error: %v", err) } // the object should still exist, because it still has a finalizer _, err = registry.Get(testContext, podWithFinalizer.Name) if err != nil { t.Fatalf("Unexpected error: %v", err) } podWithNoFinalizer := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: podWithFinalizer.ObjectMeta.ResourceVersion}, Spec: api.PodSpec{NodeName: "anothermachine"}, } _, _, err = registry.Update(testContext, podWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(podWithNoFinalizer, api.Scheme)) if err != nil { t.Fatalf("Unexpected error: %v", err) } // the pod should be removed, because its finalizer is removed _, err = registry.Get(testContext, podWithFinalizer.Name) if !errors.IsNotFound(err) { t.Fatalf("Unexpected error: %v", err) } }
func TestServiceRegistryIPUpdate(t *testing.T) { storage, _ := NewTestREST(t, nil) svc := &api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, SessionAffinity: api.ServiceAffinityNone, Type: api.ServiceTypeClusterIP, Ports: []api.ServicePort{{ Port: 6502, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(6502), }}, }, } ctx := api.NewDefaultContext() created_svc, _ := storage.Create(ctx, svc) created_service := created_svc.(*api.Service) if created_service.Spec.Ports[0].Port != 6502 { t.Errorf("Expected port 6502, but got %v", created_service.Spec.Ports[0].Port) } if !makeIPNet(t).Contains(net.ParseIP(created_service.Spec.ClusterIP)) { t.Errorf("Unexpected ClusterIP: %s", created_service.Spec.ClusterIP) } update := deepCloneService(created_service) update.Spec.Ports[0].Port = 6503 updated_svc, _, _ := storage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(update, api.Scheme)) updated_service := updated_svc.(*api.Service) if updated_service.Spec.Ports[0].Port != 6503 { t.Errorf("Expected port 6503, but got %v", updated_service.Spec.Ports[0].Port) } testIPs := []string{"1.2.3.93", "1.2.3.94", "1.2.3.95", "1.2.3.96"} testIP := "" for _, ip := range testIPs { if !storage.serviceIPs.(*ipallocator.Range).Has(net.ParseIP(ip)) { testIP = ip break } } update = deepCloneService(created_service) update.Spec.Ports[0].Port = 6503 update.Spec.ClusterIP = testIP // Error: Cluster IP is immutable _, _, err := storage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(update, api.Scheme)) if err == nil || !errors.IsInvalid(err) { t.Errorf("Unexpected error type: %v", err) } }
func TestStoreUpdate(t *testing.T) { podA := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test"}, Spec: api.PodSpec{NodeName: "machine"}, } podB := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test"}, Spec: api.PodSpec{NodeName: "machine2"}, } podAWithResourceVersion := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "7"}, Spec: api.PodSpec{NodeName: "machine"}, } testContext := api.WithNamespace(api.NewContext(), "test") server, registry := NewTestGenericStoreRegistry(t) defer server.Terminate(t) // Test1 try to update a non-existing node _, _, err := registry.Update(testContext, podA.Name, rest.DefaultUpdatedObjectInfo(podA, api.Scheme)) if !errors.IsNotFound(err) { t.Errorf("Unexpected error: %v", err) } // Test2 createIfNotFound and verify registry.UpdateStrategy.(*testRESTStrategy).allowCreateOnUpdate = true if !updateAndVerify(t, testContext, registry, podA) { t.Errorf("Unexpected error updating podA") } registry.UpdateStrategy.(*testRESTStrategy).allowCreateOnUpdate = false // Test3 outofDate _, _, err = registry.Update(testContext, podAWithResourceVersion.Name, rest.DefaultUpdatedObjectInfo(podAWithResourceVersion, api.Scheme)) if !errors.IsConflict(err) { t.Errorf("Unexpected error updating podAWithResourceVersion: %v", err) } // Test4 normal update and verify if !updateAndVerify(t, testContext, registry, podB) { t.Errorf("Unexpected error updating podB") } // Test5 unconditional update // NOTE: The logic for unconditional updates doesn't make sense to me, and imho should be removed. // doUnconditionalUpdate := resourceVersion == 0 && e.UpdateStrategy.AllowUnconditionalUpdate() // ^^ That condition can *never be true due to the creation of root objects. // // registry.UpdateStrategy.(*testRESTStrategy).allowUnconditionalUpdate = true // updateAndVerify(t, testContext, registry, podAWithResourceVersion) }
func TestGenerationNumber(t *testing.T) { storage, server := newStorage(t) defer server.Terminate(t) defer storage.ReplicaSet.Store.DestroyFunc() modifiedSno := *validNewReplicaSet() modifiedSno.Generation = 100 modifiedSno.Status.ObservedGeneration = 10 ctx := api.NewDefaultContext() rs, err := createReplicaSet(storage.ReplicaSet, modifiedSno, t) etcdRS, err := storage.ReplicaSet.Get(ctx, rs.Name) if err != nil { t.Errorf("unexpected error: %v", err) } storedRS, _ := etcdRS.(*extensions.ReplicaSet) // Generation initialization if storedRS.Generation != 1 && storedRS.Status.ObservedGeneration != 0 { t.Fatalf("Unexpected generation number %v, status generation %v", storedRS.Generation, storedRS.Status.ObservedGeneration) } // Updates to spec should increment the generation number storedRS.Spec.Replicas += 1 storage.ReplicaSet.Update(ctx, storedRS.Name, rest.DefaultUpdatedObjectInfo(storedRS, api.Scheme)) if err != nil { t.Errorf("unexpected error: %v", err) } etcdRS, err = storage.ReplicaSet.Get(ctx, rs.Name) if err != nil { t.Errorf("unexpected error: %v", err) } storedRS, _ = etcdRS.(*extensions.ReplicaSet) if storedRS.Generation != 2 || storedRS.Status.ObservedGeneration != 0 { t.Fatalf("Unexpected generation, spec: %v, status: %v", storedRS.Generation, storedRS.Status.ObservedGeneration) } // Updates to status should not increment either spec or status generation numbers storedRS.Status.Replicas += 1 storage.ReplicaSet.Update(ctx, storedRS.Name, rest.DefaultUpdatedObjectInfo(storedRS, api.Scheme)) if err != nil { t.Errorf("unexpected error: %v", err) } etcdRS, err = storage.ReplicaSet.Get(ctx, rs.Name) if err != nil { t.Errorf("unexpected error: %v", err) } storedRS, _ = etcdRS.(*extensions.ReplicaSet) if storedRS.Generation != 2 || storedRS.Status.ObservedGeneration != 0 { t.Fatalf("Unexpected generation number, spec: %v, status: %v", storedRS.Generation, storedRS.Status.ObservedGeneration) } }
func TestGenerationNumber(t *testing.T) { storage, server := newStorage(t) defer server.Terminate(t) defer storage.Controller.Store.DestroyFunc() modifiedSno := *validNewController() modifiedSno.Generation = 100 modifiedSno.Status.ObservedGeneration = 10 ctx := api.NewDefaultContext() rc, err := createController(storage.Controller, modifiedSno, t) ctrl, err := storage.Controller.Get(ctx, rc.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } controller, _ := ctrl.(*api.ReplicationController) // Generation initialization if controller.Generation != 1 && controller.Status.ObservedGeneration != 0 { t.Fatalf("Unexpected generation number %v, status generation %v", controller.Generation, controller.Status.ObservedGeneration) } // Updates to spec should increment the generation number controller.Spec.Replicas += 1 storage.Controller.Update(ctx, controller.Name, rest.DefaultUpdatedObjectInfo(controller, api.Scheme)) if err != nil { t.Errorf("unexpected error: %v", err) } ctrl, err = storage.Controller.Get(ctx, rc.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } controller, _ = ctrl.(*api.ReplicationController) if controller.Generation != 2 || controller.Status.ObservedGeneration != 0 { t.Fatalf("Unexpected generation, spec: %v, status: %v", controller.Generation, controller.Status.ObservedGeneration) } // Updates to status should not increment either spec or status generation numbers controller.Status.Replicas += 1 storage.Controller.Update(ctx, controller.Name, rest.DefaultUpdatedObjectInfo(controller, api.Scheme)) if err != nil { t.Errorf("unexpected error: %v", err) } ctrl, err = storage.Controller.Get(ctx, rc.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } controller, _ = ctrl.(*api.ReplicationController) if controller.Generation != 2 || controller.Status.ObservedGeneration != 0 { t.Fatalf("Unexpected generation number, spec: %v, status: %v", controller.Generation, controller.Status.ObservedGeneration) } }
func TestUpdateError(t *testing.T) { ctx := kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "unittest"), &user.DefaultInfo{Name: "system:admin"}) storage := makeTestStorage() obj, err := storage.Create(ctx, &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "my-different"}, RoleRef: kapi.ObjectReference{Name: "admin"}, }) if err != nil { t.Errorf("unexpected error: %v", err) return } original := obj.(*authorizationapi.RoleBinding) roleBinding := &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "my-roleBinding", ResourceVersion: original.ResourceVersion}, RoleRef: kapi.ObjectReference{Name: "admin"}, } _, _, err = storage.Update(ctx, roleBinding.Name, rest.DefaultUpdatedObjectInfo(roleBinding, kapi.Scheme)) if err == nil { t.Errorf("Missing expected error") return } if !kapierrors.IsNotFound(err) { t.Errorf("Unexpected error %v", err) } }
func TestUpdateCannotChangeRoleRefError(t *testing.T) { ctx := kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "unittest"), &user.DefaultInfo{Name: "system:admin"}) storage := makeTestStorage() obj, err := storage.Create(ctx, &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "my-different"}, RoleRef: kapi.ObjectReference{Name: "admin"}, }) if err != nil { t.Errorf("unexpected error: %v", err) return } original := obj.(*authorizationapi.RoleBinding) roleBinding := &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "my-different", ResourceVersion: original.ResourceVersion}, RoleRef: kapi.ObjectReference{Name: "cluster-admin"}, } _, _, err = storage.Update(ctx, roleBinding.Name, rest.DefaultUpdatedObjectInfo(roleBinding, kapi.Scheme)) if err == nil { t.Errorf("Missing expected error") return } expectedErr := "cannot change roleRef" if !strings.Contains(err.Error(), expectedErr) { t.Errorf("Expected %v, got %v", expectedErr, err.Error()) } }
func TestConflictingUpdate(t *testing.T) { storage := makeLocalTestStorage() ctx := kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "unittest"), &user.DefaultInfo{Name: "system:admin"}) realizedRoleObj, err := storage.Create(ctx, &authorizationapi.Role{ ObjectMeta: kapi.ObjectMeta{Name: "my-role"}, Rules: []authorizationapi.PolicyRule{ {Verbs: sets.NewString(authorizationapi.VerbAll)}, }, }) if err != nil { t.Fatalf("unexpected error: %v", err) } realizedRole := realizedRoleObj.(*authorizationapi.Role) role := &authorizationapi.Role{ ObjectMeta: realizedRole.ObjectMeta, Rules: []authorizationapi.PolicyRule{ {Verbs: sets.NewString("list", "update")}, }, } role.ResourceVersion += "1" _, _, err = storage.Update(ctx, role.Name, rest.DefaultUpdatedObjectInfo(role, kapi.Scheme)) if err == nil || !kapierrors.IsConflict(err) { t.Errorf("Expected conflict error, got: %#v", err) } }
func (s *storage) UpdateUser(ctx kapi.Context, user *api.User) (*api.User, error) { obj, _, err := s.Update(ctx, user.Name, rest.DefaultUpdatedObjectInfo(user, kapi.Scheme)) if err != nil { return nil, err } return obj.(*api.User), nil }
func TestStatusUpdate(t *testing.T) { storage, server := newStorage(t) defer server.Terminate(t) ctx := api.WithNamespace(api.NewContext(), namespace) key := etcdtest.AddPrefix("/deployments/" + namespace + "/" + name) if err := storage.Deployment.Storage.Create(ctx, key, &validDeployment, nil, 0); err != nil { t.Fatalf("unexpected error: %v", err) } update := extensions.Deployment{ ObjectMeta: validDeployment.ObjectMeta, Spec: extensions.DeploymentSpec{ Replicas: defaultReplicas, }, Status: extensions.DeploymentStatus{ Replicas: defaultReplicas, }, } if _, _, err := storage.Status.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update, api.Scheme)); err != nil { t.Fatalf("unexpected error: %v", err) } obj, err := storage.Deployment.Get(ctx, name) if err != nil { t.Fatalf("unexpected error: %v", err) } deployment := obj.(*extensions.Deployment) if deployment.Spec.Replicas != 7 { t.Errorf("we expected .spec.replicas to not be updated but it was updated to %v", deployment.Spec.Replicas) } if deployment.Status.Replicas != defaultReplicas { t.Errorf("we expected .status.replicas to be updated to %d but it was %v", defaultReplicas, deployment.Status.Replicas) } }
func (s *storage) UpdateImageStreamStatus(ctx kapi.Context, imageStream *api.ImageStream) (*api.ImageStream, error) { obj, _, err := s.status.Update(ctx, imageStream.Name, rest.DefaultUpdatedObjectInfo(imageStream, kapi.Scheme)) if err != nil { return nil, err } return obj.(*api.ImageStream), nil }
func (s *storage) UpdateDeployment(ctx api.Context, deployment *extensions.Deployment) (*extensions.Deployment, error) { obj, _, err := s.Update(ctx, deployment.Name, rest.DefaultUpdatedObjectInfo(deployment, api.Scheme)) if err != nil { return nil, err } return obj.(*extensions.Deployment), nil }
func TestServiceRegistryIPLoadBalancer(t *testing.T) { storage, _ := NewTestREST(t, nil) svc := &api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, SessionAffinity: api.ServiceAffinityNone, Type: api.ServiceTypeLoadBalancer, Ports: []api.ServicePort{{ Port: 6502, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(6502), }}, }, } ctx := api.NewDefaultContext() created_svc, _ := storage.Create(ctx, svc) created_service := created_svc.(*api.Service) if created_service.Spec.Ports[0].Port != 6502 { t.Errorf("Expected port 6502, but got %v", created_service.Spec.Ports[0].Port) } if !makeIPNet(t).Contains(net.ParseIP(created_service.Spec.ClusterIP)) { t.Errorf("Unexpected ClusterIP: %s", created_service.Spec.ClusterIP) } update := deepCloneService(created_service) _, _, err := storage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(update, api.Scheme)) if err != nil { t.Errorf("Unexpected error %v", err) } }
func (t *Tester) testUpdateFailsOnVersionTooOld(obj runtime.Object, createFn CreateFunc, getFn GetFunc) { ctx := t.TestContext() foo := copyOrDie(obj) t.setObjectMeta(foo, t.namer(3)) if err := createFn(ctx, foo); err != nil { t.Errorf("unexpected error: %v", err) } storedFoo, err := getFn(ctx, foo) if err != nil { t.Errorf("unexpected error: %v", err) } older := copyOrDie(storedFoo) olderMeta := t.getObjectMetaOrFail(older) olderMeta.ResourceVersion = "1" _, _, err = t.storage.(rest.Updater).Update(t.TestContext(), olderMeta.Name, rest.DefaultUpdatedObjectInfo(older, api.Scheme)) if err == nil { t.Errorf("Expected an error, but we didn't get one") } else if !errors.IsConflict(err) { t.Errorf("Expected Conflict error, got '%v'", err) } }
func (t *Tester) testUpdateIgnoreGenerationUpdates(obj runtime.Object, createFn CreateFunc, getFn GetFunc) { ctx := t.TestContext() foo := copyOrDie(obj) name := t.namer(8) t.setObjectMeta(foo, name) if err := createFn(ctx, foo); err != nil { t.Errorf("unexpected error: %v", err) } storedFoo, err := getFn(ctx, foo) if err != nil { t.Errorf("unexpected error: %v", err) } older := copyOrDie(storedFoo) olderMeta := t.getObjectMetaOrFail(older) olderMeta.Generation = 2 _, _, err = t.storage.(rest.Updater).Update(t.TestContext(), olderMeta.Name, rest.DefaultUpdatedObjectInfo(older, api.Scheme)) if err != nil { t.Errorf("Unexpected error: %v", err) } updatedFoo, err := getFn(ctx, older) if err != nil { t.Errorf("unexpected error: %v", err) } if exp, got := int64(1), t.getObjectMetaOrFail(updatedFoo).Generation; exp != got { t.Errorf("Unexpected generation update: expected %d, got %d", exp, got) } }
func (t *Tester) testUpdateEquals(obj runtime.Object, createFn CreateFunc, getFn GetFunc, updateFn UpdateFunc) { ctx := t.TestContext() foo := copyOrDie(obj) t.setObjectMeta(foo, t.namer(2)) if err := createFn(ctx, foo); err != nil { t.Errorf("unexpected error: %v", err) } toUpdate, err := getFn(ctx, foo) if err != nil { t.Errorf("unexpected error: %v", err) } toUpdate = updateFn(toUpdate) toUpdateMeta := t.getObjectMetaOrFail(toUpdate) updated, created, err := t.storage.(rest.Updater).Update(ctx, toUpdateMeta.Name, rest.DefaultUpdatedObjectInfo(toUpdate, api.Scheme)) if err != nil { t.Errorf("unexpected error: %v", err) } if created { t.Errorf("unexpected creation") } got, err := getFn(ctx, foo) if err != nil { t.Errorf("unexpected error: %v", err) } // Set resource version which might be unset in created object. updatedMeta := t.getObjectMetaOrFail(updated) gotMeta := t.getObjectMetaOrFail(got) updatedMeta.ResourceVersion = gotMeta.ResourceVersion if e, a := updated, got; !api.Semantic.DeepEqual(e, a) { t.Errorf("unexpected obj: %#v, expected %#v", e, a) } }
func TestUpdate(t *testing.T) { storage, server, si := newStorage(t) defer server.Terminate(t) ctx := api.WithNamespace(api.NewContext(), "test") key := etcdtest.AddPrefix("/controllers/test/foo") if err := si.Create(ctx, key, &validController, nil, 0); err != nil { t.Fatalf("unexpected error: %v", err) } replicas := int32(12) update := extensions.Scale{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test"}, Spec: extensions.ScaleSpec{ Replicas: replicas, }, } if _, _, err := storage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update, api.Scheme)); err != nil { t.Fatalf("unexpected error: %v", err) } obj, err := storage.Get(ctx, "foo") if err != nil { t.Fatalf("unexpected error: %v", err) } updated := obj.(*extensions.Scale) if updated.Spec.Replicas != replicas { t.Errorf("wrong replicas count expected: %d got: %d", replicas, updated.Spec.Replicas) } }
func (t *Tester) testUpdateIgnoreClusterName(obj runtime.Object, createFn CreateFunc, getFn GetFunc) { ctx := t.TestContext() foo := copyOrDie(obj) name := t.namer(9) t.setObjectMeta(foo, name) if err := createFn(ctx, foo); err != nil { t.Errorf("unexpected error: %v", err) } storedFoo, err := getFn(ctx, foo) if err != nil { t.Errorf("unexpected error: %v", err) } older := copyOrDie(storedFoo) olderMeta := t.getObjectMetaOrFail(older) olderMeta.ClusterName = "clustername-to-ignore" _, _, err = t.storage.(rest.Updater).Update(t.TestContext(), olderMeta.Name, rest.DefaultUpdatedObjectInfo(older, api.Scheme)) if err != nil { t.Errorf("Unexpected error: %v", err) } updatedFoo, err := getFn(ctx, older) if err != nil { t.Errorf("unexpected error: %v", err) } if clusterName := t.getObjectMetaOrFail(updatedFoo).ClusterName; len(clusterName) != 0 { t.Errorf("Unexpected clusterName update: expected empty, got %v", clusterName) } }
func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { ctx := api.NewDefaultContext() storage, _ := NewTestREST(t, nil) // Create external load balancer. svc1 := &api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, SessionAffinity: api.ServiceAffinityNone, Type: api.ServiceTypeLoadBalancer, Ports: []api.ServicePort{{ Name: "p", Port: 6502, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(6502), }, { Name: "q", Port: 8086, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(8086), }}, }, } if _, err := storage.Create(ctx, svc1); err != nil { t.Fatalf("Unexpected error: %v", err) } // Modify ports svc2 := deepCloneService(svc1) svc2.Spec.Ports[1].Port = 8088 if _, _, err := storage.Update(ctx, svc2.Name, rest.DefaultUpdatedObjectInfo(svc2, api.Scheme)); err != nil { t.Fatalf("Unexpected error: %v", err) } }
func TestUpdateStatus(t *testing.T) { storage, statusStorage, server := newStorage(t) defer server.Terminate(t) ctx := api.NewContext() key, _ := storage.KeyFunc(ctx, "foo") key = etcdtest.AddPrefix(key) pvStart := validNewPersistentVolume("foo") err := storage.Storage.Create(ctx, key, pvStart, nil, 0) if err != nil { t.Errorf("unexpected error: %v", err) } pvIn := &api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ Name: "foo", }, Status: api.PersistentVolumeStatus{ Phase: api.VolumeBound, }, } _, _, err = statusStorage.Update(ctx, pvIn.Name, rest.DefaultUpdatedObjectInfo(pvIn, api.Scheme)) if err != nil { t.Fatalf("Unexpected error: %v", err) } obj, err := storage.Get(ctx, "foo") if err != nil { t.Errorf("unexpected error: %v", err) } pvOut := obj.(*api.PersistentVolume) // only compare the relevant change b/c metadata will differ if !api.Semantic.DeepEqual(pvIn.Status, pvOut.Status) { t.Errorf("unexpected object: %s", diff.ObjectDiff(pvIn.Status, pvOut.Status)) } }
func (s *storage) UpdateClientAuthorization(ctx kapi.Context, client *api.OAuthClientAuthorization) (*api.OAuthClientAuthorization, error) { obj, _, err := s.Update(ctx, client.Name, rest.DefaultUpdatedObjectInfo(client, kapi.Scheme)) if err != nil { return nil, err } return obj.(*api.OAuthClientAuthorization), nil }
func TestUpdateOldUserMatches(t *testing.T) { user, identity := makeAssociated() expectedActions := []test.Action{ // Existing mapping lookup {"GetIdentity", identity.Name}, {"GetUser", user.Name}, } mapping := &api.UserIdentityMapping{ ObjectMeta: kapi.ObjectMeta{ResourceVersion: identity.ResourceVersion}, Identity: kapi.ObjectReference{Name: identity.Name}, User: kapi.ObjectReference{Name: user.Name}, } actions, _, _, rest := setupRegistries(identity, user) createdMapping, created, err := rest.Update(kapi.NewContext(), mapping.Name, kapirest.DefaultUpdatedObjectInfo(mapping, kapi.Scheme)) if err != nil { t.Errorf("Unexpected error: %v", err) } if created { t.Errorf("Unexpected created") } verifyActions(expectedActions, *actions, t) verifyMapping(createdMapping, user, identity, t) }
func TestEtcdUpdateNotScheduled(t *testing.T) { storage, _, _, server := newStorage(t) defer server.Terminate(t) defer storage.Store.DestroyFunc() ctx := api.NewDefaultContext() key, _ := storage.KeyFunc(ctx, "foo") key = etcdtest.AddPrefix(key) if _, err := storage.Create(ctx, validNewPod()); err != nil { t.Fatalf("unexpected error: %v", err) } podIn := validChangedPod() _, _, err := storage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(podIn, api.Scheme)) if err != nil { t.Errorf("Unexpected error: %v", err) } obj, err := storage.Get(ctx, validNewPod().ObjectMeta.Name) if err != nil { t.Errorf("unexpected error: %v", err) } podOut := obj.(*api.Pod) // validChangedPod only changes the Labels, so were checking the update was valid if !api.Semantic.DeepEqual(podIn.Labels, podOut.Labels) { t.Errorf("objects differ: %v", diff.ObjectDiff(podOut, podIn)) } }
func (s *storage) UpdateIdentity(ctx kapi.Context, identity *api.Identity) (*api.Identity, error) { obj, _, err := s.Update(ctx, identity.Name, rest.DefaultUpdatedObjectInfo(identity, kapi.Scheme)) if err != nil { return nil, err } return obj.(*api.Identity), nil }
func (s *storage) UpdateController(ctx api.Context, controller *api.ReplicationController) (*api.ReplicationController, error) { obj, _, err := s.Update(ctx, controller.Name, rest.DefaultUpdatedObjectInfo(controller, api.Scheme)) if err != nil { return nil, err } return obj.(*api.ReplicationController), nil }
func (s *storage) UpdateImage(ctx kapi.Context, image *api.Image) (*api.Image, error) { obj, _, err := s.Update(ctx, image.Name, rest.DefaultUpdatedObjectInfo(image, kapi.Scheme)) if err != nil { return nil, err } return obj.(*api.Image), nil }
func (s *storage) UpdateReplicaSet(ctx api.Context, replicaSet *extensions.ReplicaSet) (*extensions.ReplicaSet, error) { obj, _, err := s.Update(ctx, replicaSet.Name, rest.DefaultUpdatedObjectInfo(replicaSet, api.Scheme)) if err != nil { return nil, err } return obj.(*extensions.ReplicaSet), nil }
func TestConflictingUpdate(t *testing.T) { ctx := kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "unittest"), &user.DefaultInfo{Name: "system:admin"}) storage := makeTestStorage() obj, err := storage.Create(ctx, &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "my-roleBinding"}, RoleRef: kapi.ObjectReference{Name: "admin"}, }) if err != nil { t.Errorf("unexpected error: %v", err) return } original := obj.(*authorizationapi.RoleBinding) roleBinding := &authorizationapi.RoleBinding{ ObjectMeta: original.ObjectMeta, RoleRef: kapi.ObjectReference{Name: "admin"}, Subjects: []kapi.ObjectReference{{Name: "bob", Kind: "User"}}, } roleBinding.ResourceVersion = roleBinding.ResourceVersion + "1" _, _, err = storage.Update(ctx, roleBinding.Name, rest.DefaultUpdatedObjectInfo(roleBinding, kapi.Scheme)) if err == nil || !kapierrors.IsConflict(err) { t.Errorf("Expected conflict error, got: %#v", err) } }
func (s *storage) UpdateUserIdentityMapping(ctx kapi.Context, mapping *api.UserIdentityMapping) (*api.UserIdentityMapping, error) { obj, _, err := s.Update(ctx, mapping.Name, rest.DefaultUpdatedObjectInfo(mapping, kapi.Scheme)) if err != nil { return nil, err } return obj.(*api.UserIdentityMapping), nil }
func TestUpdateWithMismatchedResourceVersion(t *testing.T) { // Starting conditions associatedUser1, associatedIdentity1User1 := makeAssociated() unassociatedUser2 := makeUser() // Finishing conditions _, unassociatedIdentity1 := disassociate(associatedUser1, associatedIdentity1User1) expectedActions := []test.Action{ // Existing mapping lookup {"GetIdentity", associatedIdentity1User1.Name}, {"GetUser", associatedUser1.Name}, } mapping := &api.UserIdentityMapping{ ObjectMeta: kapi.ObjectMeta{ResourceVersion: "123"}, Identity: kapi.ObjectReference{Name: unassociatedIdentity1.Name}, User: kapi.ObjectReference{Name: unassociatedUser2.Name}, } actions, _, _, rest := setupRegistries(associatedIdentity1User1, associatedUser1, unassociatedUser2) _, _, err := rest.Update(kapi.NewContext(), mapping.Name, kapirest.DefaultUpdatedObjectInfo(mapping, kapi.Scheme)) if err == nil { t.Errorf("Expected error") } if !kerrs.IsConflict(err) { t.Errorf("Unexpected error: %v", err) } verifyActions(expectedActions, *actions, t) }