func TestCheckGeneratedNameError(t *testing.T) { expect := errors.NewNotFound(api.Resource("foos"), "bar") if err := rest.CheckGeneratedNameError(Strategy, expect, &api.Pod{}); err != expect { t.Errorf("NotFoundError should be ignored: %v", err) } expect = errors.NewAlreadyExists(api.Resource("foos"), "bar") if err := rest.CheckGeneratedNameError(Strategy, expect, &api.Pod{}); err != expect { t.Errorf("AlreadyExists should be returned when no GenerateName field: %v", err) } expect = errors.NewAlreadyExists(api.Resource("foos"), "bar") if err := rest.CheckGeneratedNameError(Strategy, expect, &api.Pod{ObjectMeta: metav1.ObjectMeta{GenerateName: "foo"}}); err == nil || !errors.IsServerTimeout(err) { t.Errorf("expected try again later error: %v", err) } }
func (c *mockRecyclerClient) CreatePod(pod *v1.Pod) (*v1.Pod, error) { if c.pod == nil { c.pod = pod return c.pod, nil } // Simulate "already exists" error return nil, errors.NewAlreadyExists(api.Resource("pods"), pod.Name) }
// InterpretCreateError converts a generic error on a create // operation into the appropriate API error. func InterpretCreateError(err error, qualifiedResource schema.GroupResource, name string) error { switch { case storage.IsNodeExist(err): return errors.NewAlreadyExists(qualifiedResource, name) case storage.IsUnreachable(err): return errors.NewServerTimeout(qualifiedResource, "create", 2) // TODO: make configurable or handled at a higher level default: return err } }
func TestAPIStatus(t *testing.T) { cases := map[error]metav1.Status{ errors.NewNotFound(schema.GroupResource{Group: "legacy.kubernetes.io", Resource: "foos"}, "bar"): { Status: metav1.StatusFailure, Code: http.StatusNotFound, Reason: metav1.StatusReasonNotFound, Message: "foos.legacy.kubernetes.io \"bar\" not found", Details: &metav1.StatusDetails{ Group: "legacy.kubernetes.io", Kind: "foos", Name: "bar", }, }, errors.NewAlreadyExists(api.Resource("foos"), "bar"): { Status: metav1.StatusFailure, Code: http.StatusConflict, Reason: "AlreadyExists", Message: "foos \"bar\" already exists", Details: &metav1.StatusDetails{ Group: "", Kind: "foos", Name: "bar", }, }, errors.NewConflict(api.Resource("foos"), "bar", stderrs.New("failure")): { Status: metav1.StatusFailure, Code: http.StatusConflict, Reason: "Conflict", Message: "Operation cannot be fulfilled on foos \"bar\": failure", Details: &metav1.StatusDetails{ Group: "", Kind: "foos", Name: "bar", }, }, } for k, v := range cases { actual := apiStatus(k) if !reflect.DeepEqual(actual, &v) { t.Errorf("%s: Expected %#v, Got %#v", k, v, actual) } } }
// Create adds a new Node to the fake store. func (m *FakeNodeHandler) Create(node *v1.Node) (*v1.Node, error) { m.lock.Lock() defer func() { m.RequestCount++ m.lock.Unlock() }() for _, n := range m.Existing { if n.Name == node.Name { return nil, apierrors.NewAlreadyExists(api.Resource("nodes"), node.Name) } } if m.CreateHook == nil || m.CreateHook(m, node) { nodeCopy := *node m.CreatedNodes = append(m.CreatedNodes, &nodeCopy) return node, nil } else { return nil, errors.New("Create error.") } }
func TestAdmissionWithLatentCache(t *testing.T) { namespace := "test" mockClient := newMockClientForTest([]string{}) mockClient.AddReactor("create", "namespaces", func(action core.Action) (bool, runtime.Object, error) { return true, nil, errors.NewAlreadyExists(api.Resource("namespaces"), namespace) }) handler, informerFactory, err := newHandlerForTest(mockClient) if err != nil { t.Errorf("unexpected error initializing handler: %v", err) } informerFactory.Start(wait.NeverStop) pod := newPod(namespace) err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err != nil { t.Errorf("unexpected error returned from admission handler") } if !hasCreateNamespaceAction(mockClient) { t.Errorf("expected create namespace action") } }
func (t *tracker) add(obj runtime.Object, ns string, replaceExisting bool) error { gvks, _, err := t.scheme.ObjectKinds(obj) if err != nil { return err } if len(gvks) == 0 { return fmt.Errorf("no registered kinds for %v", obj) } t.lock.Lock() defer t.lock.Unlock() for _, gvk := range gvks { gr := schema.GroupResource{Group: gvk.Group, Resource: gvk.Kind} // To avoid the object from being accidentally modified by caller // after it's been added to the tracker, we always store the deep // copy. obj, err = t.scheme.Copy(obj) if err != nil { return err } if status, ok := obj.(*metav1.Status); ok && status.Details != nil { gvk.Kind = status.Details.Kind } newMeta, err := meta.Accessor(obj) if err != nil { return err } // Propagate namespace to the new object if hasn't already been set. if len(newMeta.GetNamespace()) == 0 { newMeta.SetNamespace(ns) } if ns != newMeta.GetNamespace() { msg := fmt.Sprintf("request namespace does not match object namespace, request: %q object: %q", ns, newMeta.GetNamespace()) return errors.NewBadRequest(msg) } if err := checkNamespace(gvk, newMeta.GetNamespace()); err != nil { return err } for i, existingObj := range t.objects[gvk] { oldMeta, err := meta.Accessor(existingObj) if err != nil { return err } if oldMeta.GetNamespace() == newMeta.GetNamespace() && oldMeta.GetName() == newMeta.GetName() { if replaceExisting { t.objects[gvk][i] = obj return nil } return errors.NewAlreadyExists(gr, newMeta.GetName()) } } if replaceExisting { // Tried to update but no matching object was found. return errors.NewNotFound(gr, newMeta.GetName()) } t.objects[gvk] = append(t.objects[gvk], obj) } return nil }