func TestValidateDeploymentConfigUpdate(t *testing.T) { oldConfig := &api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar", ResourceVersion: "1"}, Triggers: manualTrigger(), Template: test.OkDeploymentTemplate(), LatestVersion: 5, } newConfig := &api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar", ResourceVersion: "1"}, Triggers: manualTrigger(), Template: test.OkDeploymentTemplate(), LatestVersion: 3, } scenarios := []struct { oldLatestVersion int newLatestVersion int }{ {5, 3}, {5, 7}, {0, -1}, } for _, values := range scenarios { oldConfig.LatestVersion = values.oldLatestVersion newConfig.LatestVersion = values.newLatestVersion errs := ValidateDeploymentConfigUpdate(newConfig, oldConfig) if len(errs) == 0 { t.Errorf("Expected update failure") } for i := range errs { if errs[i].(*fielderrors.ValidationError).Type != fielderrors.ValidationErrorTypeInvalid { t.Errorf("expected update error to have type %s: %v", fielderrors.ValidationErrorTypeInvalid, errs[i]) } if errs[i].(*fielderrors.ValidationError).Field != "latestVersion" { t.Errorf("expected update error to have field %s: %v", "latestVersion", errs[i]) } } } // testing for a successful update oldConfig.LatestVersion = 5 newConfig.LatestVersion = 6 errs := ValidateDeploymentConfigUpdate(newConfig, oldConfig) if len(errs) > 0 { t.Errorf("Unexpected update failure") } }
func TestValidateDeploymentConfigImageRepositorySupported(t *testing.T) { config := &api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Triggers: []api.DeploymentTriggerPolicy{ { Type: api.DeploymentTriggerOnImageChange, ImageChangeParams: &api.DeploymentTriggerImageChangeParams{ From: kapi.ObjectReference{ Kind: "ImageRepository", Name: "name", }, ContainerNames: []string{"foo"}, }, }, }, Template: test.OkDeploymentTemplate(), } errs := ValidateDeploymentConfig(config) if len(errs) > 0 { t.Errorf("Unxpected non-empty error list: %v", errs) } if e, a := "ImageRepository", config.Triggers[0].ImageChangeParams.From.Kind; e != a { t.Errorf("expected imageChangeParams.from.kind %s, got %s", e, a) } }
func TestValidateDeploymentConfigOK(t *testing.T) { errs := ValidateDeploymentConfig(&api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Triggers: manualTrigger(), Template: test.OkDeploymentTemplate(), }) if len(errs) > 0 { t.Errorf("Unxpected non-empty error list: %#v", errs) } }
func TestValidateDeploymentConfigMissingFields(t *testing.T) { errorCases := map[string]struct { D api.DeploymentConfig T fielderrors.ValidationErrorType F string }{ "missing name": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "", Namespace: "bar"}, Template: test.OkDeploymentTemplate(), }, fielderrors.ValidationErrorTypeRequired, "metadata.name", }, "missing namespace": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: ""}, Template: test.OkDeploymentTemplate(), }, fielderrors.ValidationErrorTypeRequired, "metadata.namespace", }, "invalid name": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "-foo", Namespace: "bar"}, Template: test.OkDeploymentTemplate(), }, fielderrors.ValidationErrorTypeInvalid, "metadata.name", }, "invalid namespace": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "-bar"}, Template: test.OkDeploymentTemplate(), }, fielderrors.ValidationErrorTypeInvalid, "metadata.namespace", }, "missing trigger.type": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Triggers: []api.DeploymentTriggerPolicy{ { ImageChangeParams: &api.DeploymentTriggerImageChangeParams{ ContainerNames: []string{"foo"}, }, }, }, Template: test.OkDeploymentTemplate(), }, fielderrors.ValidationErrorTypeRequired, "triggers[0].type", }, "missing Trigger imageChangeParams.from": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Triggers: []api.DeploymentTriggerPolicy{ { Type: api.DeploymentTriggerOnImageChange, ImageChangeParams: &api.DeploymentTriggerImageChangeParams{ ContainerNames: []string{"foo"}, }, }, }, Template: test.OkDeploymentTemplate(), }, fielderrors.ValidationErrorTypeRequired, "triggers[0].imageChangeParams.from", }, "invalid Trigger imageChangeParams.from.kind": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Triggers: []api.DeploymentTriggerPolicy{ { Type: api.DeploymentTriggerOnImageChange, ImageChangeParams: &api.DeploymentTriggerImageChangeParams{ From: kapi.ObjectReference{ Kind: "Invalid", Name: "name", }, ContainerNames: []string{"foo"}, }, }, }, Template: test.OkDeploymentTemplate(), }, fielderrors.ValidationErrorTypeInvalid, "triggers[0].imageChangeParams.from.kind", }, "both fields illegal Trigger imageChangeParams.repositoryName": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Triggers: []api.DeploymentTriggerPolicy{ { Type: api.DeploymentTriggerOnImageChange, ImageChangeParams: &api.DeploymentTriggerImageChangeParams{ ContainerNames: []string{"foo"}, RepositoryName: "name", From: kapi.ObjectReference{ Name: "other", }, }, }, }, Template: test.OkDeploymentTemplate(), }, fielderrors.ValidationErrorTypeInvalid, "triggers[0].imageChangeParams.repositoryName", }, "missing Trigger imageChangeParams.containerNames": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Triggers: []api.DeploymentTriggerPolicy{ { Type: api.DeploymentTriggerOnImageChange, ImageChangeParams: &api.DeploymentTriggerImageChangeParams{ RepositoryName: "foo", }, }, }, Template: test.OkDeploymentTemplate(), }, fielderrors.ValidationErrorTypeRequired, "triggers[0].imageChangeParams.containerNames", }, "missing strategy.type": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Triggers: manualTrigger(), Template: api.DeploymentTemplate{ Strategy: api.DeploymentStrategy{ CustomParams: test.OkCustomParams(), }, ControllerTemplate: test.OkControllerTemplate(), }, }, fielderrors.ValidationErrorTypeRequired, "template.strategy.type", }, "missing strategy.customParams": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Triggers: manualTrigger(), Template: api.DeploymentTemplate{ Strategy: api.DeploymentStrategy{ Type: api.DeploymentStrategyTypeCustom, }, ControllerTemplate: test.OkControllerTemplate(), }, }, fielderrors.ValidationErrorTypeRequired, "template.strategy.customParams", }, "missing template.strategy.customParams.image": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Triggers: manualTrigger(), Template: api.DeploymentTemplate{ Strategy: api.DeploymentStrategy{ Type: api.DeploymentStrategyTypeCustom, CustomParams: &api.CustomDeploymentStrategyParams{}, }, ControllerTemplate: test.OkControllerTemplate(), }, }, fielderrors.ValidationErrorTypeRequired, "template.strategy.customParams.image", }, "missing template.strategy.recreateParams.pre.failurePolicy": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Template: api.DeploymentTemplate{ Strategy: api.DeploymentStrategy{ Type: api.DeploymentStrategyTypeRecreate, RecreateParams: &api.RecreateDeploymentStrategyParams{ Pre: &api.LifecycleHook{ ExecNewPod: &api.ExecNewPodHook{ Command: []string{"cmd"}, ContainerName: "container", }, }, }, }, ControllerTemplate: test.OkControllerTemplate(), }, }, fielderrors.ValidationErrorTypeRequired, "template.strategy.recreateParams.pre.failurePolicy", }, "missing template.strategy.recreateParams.pre.execNewPod": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Template: api.DeploymentTemplate{ Strategy: api.DeploymentStrategy{ Type: api.DeploymentStrategyTypeRecreate, RecreateParams: &api.RecreateDeploymentStrategyParams{ Pre: &api.LifecycleHook{ FailurePolicy: api.LifecycleHookFailurePolicyRetry, }, }, }, ControllerTemplate: test.OkControllerTemplate(), }, }, fielderrors.ValidationErrorTypeRequired, "template.strategy.recreateParams.pre.execNewPod", }, "missing template.strategy.recreateParams.pre.execNewPod.command": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Template: api.DeploymentTemplate{ Strategy: api.DeploymentStrategy{ Type: api.DeploymentStrategyTypeRecreate, RecreateParams: &api.RecreateDeploymentStrategyParams{ Pre: &api.LifecycleHook{ FailurePolicy: api.LifecycleHookFailurePolicyRetry, ExecNewPod: &api.ExecNewPodHook{ ContainerName: "container", }, }, }, }, ControllerTemplate: test.OkControllerTemplate(), }, }, fielderrors.ValidationErrorTypeRequired, "template.strategy.recreateParams.pre.execNewPod.command", }, "missing template.strategy.recreateParams.pre.execNewPod.containerName": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Template: api.DeploymentTemplate{ Strategy: api.DeploymentStrategy{ Type: api.DeploymentStrategyTypeRecreate, RecreateParams: &api.RecreateDeploymentStrategyParams{ Pre: &api.LifecycleHook{ FailurePolicy: api.LifecycleHookFailurePolicyRetry, ExecNewPod: &api.ExecNewPodHook{ Command: []string{"cmd"}, }, }, }, }, ControllerTemplate: test.OkControllerTemplate(), }, }, fielderrors.ValidationErrorTypeRequired, "template.strategy.recreateParams.pre.execNewPod.containerName", }, "invalid template.strategy.rollingParams.intervalSeconds": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Triggers: manualTrigger(), Template: api.DeploymentTemplate{ Strategy: api.DeploymentStrategy{ Type: api.DeploymentStrategyTypeRolling, RollingParams: &api.RollingDeploymentStrategyParams{ IntervalSeconds: mkintp(-20), UpdatePeriodSeconds: mkintp(1), TimeoutSeconds: mkintp(1), }, }, ControllerTemplate: test.OkControllerTemplate(), }, }, fielderrors.ValidationErrorTypeInvalid, "template.strategy.rollingParams.intervalSeconds", }, "invalid template.strategy.rollingParams.updatePeriodSeconds": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Triggers: manualTrigger(), Template: api.DeploymentTemplate{ Strategy: api.DeploymentStrategy{ Type: api.DeploymentStrategyTypeRolling, RollingParams: &api.RollingDeploymentStrategyParams{ IntervalSeconds: mkintp(1), UpdatePeriodSeconds: mkintp(-20), TimeoutSeconds: mkintp(1), }, }, ControllerTemplate: test.OkControllerTemplate(), }, }, fielderrors.ValidationErrorTypeInvalid, "template.strategy.rollingParams.updatePeriodSeconds", }, "invalid template.strategy.rollingParams.timeoutSeconds": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Triggers: manualTrigger(), Template: api.DeploymentTemplate{ Strategy: api.DeploymentStrategy{ Type: api.DeploymentStrategyTypeRolling, RollingParams: &api.RollingDeploymentStrategyParams{ IntervalSeconds: mkintp(1), UpdatePeriodSeconds: mkintp(1), TimeoutSeconds: mkintp(-20), }, }, ControllerTemplate: test.OkControllerTemplate(), }, }, fielderrors.ValidationErrorTypeInvalid, "template.strategy.rollingParams.timeoutSeconds", }, "missing template.strategy.rollingParams.pre.failurePolicy": { api.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{Name: "foo", Namespace: "bar"}, Template: api.DeploymentTemplate{ Strategy: api.DeploymentStrategy{ Type: api.DeploymentStrategyTypeRolling, RollingParams: &api.RollingDeploymentStrategyParams{ IntervalSeconds: mkintp(1), UpdatePeriodSeconds: mkintp(1), TimeoutSeconds: mkintp(20), Pre: &api.LifecycleHook{ ExecNewPod: &api.ExecNewPodHook{ Command: []string{"cmd"}, ContainerName: "container", }, }, }, }, ControllerTemplate: test.OkControllerTemplate(), }, }, fielderrors.ValidationErrorTypeRequired, "template.strategy.rollingParams.pre.failurePolicy", }, } for k, v := range errorCases { errs := ValidateDeploymentConfig(&v.D) if len(errs) == 0 { t.Errorf("Expected failure for scenario %s", k) } for i := range errs { if errs[i].(*fielderrors.ValidationError).Type != v.T { t.Errorf("%s: expected errors to have type %s: %v", k, v.T, errs[i]) } if errs[i].(*fielderrors.ValidationError).Field != v.F { t.Errorf("%s: expected errors to have field %s: %v", k, v.F, errs[i]) } } } }
func TestExport(t *testing.T) { exporter := &defaultExporter{} baseSA := &kapi.ServiceAccount{} baseSA.Name = "my-sa" tests := []struct { name string object runtime.Object exact bool expectedObj runtime.Object expectedErr error }{ { name: "export deploymentConfig", object: deploytest.OkDeploymentConfig(1), expectedObj: &deployapi.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{ Name: "config", }, LatestVersion: 0, Triggers: []deployapi.DeploymentTriggerPolicy{ deploytest.OkImageChangeTrigger(), }, Template: deploytest.OkDeploymentTemplate(), }, expectedErr: nil, }, { name: "export imageStream", object: &imageapi.ImageStream{ ObjectMeta: kapi.ObjectMeta{ Name: "test", Namespace: "other", }, Spec: imageapi.ImageStreamSpec{ Tags: map[string]imageapi.TagReference{ "v1": { Annotations: map[string]string{"an": "annotation"}, }, }, }, Status: imageapi.ImageStreamStatus{ DockerImageRepository: "foo/bar", Tags: map[string]imageapi.TagEventList{ "v1": { Items: []imageapi.TagEvent{{Image: "the image"}}, }, }, }, }, expectedObj: &imageapi.ImageStream{ ObjectMeta: kapi.ObjectMeta{ Name: "test", Namespace: "", }, Spec: imageapi.ImageStreamSpec{ Tags: map[string]imageapi.TagReference{ "v1": { From: &kapi.ObjectReference{ Kind: "DockerImage", Name: "foo/bar:v1", }, Annotations: map[string]string{"an": "annotation"}, }, }, }, Status: imageapi.ImageStreamStatus{ Tags: map[string]imageapi.TagEventList{}, }, }, expectedErr: nil, }, { name: "remove unexportable SA secrets", object: &kapi.ServiceAccount{ ObjectMeta: kapi.ObjectMeta{ Name: baseSA.Name, }, ImagePullSecrets: []kapi.LocalObjectReference{ {Name: osautil.GetDockercfgSecretNamePrefix(baseSA) + "-foo"}, {Name: "another-pull-secret"}, }, Secrets: []kapi.ObjectReference{ {Name: osautil.GetDockercfgSecretNamePrefix(baseSA) + "-foo"}, {Name: osautil.GetTokenSecretNamePrefix(baseSA) + "-foo"}, {Name: "another-mountable-secret"}, }, }, expectedObj: &kapi.ServiceAccount{ ObjectMeta: kapi.ObjectMeta{ Name: baseSA.Name, }, ImagePullSecrets: []kapi.LocalObjectReference{ {Name: "another-pull-secret"}, }, Secrets: []kapi.ObjectReference{ {Name: "another-mountable-secret"}, }, }, expectedErr: nil, }, { name: "do not remove unexportable SA secrets with exact", object: &kapi.ServiceAccount{ ObjectMeta: kapi.ObjectMeta{ Name: baseSA.Name, }, ImagePullSecrets: []kapi.LocalObjectReference{ {Name: osautil.GetDockercfgSecretNamePrefix(baseSA) + "-foo"}, {Name: "another-pull-secret"}, }, Secrets: []kapi.ObjectReference{ {Name: osautil.GetDockercfgSecretNamePrefix(baseSA) + "-foo"}, {Name: osautil.GetTokenSecretNamePrefix(baseSA) + "-foo"}, {Name: "another-mountable-secret"}, }, }, expectedObj: &kapi.ServiceAccount{ ObjectMeta: kapi.ObjectMeta{ Name: baseSA.Name, }, ImagePullSecrets: []kapi.LocalObjectReference{ {Name: osautil.GetDockercfgSecretNamePrefix(baseSA) + "-foo"}, {Name: "another-pull-secret"}, }, Secrets: []kapi.ObjectReference{ {Name: osautil.GetDockercfgSecretNamePrefix(baseSA) + "-foo"}, {Name: osautil.GetTokenSecretNamePrefix(baseSA) + "-foo"}, {Name: "another-mountable-secret"}, }, }, exact: true, expectedErr: nil, }, } for _, test := range tests { if err := exporter.Export(test.object, test.exact); err != test.expectedErr { t.Errorf("error mismatch: expected %v, got %v", test.expectedErr, err) } if !reflect.DeepEqual(test.object, test.expectedObj) { t.Errorf("object mismatch: expected \n%v\ngot \n%v\n", test.expectedObj, test.object) } } }
func TestExport(t *testing.T) { exporter := &defaultExporter{} tests := []struct { name string object runtime.Object exact bool expectedObj runtime.Object expectedErr error }{ { name: "export deploymentConfig", object: deploytest.OkDeploymentConfig(1), expectedObj: &deployapi.DeploymentConfig{ ObjectMeta: kapi.ObjectMeta{ Name: "config", }, LatestVersion: 0, Triggers: []deployapi.DeploymentTriggerPolicy{ deploytest.OkImageChangeTrigger(), }, Template: deploytest.OkDeploymentTemplate(), }, expectedErr: nil, }, { name: "export imageStream", object: &imageapi.ImageStream{ ObjectMeta: kapi.ObjectMeta{ Name: "test", Namespace: "other", }, Spec: imageapi.ImageStreamSpec{ Tags: map[string]imageapi.TagReference{ "v1": { Annotations: map[string]string{"an": "annotation"}, }, }, }, Status: imageapi.ImageStreamStatus{ DockerImageRepository: "foo/bar", Tags: map[string]imageapi.TagEventList{ "v1": { Items: []imageapi.TagEvent{{Image: "the image"}}, }, }, }, }, expectedObj: &imageapi.ImageStream{ ObjectMeta: kapi.ObjectMeta{ Name: "test", Namespace: "", }, Spec: imageapi.ImageStreamSpec{ Tags: map[string]imageapi.TagReference{ "v1": { From: &kapi.ObjectReference{ Kind: "DockerImage", Name: "foo/bar:v1", }, Annotations: map[string]string{"an": "annotation"}, }, }, }, Status: imageapi.ImageStreamStatus{ Tags: map[string]imageapi.TagEventList{}, }, }, expectedErr: nil, }, } for _, test := range tests { if err := exporter.Export(test.object, test.exact); err != test.expectedErr { t.Errorf("error mismatch: expected %v, got %v", test.expectedErr, err) } if !reflect.DeepEqual(test.object, test.expectedObj) { t.Errorf("object mismatch: expected \n%v\ngot \n%v\n", test.expectedObj, test.object) } } }