func TestNodeBuilder(t *testing.T) { node := &api.Node{ ObjectMeta: api.ObjectMeta{Name: "node1", Namespace: "should-not-have", ResourceVersion: "10"}, Spec: api.NodeSpec{ Capacity: api.ResourceList{ api.ResourceCPU: resource.MustParse("1000m"), api.ResourceMemory: resource.MustParse("1Mi"), }, }, } r, w := io.Pipe() go func() { defer w.Close() w.Write([]byte(runtime.EncodeOrDie(latest.Codec, node))) }() b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). NamespaceParam("test").Stream(r, "STDIN") test := &testVisitor{} err := b.Do().Visit(test.Handle) if err != nil || len(test.Infos) != 1 { t.Fatalf("unexpected response: %v %#v", err, test.Infos) } info := test.Infos[0] if info.Name != "node1" || info.Namespace != "" || info.Object == nil { t.Errorf("unexpected info: %#v", info) } }
func mockResources() kapi.ResourceRequirements { res := kapi.ResourceRequirements{} res.Limits = kapi.ResourceList{} res.Limits[kapi.ResourceCPU] = resource.MustParse("100m") res.Limits[kapi.ResourceMemory] = resource.MustParse("100Mi") return res }
func TestSyncResourceQuotaNoChange(t *testing.T) { quota := api.ResourceQuota{ Spec: api.ResourceQuotaSpec{ Hard: api.ResourceList{ api.ResourceCPU: resource.MustParse("4"), }, }, Status: api.ResourceQuotaStatus{ Hard: api.ResourceList{ api.ResourceCPU: resource.MustParse("4"), }, Used: api.ResourceList{ api.ResourceCPU: resource.MustParse("0"), }, }, } kubeClient := testclient.NewSimpleFake(&api.PodList{}, "a) ResourceQuotaController := NewResourceQuotaController(kubeClient) err := ResourceQuotaController.syncResourceQuota(quota) if err != nil { t.Fatalf("Unexpected error %v", err) } actions := kubeClient.Actions() if len(actions) != 1 && actions[0].Action != "list-pods" { t.Errorf("SyncResourceQuota made an unexpected client action when state was not dirty: %v", kubeClient.Actions) } }
func TestIncrementUsageReplicationControllers(t *testing.T) { namespace := "default" client := &client.Fake{ CtrlList: api.ReplicationControllerList{ Items: []api.ReplicationController{ { ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace}, }, }, }, } status := &api.ResourceQuotaStatus{ Hard: api.ResourceList{}, Used: api.ResourceList{}, } r := api.ResourceReplicationControllers status.Hard[r] = resource.MustParse("2") status.Used[r] = resource.MustParse("1") dirty, err := IncrementUsage(admission.NewAttributesRecord(&api.ReplicationController{}, namespace, "replicationControllers", "CREATE"), status, client) if err != nil { t.Errorf("Unexpected error", err) } if !dirty { t.Errorf("Expected the status to get incremented, therefore should have been dirty") } quantity := status.Used[r] if quantity.Value() != int64(2) { t.Errorf("Expected new item count to be 2, but was %s", quantity.String()) } }
func (resourceDefaults) Admit(a admission.Attributes) (err error) { // ignore deletes, only process create and update if a.GetOperation() == "DELETE" { return nil } // we only care about pods if a.GetResource() != "pods" { return nil } // get the pod, so we can validate each of the containers within have default mem / cpu constraints obj := a.GetObject() pod := obj.(*api.Pod) for index := range pod.Spec.Containers { if pod.Spec.Containers[index].Resources.Limits == nil { pod.Spec.Containers[index].Resources.Limits = api.ResourceList{} } if pod.Spec.Containers[index].Resources.Limits.Memory().Value() == 0 { pod.Spec.Containers[index].Resources.Limits[api.ResourceMemory] = resource.MustParse(defaultMemory) } if pod.Spec.Containers[index].Resources.Limits.Cpu().Value() == 0 { pod.Spec.Containers[index].Resources.Limits[api.ResourceCPU] = resource.MustParse(defaultCPU) } } return nil }
func TestIncrementUsagePods(t *testing.T) { namespace := "default" client := &client.Fake{ PodsList: api.PodList{ Items: []api.Pod{ { ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace}, Spec: api.PodSpec{ Volumes: []api.Volume{{Name: "vol"}}, Containers: []api.Container{{Name: "ctr", Image: "image", Resources: getResourceRequirements("100m", "1Gi")}}, }, }, }, }, } status := &api.ResourceQuotaStatus{ Hard: api.ResourceList{}, Used: api.ResourceList{}, } r := api.ResourcePods status.Hard[r] = resource.MustParse("2") status.Used[r] = resource.MustParse("1") dirty, err := IncrementUsage(admission.NewAttributesRecord(&api.Pod{}, namespace, "pods", "CREATE"), status, client) if err != nil { t.Errorf("Unexpected error", err) } if !dirty { t.Errorf("Expected the status to get incremented, therefore should have been dirty") } quantity := status.Used[r] if quantity.Value() != int64(2) { t.Errorf("Expected new item count to be 2, but was %s", quantity.String()) } }
func TestUpdateMinion(t *testing.T) { requestMinion := &api.Node{ ObjectMeta: api.ObjectMeta{ Name: "foo", ResourceVersion: "1", }, Status: api.NodeStatus{ Capacity: api.ResourceList{ api.ResourceCPU: resource.MustParse("1000m"), api.ResourceMemory: resource.MustParse("1Mi"), }, }, Spec: api.NodeSpec{ Unschedulable: true, }, } c := &testClient{ Request: testRequest{ Method: "PUT", Path: testapi.ResourcePath(getNodesResourceName(), "", "foo"), }, Response: Response{StatusCode: 200, Body: requestMinion}, } response, err := c.Setup().Nodes().Update(requestMinion) c.Validate(t, response, err) }
func TestExceedUsagePods(t *testing.T) { namespace := "default" client := &client.Fake{ PodsList: api.PodList{ Items: []api.Pod{ { ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace}, Spec: api.PodSpec{ Volumes: []api.Volume{{Name: "vol"}}, Containers: []api.Container{{Name: "ctr", Image: "image", Resources: getResourceRequirements("100m", "1Gi")}}, }, }, }, }, } status := &api.ResourceQuotaStatus{ Hard: api.ResourceList{}, Used: api.ResourceList{}, } r := api.ResourcePods status.Hard[r] = resource.MustParse("1") status.Used[r] = resource.MustParse("1") _, err := IncrementUsage(admission.NewAttributesRecord(&api.Pod{}, namespace, "pods", "CREATE"), status, client) if err == nil { t.Errorf("Expected error because this would exceed your quota") } }
func TestInvalidLimitRangeUpdate(t *testing.T) { ns := api.NamespaceDefault limitRange := &api.LimitRange{ ObjectMeta: api.ObjectMeta{ Name: "abc", }, Spec: api.LimitRangeSpec{ Limits: []api.LimitRangeItem{ { Type: api.LimitTypePod, Max: api.ResourceList{ api.ResourceCPU: resource.MustParse("100"), api.ResourceMemory: resource.MustParse("10000"), }, Min: api.ResourceList{ api.ResourceCPU: resource.MustParse("0"), api.ResourceMemory: resource.MustParse("100"), }, }, }, }, } c := &testClient{ Request: testRequest{Method: "PUT", Path: buildResourcePath(ns, "/limitRanges/abc"), Query: buildQueryValues(ns, nil)}, Response: Response{StatusCode: 200, Body: limitRange}, } _, err := c.Setup().LimitRanges(ns).Update(limitRange) if err == nil { t.Errorf("Expected an error due to missing ResourceVersion") } }
func TestLimitRangeGet(t *testing.T) { ns := api.NamespaceDefault limitRange := &api.LimitRange{ ObjectMeta: api.ObjectMeta{ Name: "abc", }, Spec: api.LimitRangeSpec{ Limits: []api.LimitRangeItem{ { Type: api.LimitTypePod, Max: api.ResourceList{ api.ResourceCPU: resource.MustParse("100"), api.ResourceMemory: resource.MustParse("10000"), }, Min: api.ResourceList{ api.ResourceCPU: resource.MustParse("0"), api.ResourceMemory: resource.MustParse("100"), }, }, }, }, } c := &testClient{ Request: testRequest{ Method: "GET", Path: buildResourcePath(ns, "/limitRanges/abc"), Query: buildQueryValues(ns, nil), Body: nil, }, Response: Response{StatusCode: 200, Body: limitRange}, } response, err := c.Setup().LimitRanges(ns).Get("abc") c.Validate(t, response, err) }
func TestAdmissionIgnoresSubresources(t *testing.T) { indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"namespace": cache.MetaNamespaceIndexFunc}) handler := createResourceQuota(&testclient.Fake{}, indexer) quota := &api.ResourceQuota{} quota.Name = "quota" quota.Namespace = "test" quota.Status = api.ResourceQuotaStatus{ Hard: api.ResourceList{}, Used: api.ResourceList{}, } quota.Status.Hard[api.ResourceMemory] = resource.MustParse("2Gi") quota.Status.Used[api.ResourceMemory] = resource.MustParse("1Gi") indexer.Add(quota) newPod := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "123", Namespace: quota.Namespace}, Spec: api.PodSpec{ Volumes: []api.Volume{{Name: "vol"}}, Containers: []api.Container{{Name: "ctr", Image: "image", Resources: getResourceRequirements("100m", "2Gi")}}, }} err := handler.Admit(admission.NewAttributesRecord(newPod, "Pod", newPod.Namespace, "pods", "", admission.Create, nil)) if err == nil { t.Errorf("Expected an error because the pod exceeded allowed quota") } err = handler.Admit(admission.NewAttributesRecord(newPod, "Pod", newPod.Namespace, "pods", "subresource", admission.Create, nil)) if err != nil { t.Errorf("Did not expect an error because the action went to a subresource: %v", err) } }
func TestCreateMinion(t *testing.T) { requestMinion := &api.Node{ ObjectMeta: api.ObjectMeta{ Name: "minion-1", }, Status: api.NodeStatus{ HostIP: "123.321.456.654", }, Spec: api.NodeSpec{ Capacity: api.ResourceList{ api.ResourceCPU: resource.MustParse("1000m"), api.ResourceMemory: resource.MustParse("1Mi"), }, }, } c := &testClient{ Request: testRequest{Method: "POST", Path: "/minions", Body: requestMinion}, Response: Response{ StatusCode: 200, Body: requestMinion, }, } receivedMinion, err := c.Setup().Nodes().Create(requestMinion) c.Validate(t, receivedMinion, err) }
func TestIncrementUsageServices(t *testing.T) { namespace := "default" client := testclient.NewSimpleFake(&api.ServiceList{ Items: []api.Service{ { ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace}, }, }, }) status := &api.ResourceQuotaStatus{ Hard: api.ResourceList{}, Used: api.ResourceList{}, } r := api.ResourceServices status.Hard[r] = resource.MustParse("2") status.Used[r] = resource.MustParse("1") dirty, err := IncrementUsage(admission.NewAttributesRecord(&api.Service{}, "Service", namespace, "services", "", admission.Create, nil), status, client) if err != nil { t.Errorf("Unexpected error: %v", err) } if !dirty { t.Errorf("Expected the status to get incremented, therefore should have been dirty") } quantity := status.Used[r] if quantity.Value() != int64(2) { t.Errorf("Expected new item count to be 2, but was %s", quantity.String()) } }
func TestExceedUsageCPU(t *testing.T) { namespace := "default" client := testclient.NewSimpleFake(&api.PodList{ Items: []api.Pod{ { ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace}, Spec: api.PodSpec{ Volumes: []api.Volume{{Name: "vol"}}, Containers: []api.Container{{Name: "ctr", Image: "image", Resources: getResourceRequirements("100m", "1Gi")}}, }, }, }, }) status := &api.ResourceQuotaStatus{ Hard: api.ResourceList{}, Used: api.ResourceList{}, } r := api.ResourceCPU status.Hard[r] = resource.MustParse("200m") status.Used[r] = resource.MustParse("100m") newPod := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace}, Spec: api.PodSpec{ Volumes: []api.Volume{{Name: "vol"}}, Containers: []api.Container{{Name: "ctr", Image: "image", Resources: getResourceRequirements("500m", "1Gi")}}, }} _, err := IncrementUsage(admission.NewAttributesRecord(newPod, "Pod", namespace, "pods", "", admission.Create, nil), status, client) if err == nil { t.Errorf("Expected CPU usage exceeded error") } }
func TestResourceHelpers(t *testing.T) { cpuLimit := resource.MustParse("10") memoryLimit := resource.MustParse("10G") resourceSpec := ResourceRequirements{ Limits: ResourceList{ "cpu": cpuLimit, "memory": memoryLimit, "kube.io/storage": memoryLimit, }, } if res := resourceSpec.Limits.Cpu(); *res != cpuLimit { t.Errorf("expected cpulimit %d, got %d", cpuLimit, res) } if res := resourceSpec.Limits.Memory(); *res != memoryLimit { t.Errorf("expected memorylimit %d, got %d", memoryLimit, res) } resourceSpec = ResourceRequirements{ Limits: ResourceList{ "memory": memoryLimit, "kube.io/storage": memoryLimit, }, } if res := resourceSpec.Limits.Cpu(); res.Value() != 0 { t.Errorf("expected cpulimit %d, got %d", 0, res) } if res := resourceSpec.Limits.Memory(); *res != memoryLimit { t.Errorf("expected memorylimit %d, got %d", memoryLimit, res) } }
func TestSyncResourceQuotaSpecChange(t *testing.T) { quota := api.ResourceQuota{ Spec: api.ResourceQuotaSpec{ Hard: api.ResourceList{ api.ResourceCPU: resource.MustParse("4"), }, }, Status: api.ResourceQuotaStatus{ Hard: api.ResourceList{ api.ResourceCPU: resource.MustParse("3"), }, Used: api.ResourceList{ api.ResourceCPU: resource.MustParse("0"), }, }, } expectedUsage := api.ResourceQuota{ Status: api.ResourceQuotaStatus{ Hard: api.ResourceList{ api.ResourceCPU: resource.MustParse("4"), }, Used: api.ResourceList{ api.ResourceCPU: resource.MustParse("0"), }, }, } kubeClient := testclient.NewSimpleFake("a) ResourceQuotaController := NewResourceQuotaController(kubeClient) err := ResourceQuotaController.syncResourceQuota(quota) if err != nil { t.Fatalf("Unexpected error %v", err) } usage := kubeClient.Actions()[1].Value.(*api.ResourceQuota) // ensure hard and used limits are what we expected for k, v := range expectedUsage.Status.Hard { actual := usage.Status.Hard[k] actualValue := actual.String() expectedValue := v.String() if expectedValue != actualValue { t.Errorf("Usage Hard: Key: %v, Expected: %v, Actual: %v", k, expectedValue, actualValue) } } for k, v := range expectedUsage.Status.Used { actual := usage.Status.Used[k] actualValue := actual.String() expectedValue := v.String() if expectedValue != actualValue { t.Errorf("Usage Used: Key: %v, Expected: %v, Actual: %v", k, expectedValue, actualValue) } } }
func getResourceList(cpu, memory string) api.ResourceList { res := api.ResourceList{} if cpu != "" { res[api.ResourceCPU] = resource.MustParse(cpu) } if memory != "" { res[api.ResourceMemory] = resource.MustParse(memory) } return res }
func OkStrategy() deployapi.DeploymentStrategy { return deployapi.DeploymentStrategy{ Type: deployapi.DeploymentStrategyTypeRecreate, Resources: kapi.ResourceRequirements{ Limits: kapi.ResourceList{ kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"), kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("10G"), }, }, } }
func getResourceRequirements(cpu, memory string) api.ResourceRequirements { res := api.ResourceRequirements{} res.Limits = api.ResourceList{} if cpu != "" { res.Limits[api.ResourceCPU] = resource.MustParse(cpu) } if memory != "" { res.Limits[api.ResourceMemory] = resource.MustParse(memory) } return res }
func mockSTIBuild() *buildapi.Build { return &buildapi.Build{ ObjectMeta: kapi.ObjectMeta{ Name: "stiBuild", Labels: map[string]string{ "name": "stiBuild", }, }, Spec: buildapi.BuildSpec{ Revision: &buildapi.SourceRevision{ Git: &buildapi.GitSourceRevision{}, }, Source: buildapi.BuildSource{ Git: &buildapi.GitBuildSource{ URI: "http://my.build.com/the/stibuild/Dockerfile", }, SourceSecret: &kapi.LocalObjectReference{Name: "fooSecret"}, }, Strategy: buildapi.BuildStrategy{ Type: buildapi.SourceBuildStrategyType, SourceStrategy: &buildapi.SourceBuildStrategy{ From: kapi.ObjectReference{ Kind: "DockerImage", Name: "repository/sti-builder", }, PullSecret: &kapi.LocalObjectReference{Name: "bar"}, Scripts: "http://my.build.com/the/sti/scripts", Env: []kapi.EnvVar{ {Name: "BUILD_LOGLEVEL", Value: "bar"}, {Name: "ILLEGAL", Value: "foo"}, }, }, }, Output: buildapi.BuildOutput{ To: &kapi.ObjectReference{ Kind: "DockerImage", Name: "docker-registry/repository/stiBuild", }, PushSecret: &kapi.LocalObjectReference{Name: "foo"}, }, Resources: kapi.ResourceRequirements{ Limits: kapi.ResourceList{ kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"), kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("10G"), }, }, }, Status: buildapi.BuildStatus{ Phase: buildapi.BuildPhaseNew, }, } }
func mockCustomBuild() *buildapi.Build { return &buildapi.Build{ ObjectMeta: kapi.ObjectMeta{ Name: "customBuild", Labels: map[string]string{ "name": "customBuild", }, }, Spec: buildapi.BuildSpec{ Revision: &buildapi.SourceRevision{ Git: &buildapi.GitSourceRevision{}, }, Source: buildapi.BuildSource{ Type: buildapi.BuildSourceGit, Git: &buildapi.GitBuildSource{ URI: "http://my.build.com/the/dockerbuild/Dockerfile", Ref: "master", }, SourceSecret: &kapi.LocalObjectReference{Name: "secretFoo"}, }, Strategy: buildapi.BuildStrategy{ Type: buildapi.CustomBuildStrategyType, CustomStrategy: &buildapi.CustomBuildStrategy{ From: kapi.ObjectReference{ Kind: "DockerImage", Name: "builder-image", }, Env: []kapi.EnvVar{ {Name: "FOO", Value: "BAR"}, }, ExposeDockerSocket: true, }, }, Output: buildapi.BuildOutput{ To: &kapi.ObjectReference{ Kind: "DockerImage", Name: "docker-registry/repository/customBuild", }, PushSecret: &kapi.LocalObjectReference{Name: "foo"}, }, Resources: kapi.ResourceRequirements{ Limits: kapi.ResourceList{ kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"), kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("10G"), }, }, }, Status: buildapi.BuildStatus{ Phase: buildapi.BuildPhaseNew, }, } }
func TestContainerConversion(t *testing.T) { cpuLimit := resource.MustParse("10") memoryLimit := resource.MustParse("10M") null := resource.Quantity{} testCases := []current.Container{ { Name: "container", Resources: getResourceRequirements(cpuLimit, memoryLimit), }, { Name: "container", CPU: int(cpuLimit.MilliValue()), Resources: getResourceRequirements(null, memoryLimit), }, { Name: "container", Memory: memoryLimit.Value(), Resources: getResourceRequirements(cpuLimit, null), }, { Name: "container", CPU: int(cpuLimit.MilliValue()), Memory: memoryLimit.Value(), }, { Name: "container", Memory: memoryLimit.Value(), Resources: getResourceRequirements(cpuLimit, resource.MustParse("100M")), }, { Name: "container", CPU: int(cpuLimit.MilliValue()), Resources: getResourceRequirements(resource.MustParse("500"), memoryLimit), }, } for i, tc := range testCases { got := newer.Container{} if err := Convert(&tc, &got); err != nil { t.Errorf("[Case: %d] Unexpected error: %v", i, err) continue } if cpu := got.Resources.Limits.Cpu(); cpu.Value() != cpuLimit.Value() { t.Errorf("[Case: %d] Expected cpu: %v, got: %v", i, cpuLimit, *cpu) } if memory := got.Resources.Limits.Memory(); memory.Value() != memoryLimit.Value() { t.Errorf("[Case: %d] Expected memory: %v, got: %v", i, memoryLimit, *memory) } } }
func newNode(name string) *api.Node { return &api.Node{ ObjectMeta: api.ObjectMeta{Name: name}, Spec: api.NodeSpec{ ExternalID: name, }, Status: api.NodeStatus{ Capacity: api.ResourceList{ api.ResourceName(api.ResourceCPU): resource.MustParse("10"), api.ResourceName(api.ResourceMemory): resource.MustParse("10G"), }, }, } }
func makePersistentVolume(serverIP string) *api.PersistentVolume { return &api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ GenerateName: "nfs-", }, Spec: api.PersistentVolumeSpec{ PersistentVolumeReclaimPolicy: api.PersistentVolumeReclaimRecycle, Capacity: api.ResourceList{ api.ResourceName(api.ResourceStorage): resource.MustParse("2Gi"), }, PersistentVolumeSource: api.PersistentVolumeSource{ NFS: &api.NFSVolumeSource{ Server: serverIP, Path: "/", ReadOnly: false, }, }, AccessModes: []api.PersistentVolumeAccessMode{ api.ReadWriteOnce, api.ReadOnlyMany, api.ReadWriteMany, }, }, } }
func TestPersistentVolumeClaimGet(t *testing.T) { ns := api.NamespaceDefault persistentVolumeClaim := &api.PersistentVolumeClaim{ ObjectMeta: api.ObjectMeta{ Name: "abc", Namespace: "foo", }, Spec: api.PersistentVolumeClaimSpec{ AccessModes: []api.AccessModeType{ api.ReadWriteOnce, api.ReadOnlyMany, }, Resources: api.ResourceRequirements{ Requests: api.ResourceList{ api.ResourceName(api.ResourceStorage): resource.MustParse("10G"), }, }, }, } c := &testClient{ Request: testRequest{ Method: "GET", Path: testapi.ResourcePath(getPersistentVolumeClaimsResoureName(), ns, "abc"), Query: buildQueryValues(ns, nil), Body: nil, }, Response: Response{StatusCode: 200, Body: persistentVolumeClaim}, } response, err := c.Setup().PersistentVolumeClaims(ns).Get("abc") c.Validate(t, response, err) }
func TestPersistentVolumeClaimStatusUpdate(t *testing.T) { ns := api.NamespaceDefault persistentVolumeClaim := &api.PersistentVolumeClaim{ ObjectMeta: api.ObjectMeta{ Name: "abc", ResourceVersion: "1", }, Spec: api.PersistentVolumeClaimSpec{ AccessModes: []api.PersistentVolumeAccessMode{ api.ReadWriteOnce, api.ReadOnlyMany, }, Resources: api.ResourceRequirements{ Requests: api.ResourceList{ api.ResourceName(api.ResourceStorage): resource.MustParse("10G"), }, }, }, Status: api.PersistentVolumeClaimStatus{ Phase: api.ClaimBound, }, } c := &testClient{ Request: testRequest{ Method: "PUT", Path: testapi.ResourcePath(getPersistentVolumeClaimsResoureName(), ns, "abc") + "/status", Query: buildQueryValues(ns, nil)}, Response: Response{StatusCode: 200, Body: persistentVolumeClaim}, } response, err := c.Setup().PersistentVolumeClaims(ns).UpdateStatus(persistentVolumeClaim) c.Validate(t, response, err) }
func TestMergePodResourceRequirements(t *testing.T) { limitRange := validLimitRange() // pod with no resources enumerated should get each resource from default expected := getResourceRequirements(getResourceList("", ""), getResourceList("", "")) pod := validPod("empty-resources", 1, expected) defaultRequirements := defaultContainerResourceRequirements(&limitRange) mergePodResourceRequirements(&pod, &defaultRequirements) for i := range pod.Spec.Containers { actual := pod.Spec.Containers[i].Resources if !api.Semantic.DeepEqual(expected, actual) { t.Errorf("pod %v, expected != actual; %v != %v", pod.Name, expected, actual) } } // pod with some resources enumerated should only merge empty input := getResourceRequirements(getResourceList("", "512Mi"), getResourceList("", "")) pod = validPod("limit-memory", 1, input) expected = api.ResourceRequirements{ Limits: api.ResourceList{ api.ResourceCPU: defaultRequirements.Limits[api.ResourceCPU], api.ResourceMemory: resource.MustParse("512Mi"), }, Requests: api.ResourceList{}, } mergePodResourceRequirements(&pod, &defaultRequirements) for i := range pod.Spec.Containers { actual := pod.Spec.Containers[i].Resources if !api.Semantic.DeepEqual(expected, actual) { t.Errorf("pod %v, expected != actual; %v != %v", pod.Name, expected, actual) } } }
func TestResourceQuotaStatusConversion(t *testing.T) { // should serialize as "0" expected := resource.NewQuantity(int64(0), resource.DecimalSI) if "0" != expected.String() { t.Errorf("Expected: 0, Actual: %v, do not require units", expected.String()) } parsed := resource.MustParse("0") if "0" != parsed.String() { t.Errorf("Expected: 0, Actual: %v, do not require units", parsed.String()) } quota := &api.ResourceQuota{} quota.Status = api.ResourceQuotaStatus{} quota.Status.Hard = api.ResourceList{} quota.Status.Used = api.ResourceList{} quota.Status.Hard[api.ResourcePods] = *expected // round-trip the object data, _ := versioned.Codec.Encode(quota) object, _ := versioned.Codec.Decode(data) after := object.(*api.ResourceQuota) actualQuantity := after.Status.Hard[api.ResourcePods] actual := &actualQuantity // should be "0", but was "0m" if expected.String() != actual.String() { t.Errorf("Expected %v, Actual %v", expected.String(), actual.String()) } }
func TestPersistentVolumeGet(t *testing.T) { persistentVolume := &api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ Name: "abc", Namespace: "foo", }, Spec: api.PersistentVolumeSpec{ Capacity: api.ResourceList{ api.ResourceName(api.ResourceStorage): resource.MustParse("10G"), }, PersistentVolumeSource: api.PersistentVolumeSource{ HostPath: &api.HostPathVolumeSource{Path: "/foo"}, }, }, } c := &testClient{ Request: testRequest{ Method: "GET", Path: testapi.ResourcePath(getPersistentVolumesResoureName(), "", "abc"), Query: buildQueryValues("", nil), Body: nil, }, Response: Response{StatusCode: 200, Body: persistentVolume}, } response, err := c.Setup().PersistentVolumes().Get("abc") c.Validate(t, response, err) }
func TestPersistentVolumeStatusUpdate(t *testing.T) { persistentVolume := &api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ Name: "abc", ResourceVersion: "1", }, Spec: api.PersistentVolumeSpec{ Capacity: api.ResourceList{ api.ResourceName(api.ResourceStorage): resource.MustParse("10G"), }, PersistentVolumeSource: api.PersistentVolumeSource{ HostPath: &api.HostPathVolumeSource{Path: "/foo"}, }, }, Status: api.PersistentVolumeStatus{ Phase: api.VolumeBound, }, } c := &testClient{ Request: testRequest{ Method: "PUT", Path: testapi.ResourcePath(getPersistentVolumesResoureName(), "", "abc") + "/status", Query: buildQueryValues("", nil)}, Response: Response{StatusCode: 200, Body: persistentVolume}, } response, err := c.Setup().PersistentVolumes().UpdateStatus(persistentVolume) c.Validate(t, response, err) }