package util import ( "sort" "strconv" "testing" "time" kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/unversioned" deployapi "github.com/openshift/origin/pkg/deploy/api" deploytest "github.com/openshift/origin/pkg/deploy/api/test" deployv1 "github.com/openshift/origin/pkg/deploy/api/v1" _ "github.com/openshift/origin/pkg/api/install" ) func podTemplateA() *kapi.PodTemplateSpec { t := deploytest.OkPodTemplate() t.Spec.Containers = append(t.Spec.Containers, kapi.Container{ Name: "container1", Image: "registry:8080/repo1:ref1", }) return t } func podTemplateB() *kapi.PodTemplateSpec { t := podTemplateA() t.Labels = map[string]string{"c": "d"} return t } func podTemplateC() *kapi.PodTemplateSpec { t := podTemplateA() t.Spec.Containers[0] = kapi.Container{ Name: "container2", Image: "registry:8080/repo1:ref3", } return t } func podTemplateD() *kapi.PodTemplateSpec { t := podTemplateA() t.Spec.Containers = append(t.Spec.Containers, kapi.Container{ Name: "container2", Image: "registry:8080/repo1:ref4", }) return t } func TestPodName(t *testing.T) { deployment := &kapi.ReplicationController{ ObjectMeta: kapi.ObjectMeta{ Name: "testName", }, } expected := "testName-deploy" actual := DeployerPodNameForDeployment(deployment.Name) if expected != actual { t.Errorf("Unexpected pod name for deployment. Expected: %s Got: %s", expected, actual) } } func TestMakeDeploymentOk(t *testing.T) { config := deploytest.OkDeploymentConfig(1) deployment, err := MakeDeployment(config, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) if err != nil { t.Fatalf("unexpected error: %#v", err) } expectedAnnotations := map[string]string{ deployapi.DeploymentConfigAnnotation: config.Name, deployapi.DeploymentStatusAnnotation: string(deployapi.DeploymentStatusNew), deployapi.DeploymentVersionAnnotation: strconv.FormatInt(config.Status.LatestVersion, 10), } for key, expected := range expectedAnnotations { if actual := deployment.Annotations[key]; actual != expected { t.Fatalf("expected deployment annotation %s=%s, got %s", key, expected, actual) } } expectedAnnotations = map[string]string{ deployapi.DeploymentAnnotation: deployment.Name, deployapi.DeploymentConfigAnnotation: config.Name, deployapi.DeploymentVersionAnnotation: strconv.FormatInt(config.Status.LatestVersion, 10), } for key, expected := range expectedAnnotations { if actual := deployment.Spec.Template.Annotations[key]; actual != expected { t.Fatalf("expected pod template annotation %s=%s, got %s", key, expected, actual) } } if len(EncodedDeploymentConfigFor(deployment)) == 0 { t.Fatalf("expected deployment with DeploymentEncodedConfigAnnotation annotation") } if decodedConfig, err := DecodeDeploymentConfig(deployment, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)); err != nil { t.Fatalf("invalid encoded config on deployment: %v", err) } else { if e, a := config.Name, decodedConfig.Name; e != a { t.Fatalf("encoded config name doesn't match source config") } // TODO: more assertions } if deployment.Spec.Replicas != 0 { t.Fatalf("expected deployment replicas to be 0") } if l, e, a := deployapi.DeploymentConfigAnnotation, config.Name, deployment.Labels[deployapi.DeploymentConfigAnnotation]; e != a { t.Fatalf("expected label %s=%s, got %s", l, e, a) } if e, a := config.Name, deployment.Spec.Template.Labels[deployapi.DeploymentConfigLabel]; e != a { t.Fatalf("expected label DeploymentConfigLabel=%s, got %s", e, a) } if e, a := deployment.Name, deployment.Spec.Template.Labels[deployapi.DeploymentLabel]; e != a { t.Fatalf("expected label DeploymentLabel=%s, got %s", e, a) } if e, a := config.Name, deployment.Spec.Selector[deployapi.DeploymentConfigLabel]; e != a { t.Fatalf("expected selector DeploymentConfigLabel=%s, got %s", e, a) } if e, a := deployment.Name, deployment.Spec.Selector[deployapi.DeploymentLabel]; e != a { t.Fatalf("expected selector DeploymentLabel=%s, got %s", e, a) } } func TestDeploymentsByLatestVersion_sorting(t *testing.T) { mkdeployment := func(version int64) kapi.ReplicationController { deployment, _ := MakeDeployment(deploytest.OkDeploymentConfig(version), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) return *deployment } deployments := []kapi.ReplicationController{ mkdeployment(4), mkdeployment(1), mkdeployment(2), mkdeployment(3), } sort.Sort(ByLatestVersionAsc(deployments)) for i := int64(0); i < 4; i++ { if e, a := i+1, DeploymentVersionFor(&deployments[i]); e != a { t.Errorf("expected deployment[%d]=%d, got %d", i, e, a) } } sort.Sort(ByLatestVersionDesc(deployments)) for i := int64(0); i < 4; i++ { if e, a := 4-i, DeploymentVersionFor(&deployments[i]); e != a { t.Errorf("expected deployment[%d]=%d, got %d", i, e, a) } } } // TestSort verifies that builds are sorted by most recently created func TestSort(t *testing.T) { present := unversioned.Now() past := unversioned.NewTime(present.Time.Add(-1 * time.Minute)) controllers := []*kapi.ReplicationController{ { ObjectMeta: kapi.ObjectMeta{ Name: "past", CreationTimestamp: past, }, }, { ObjectMeta: kapi.ObjectMeta{ Name: "present", CreationTimestamp: present, }, }, } sort.Sort(ByMostRecent(controllers)) if controllers[0].Name != "present" { t.Errorf("Unexpected sort order") } if controllers[1].Name != "past" { t.Errorf("Unexpected sort order") } } func TestCanTransitionPhase(t *testing.T) { tests := []struct { name string current, next deployapi.DeploymentStatus expected bool }{ { name: "New->New", current: deployapi.DeploymentStatusNew, next: deployapi.DeploymentStatusNew, expected: false, }, { name: "New->Pending", current: deployapi.DeploymentStatusNew, next: deployapi.DeploymentStatusPending, expected: true, }, { name: "New->Running", current: deployapi.DeploymentStatusNew, next: deployapi.DeploymentStatusRunning, expected: true, }, { name: "New->Complete", current: deployapi.DeploymentStatusNew, next: deployapi.DeploymentStatusComplete, expected: true, }, { name: "New->Failed", current: deployapi.DeploymentStatusNew, next: deployapi.DeploymentStatusFailed, expected: true, }, { name: "Pending->New", current: deployapi.DeploymentStatusPending, next: deployapi.DeploymentStatusNew, expected: false, }, { name: "Pending->Pending", current: deployapi.DeploymentStatusPending, next: deployapi.DeploymentStatusPending, expected: false, }, { name: "Pending->Running", current: deployapi.DeploymentStatusPending, next: deployapi.DeploymentStatusRunning, expected: true, }, { name: "Pending->Failed", current: deployapi.DeploymentStatusPending, next: deployapi.DeploymentStatusFailed, expected: true, }, { name: "Pending->Complete", current: deployapi.DeploymentStatusPending, next: deployapi.DeploymentStatusComplete, expected: true, }, { name: "Running->New", current: deployapi.DeploymentStatusRunning, next: deployapi.DeploymentStatusNew, expected: false, }, { name: "Running->Pending", current: deployapi.DeploymentStatusRunning, next: deployapi.DeploymentStatusPending, expected: false, }, { name: "Running->Running", current: deployapi.DeploymentStatusRunning, next: deployapi.DeploymentStatusRunning, expected: false, }, { name: "Running->Failed", current: deployapi.DeploymentStatusRunning, next: deployapi.DeploymentStatusFailed, expected: true, }, { name: "Running->Complete", current: deployapi.DeploymentStatusRunning, next: deployapi.DeploymentStatusComplete, expected: true, }, { name: "Complete->New", current: deployapi.DeploymentStatusComplete, next: deployapi.DeploymentStatusNew, expected: false, }, { name: "Complete->Pending", current: deployapi.DeploymentStatusComplete, next: deployapi.DeploymentStatusPending, expected: false, }, { name: "Complete->Running", current: deployapi.DeploymentStatusComplete, next: deployapi.DeploymentStatusRunning, expected: false, }, { name: "Complete->Failed", current: deployapi.DeploymentStatusComplete, next: deployapi.DeploymentStatusFailed, expected: false, }, { name: "Complete->Complete", current: deployapi.DeploymentStatusComplete, next: deployapi.DeploymentStatusComplete, expected: false, }, { name: "Failed->New", current: deployapi.DeploymentStatusFailed, next: deployapi.DeploymentStatusNew, expected: false, }, { name: "Failed->Pending", current: deployapi.DeploymentStatusFailed, next: deployapi.DeploymentStatusPending, expected: false, }, { name: "Failed->Running", current: deployapi.DeploymentStatusFailed, next: deployapi.DeploymentStatusRunning, expected: false, }, { name: "Failed->Complete", current: deployapi.DeploymentStatusFailed, next: deployapi.DeploymentStatusComplete, expected: false, }, { name: "Failed->Failed", current: deployapi.DeploymentStatusFailed, next: deployapi.DeploymentStatusFailed, expected: false, }, } for _, test := range tests { got := CanTransitionPhase(test.current, test.next) if got != test.expected { t.Errorf("%s: expected %t, got %t", test.name, test.expected, got) } } }