diff --git a/pkg/kubectl/scale_test.go b/pkg/kubectl/scale_test.go index 96250d8fe1..f4e7a3b275 100644 --- a/pkg/kubectl/scale_test.go +++ b/pkg/kubectl/scale_test.go @@ -1049,3 +1049,264 @@ func TestValidateStatefulSet(t *testing.T) { } } } + +type ErrorReplicaSets struct { + extensionsclient.ReplicaSetInterface + conflict bool + invalid bool +} + +func (c *ErrorReplicaSets) Update(replicaSets *extensions.ReplicaSet) (*extensions.ReplicaSet, error) { + switch { + case c.invalid: + return nil, kerrors.NewInvalid(api.Kind(replicaSets.Kind), replicaSets.Name, nil) + case c.conflict: + return nil, kerrors.NewConflict(api.Resource(replicaSets.Kind), replicaSets.Name, nil) + } + return nil, errors.New("replicaSets update failure") +} + +func (c *ErrorReplicaSets) Get(name string, options metav1.GetOptions) (*extensions.ReplicaSet, error) { + return &extensions.ReplicaSet{ + Spec: extensions.ReplicaSetSpec{ + Replicas: 0, + }, + }, nil +} + +type ErrorReplicaSetClient struct { + extensionsclient.ReplicaSetsGetter + conflict bool + invalid bool +} + +func (c *ErrorReplicaSetClient) ReplicaSets(namespace string) extensionsclient.ReplicaSetInterface { + return &ErrorReplicaSets{ + ReplicaSetInterface: c.ReplicaSetsGetter.ReplicaSets(namespace), + invalid: c.invalid, + conflict: c.conflict, + } +} + +func replicaSet() *extensions.ReplicaSet { + return &extensions.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: metav1.NamespaceDefault, + Name: "foo", + }, + } +} + +func TestReplicaSetScale(t *testing.T) { + fake := fake.NewSimpleClientset(replicaSet()) + scaler := ReplicaSetScaler{fake.Extensions()} + preconditions := ScalePrecondition{-1, ""} + count := uint(3) + name := "foo" + scaler.Scale("default", name, count, &preconditions, nil, nil) + + actions := fake.Actions() + if len(actions) != 2 { + t.Errorf("unexpected actions: %v, expected 2 actions (get, update)", actions) + } + if action, ok := actions[0].(testcore.GetAction); !ok || action.GetResource().GroupResource() != extensions.Resource("replicasets") || action.GetName() != name { + t.Errorf("unexpected action: %v, expected get-replicationSet %s", actions[0], name) + } + if action, ok := actions[1].(testcore.UpdateAction); !ok || action.GetResource().GroupResource() != extensions.Resource("replicasets") || action.GetObject().(*extensions.ReplicaSet).Spec.Replicas != int32(count) { + t.Errorf("unexpected action %v, expected update-replicaSet with replicas = %d", actions[1], count) + } +} + +func TestReplicaSetScaleRetry(t *testing.T) { + fake := &ErrorReplicaSetClient{ReplicaSetsGetter: fake.NewSimpleClientset().Extensions(), conflict: true} + scaler := &ReplicaSetScaler{fake} + preconditions := &ScalePrecondition{-1, ""} + count := uint(3) + name := "foo" + namespace := "default" + + scaleFunc := ScaleCondition(scaler, preconditions, namespace, name, count, nil) + pass, err := scaleFunc() + if pass != false { + t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass) + } + if err != nil { + t.Errorf("Did not expect an error on update failure, got %v", err) + } + preconditions = &ScalePrecondition{3, ""} + scaleFunc = ScaleCondition(scaler, preconditions, namespace, name, count, nil) + pass, err = scaleFunc() + if err == nil { + t.Error("Expected error on precondition failure") + } +} + +func TestReplicaSetScaleInvalid(t *testing.T) { + fake := &ErrorReplicaSetClient{ReplicaSetsGetter: fake.NewSimpleClientset().Extensions(), invalid: true} + scaler := ReplicaSetScaler{fake} + preconditions := ScalePrecondition{-1, ""} + count := uint(3) + name := "foo" + namespace := "default" + + scaleFunc := ScaleCondition(&scaler, &preconditions, namespace, name, count, nil) + pass, err := scaleFunc() + if pass { + t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass) + } + e, ok := err.(ScaleError) + if err == nil || !ok || e.FailureType != ScaleUpdateFailure { + t.Errorf("Expected error on invalid update failure, got %v", err) + } +} + +func TestReplicaSetsGetterFailsPreconditions(t *testing.T) { + fake := fake.NewSimpleClientset(&extensions.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: metav1.NamespaceDefault, + Name: "foo", + }, + Spec: extensions.ReplicaSetSpec{ + Replicas: 10, + }, + }) + scaler := ReplicaSetScaler{fake.Extensions()} + preconditions := ScalePrecondition{2, ""} + count := uint(3) + name := "foo" + scaler.Scale("default", name, count, &preconditions, nil, nil) + + actions := fake.Actions() + if len(actions) != 1 { + t.Errorf("unexpected actions: %v, expected 1 actions (get)", actions) + } + if action, ok := actions[0].(testcore.GetAction); !ok || action.GetResource().GroupResource() != extensions.Resource("replicasets") || action.GetName() != name { + t.Errorf("unexpected action: %v, expected get-replicaSets %s", actions[0], name) + } +} + +func TestValidateReplicaSets(t *testing.T) { + zero, ten, twenty := int32(0), int32(10), int32(20) + tests := []struct { + preconditions ScalePrecondition + replicaSets extensions.ReplicaSet + expectError bool + test string + }{ + { + preconditions: ScalePrecondition{-1, ""}, + expectError: false, + test: "defaults", + }, + { + preconditions: ScalePrecondition{-1, ""}, + replicaSets: extensions.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: "foo", + }, + Spec: extensions.ReplicaSetSpec{ + Replicas: ten, + }, + }, + expectError: false, + test: "defaults 2", + }, + { + preconditions: ScalePrecondition{0, ""}, + replicaSets: extensions.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: "foo", + }, + Spec: extensions.ReplicaSetSpec{ + Replicas: zero, + }, + }, + expectError: false, + test: "size matches", + }, + { + preconditions: ScalePrecondition{-1, "foo"}, + replicaSets: extensions.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: "foo", + }, + Spec: extensions.ReplicaSetSpec{ + Replicas: ten, + }, + }, + expectError: false, + test: "resource version matches", + }, + { + preconditions: ScalePrecondition{10, "foo"}, + replicaSets: extensions.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: "foo", + }, + Spec: extensions.ReplicaSetSpec{ + Replicas: ten, + }, + }, + expectError: false, + test: "both match", + }, + { + preconditions: ScalePrecondition{10, "foo"}, + replicaSets: extensions.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: "foo", + }, + Spec: extensions.ReplicaSetSpec{ + Replicas: twenty, + }, + }, + expectError: true, + test: "size different", + }, + { + preconditions: ScalePrecondition{10, "foo"}, + replicaSets: extensions.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: "foo", + }, + }, + expectError: true, + test: "no replicas", + }, + { + preconditions: ScalePrecondition{10, "foo"}, + replicaSets: extensions.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: "bar", + }, + Spec: extensions.ReplicaSetSpec{ + Replicas: ten, + }, + }, + expectError: true, + test: "version different", + }, + { + preconditions: ScalePrecondition{10, "foo"}, + replicaSets: extensions.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: "bar", + }, + Spec: extensions.ReplicaSetSpec{ + Replicas: twenty, + }, + }, + expectError: true, + test: "both different", + }, + } + for _, test := range tests { + err := test.preconditions.ValidateReplicaSet(&test.replicaSets) + if err != nil && !test.expectError { + t.Errorf("unexpected error: %v (%s)", err, test.test) + } + if err == nil && test.expectError { + t.Errorf("expected an error: %v (%s)", err, test.test) + } + } +}