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 %v, got %v", cpuLimit, res)
	}
	if res := resourceSpec.Limits.Memory(); *res != memoryLimit {
		t.Errorf("expected memorylimit %v, got %v", memoryLimit, res)
	}
	resourceSpec = ResourceRequirements{
		Limits: ResourceList{
			"memory":          memoryLimit,
			"kube.io/storage": memoryLimit,
		},
	}
	if res := resourceSpec.Limits.Cpu(); res.Value() != 0 {
		t.Errorf("expected cpulimit %v, got %v", 0, res)
	}
	if res := resourceSpec.Limits.Memory(); *res != memoryLimit {
		t.Errorf("expected memorylimit %v, got %v", memoryLimit, res)
	}
}
func TestLimitRangeUpdate(t *testing.T) {
	ns := api.NamespaceDefault
	limitRange := &api.LimitRange{
		ObjectMeta: api.ObjectMeta{
			Name:            "abc",
			ResourceVersion: "1",
		},
		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 := &simple.Client{
		Request:  simple.Request{Method: "PUT", Path: testapi.Default.ResourcePath(getLimitRangesResourceName(), ns, "abc"), Query: simple.BuildQueryValues(nil)},
		Response: simple.Response{StatusCode: 200, Body: limitRange},
	}
	response, err := c.Setup(t).LimitRanges(ns).Update(limitRange)
	defer c.Close()
	c.Validate(t, response, err)
}
Exemple #3
0
func TestUpdateNode(t *testing.T) {
	requestNode := &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 := &simple.Client{
		Request: simple.Request{
			Method: "PUT",
			Path:   testapi.Default.ResourcePath(getNodesResourceName(), "", "foo"),
		},
		Response: simple.Response{StatusCode: 200, Body: requestNode},
	}
	response, err := c.Setup(t).Nodes().Update(requestNode)
	defer c.Close()
	c.Validate(t, response, err)
}
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 := &simple.Client{
		Request: simple.Request{
			Method: "GET",
			Path:   testapi.Default.ResourcePath(getPersistentVolumesResoureName(), "", "abc"),
			Query:  simple.BuildQueryValues(nil),
			Body:   nil,
		},
		Response: simple.Response{StatusCode: 200, Body: persistentVolume},
	}

	response, err := c.Setup(t).PersistentVolumes().Get("abc")
	defer c.Close()
	c.Validate(t, response, err)
}
func TestDefaultRequestIsNotSetForReplicaSet(t *testing.T) {
	s := v1.PodSpec{}
	s.Containers = []v1.Container{
		{
			Resources: v1.ResourceRequirements{
				Limits: v1.ResourceList{
					v1.ResourceCPU: resource.MustParse("100m"),
				},
			},
		},
	}
	rs := &ReplicaSet{
		Spec: ReplicaSetSpec{
			Replicas: newInt32(3),
			Template: &v1.PodTemplateSpec{
				ObjectMeta: v1.ObjectMeta{
					Labels: map[string]string{
						"foo": "bar",
					},
				},
				Spec: s,
			},
		},
	}
	output := roundTrip(t, runtime.Object(rs))
	rs2 := output.(*ReplicaSet)
	defaultRequest := rs2.Spec.Template.Spec.Containers[0].Resources.Requests
	requestValue := defaultRequest[v1.ResourceCPU]
	if requestValue.String() != "0" {
		t.Errorf("Expected 0 request value, got: %s", requestValue.String())
	}
}
func TestDefaultRequestIsNotSetForReplicationController(t *testing.T) {
	s := versioned.PodSpec{}
	s.Containers = []versioned.Container{
		{
			Resources: versioned.ResourceRequirements{
				Limits: versioned.ResourceList{
					versioned.ResourceCPU: resource.MustParse("100m"),
				},
			},
		},
	}
	rc := &versioned.ReplicationController{
		Spec: versioned.ReplicationControllerSpec{
			Replicas: newInt(3),
			Template: &versioned.PodTemplateSpec{
				ObjectMeta: versioned.ObjectMeta{
					Labels: map[string]string{
						"foo": "bar",
					},
				},
				Spec: s,
			},
		},
	}
	output := roundTrip(t, runtime.Object(rc))
	rc2 := output.(*versioned.ReplicationController)
	defaultRequest := rc2.Spec.Template.Spec.Containers[0].Resources.Requests
	requestValue := defaultRequest[versioned.ResourceCPU]
	if requestValue.String() != "0" {
		t.Errorf("Expected 0 request value, got: %s", requestValue.String())
	}
}
func TestPersistentVolumeClaimGet(t *testing.T) {
	ns := api.NamespaceDefault
	persistentVolumeClaim := &api.PersistentVolumeClaim{
		ObjectMeta: api.ObjectMeta{
			Name:      "abc",
			Namespace: "foo",
		},
		Spec: api.PersistentVolumeClaimSpec{
			AccessModes: []api.PersistentVolumeAccessMode{
				api.ReadWriteOnce,
				api.ReadOnlyMany,
			},
			Resources: api.ResourceRequirements{
				Requests: api.ResourceList{
					api.ResourceName(api.ResourceStorage): resource.MustParse("10G"),
				},
			},
		},
	}
	c := &simple.Client{
		Request: simple.Request{
			Method: "GET",
			Path:   testapi.Default.ResourcePath(getPersistentVolumeClaimsResoureName(), ns, "abc"),
			Query:  simple.BuildQueryValues(nil),
			Body:   nil,
		},
		Response: simple.Response{StatusCode: 200, Body: persistentVolumeClaim},
	}

	response, err := c.Setup(t).PersistentVolumeClaims(ns).Get("abc")
	defer c.Close()
	c.Validate(t, response, err)
}
func ExampleMustParse() {
	memorySize := resource.MustParse("5Gi")
	fmt.Printf("memorySize = %v (%v)\n", memorySize.Value(), memorySize.Format)

	diskSize := resource.MustParse("5G")
	fmt.Printf("diskSize = %v (%v)\n", diskSize.Value(), diskSize.Format)

	cores := resource.MustParse("5300m")
	fmt.Printf("milliCores = %v (%v)\n", cores.MilliValue(), cores.Format)

	cores2 := resource.MustParse("5.4")
	fmt.Printf("milliCores = %v (%v)\n", cores2.MilliValue(), cores2.Format)

	// Output:
	// memorySize = 5368709120 (BinarySI)
	// diskSize = 5000000000 (DecimalSI)
	// milliCores = 5300 (DecimalSI)
	// milliCores = 5400 (DecimalSI)
}
func TestSetDefaultLimitRangeItem(t *testing.T) {
	limitRange := &versioned.LimitRange{
		ObjectMeta: versioned.ObjectMeta{
			Name: "test-defaults",
		},
		Spec: versioned.LimitRangeSpec{
			Limits: []versioned.LimitRangeItem{{
				Type: versioned.LimitTypeContainer,
				Max: versioned.ResourceList{
					versioned.ResourceCPU: resource.MustParse("100m"),
				},
				Min: versioned.ResourceList{
					versioned.ResourceMemory: resource.MustParse("100Mi"),
				},
				Default:        versioned.ResourceList{},
				DefaultRequest: versioned.ResourceList{},
			}},
		},
	}

	output := roundTrip(t, runtime.Object(limitRange))
	limitRange2 := output.(*versioned.LimitRange)
	defaultLimit := limitRange2.Spec.Limits[0].Default
	defaultRequest := limitRange2.Spec.Limits[0].DefaultRequest

	// verify that default cpu was set to the max
	defaultValue := defaultLimit[versioned.ResourceCPU]
	if defaultValue.String() != "100m" {
		t.Errorf("Expected default cpu: %s, got: %s", "100m", defaultValue.String())
	}
	// verify that default request was set to the limit
	requestValue := defaultRequest[versioned.ResourceCPU]
	if requestValue.String() != "100m" {
		t.Errorf("Expected request cpu: %s, got: %s", "100m", requestValue.String())
	}
	// verify that if a min is provided, it will be the default if no limit is specified
	requestMinValue := defaultRequest[versioned.ResourceMemory]
	if requestMinValue.String() != "100Mi" {
		t.Errorf("Expected request memory: %s, got: %s", "100Mi", requestMinValue.String())
	}
}
func TestResourceQuotaGet(t *testing.T) {
	ns := api.NamespaceDefault
	resourceQuota := &api.ResourceQuota{
		ObjectMeta: api.ObjectMeta{
			Name:      "abc",
			Namespace: "foo",
		},
		Spec: api.ResourceQuotaSpec{
			Hard: api.ResourceList{
				api.ResourceCPU:                    resource.MustParse("100"),
				api.ResourceMemory:                 resource.MustParse("10000"),
				api.ResourcePods:                   resource.MustParse("10"),
				api.ResourceServices:               resource.MustParse("10"),
				api.ResourceReplicationControllers: resource.MustParse("10"),
				api.ResourceQuotas:                 resource.MustParse("10"),
			},
		},
	}
	c := &simple.Client{
		Request: simple.Request{
			Method: "GET",
			Path:   testapi.Default.ResourcePath(getResourceQuotasResoureName(), ns, "abc"),
			Query:  simple.BuildQueryValues(nil),
			Body:   nil,
		},
		Response: simple.Response{StatusCode: 200, Body: resourceQuota},
	}

	response, err := c.Setup(t).ResourceQuotas(ns).Get("abc")
	defer c.Close()
	c.Validate(t, response, err)
}
Exemple #11
0
func TestSemantic(t *testing.T) {
	table := []struct {
		a, b        interface{}
		shouldEqual bool
	}{
		{resource.MustParse("0"), resource.Quantity{}, true},
		{resource.Quantity{}, resource.MustParse("0"), true},
		{resource.Quantity{}, resource.MustParse("1m"), false},
		{
			resource.Quantity{Amount: inf.NewDec(5, 0), Format: resource.BinarySI},
			resource.Quantity{Amount: inf.NewDec(5, 0), Format: resource.DecimalSI},
			true,
		},
		{resource.MustParse("2m"), resource.MustParse("1m"), false},
	}

	for index, item := range table {
		if e, a := item.shouldEqual, Semantic.DeepEqual(item.a, item.b); e != a {
			t.Errorf("case[%d], expected %v, got %v.", index, e, a)
		}
	}
}
Exemple #12
0
func TestSetDefaultRequestsPod(t *testing.T) {
	// verify we default if limits are specified
	s := versioned.PodSpec{}
	s.Containers = []versioned.Container{
		{
			Resources: versioned.ResourceRequirements{
				Limits: versioned.ResourceList{
					versioned.ResourceCPU: resource.MustParse("100m"),
				},
			},
		},
	}
	pod := &versioned.Pod{
		Spec: s,
	}
	output := roundTrip(t, runtime.Object(pod))
	pod2 := output.(*versioned.Pod)
	defaultRequest := pod2.Spec.Containers[0].Resources.Requests
	requestValue := defaultRequest[versioned.ResourceCPU]
	if requestValue.String() != "100m" {
		t.Errorf("Expected request cpu: %s, got: %s", "100m", requestValue.String())
	}

	// verify we do nothing if no limits are specified
	s = versioned.PodSpec{}
	s.Containers = []versioned.Container{{}}
	pod = &versioned.Pod{
		Spec: s,
	}
	output = roundTrip(t, runtime.Object(pod))
	pod2 = output.(*versioned.Pod)
	defaultRequest = pod2.Spec.Containers[0].Resources.Requests
	requestValue = defaultRequest[versioned.ResourceCPU]
	if requestValue.String() != "0" {
		t.Errorf("Expected 0 request value, got: %s", requestValue.String())
	}
}
Exemple #13
0
func TestSetDefaultNodeStatusAllocatable(t *testing.T) {
	capacity := versioned.ResourceList{
		versioned.ResourceCPU:    resource.MustParse("1000m"),
		versioned.ResourceMemory: resource.MustParse("10G"),
	}
	allocatable := versioned.ResourceList{
		versioned.ResourceCPU:    resource.MustParse("500m"),
		versioned.ResourceMemory: resource.MustParse("5G"),
	}
	tests := []struct {
		capacity            versioned.ResourceList
		allocatable         versioned.ResourceList
		expectedAllocatable versioned.ResourceList
	}{{ // Everything set, no defaulting.
		capacity:            capacity,
		allocatable:         allocatable,
		expectedAllocatable: allocatable,
	}, { // Allocatable set, no defaulting.
		capacity:            nil,
		allocatable:         allocatable,
		expectedAllocatable: allocatable,
	}, { // Capacity set, allocatable defaults to capacity.
		capacity:            capacity,
		allocatable:         nil,
		expectedAllocatable: capacity,
	}, { // Nothing set, allocatable "defaults" to capacity.
		capacity:            nil,
		allocatable:         nil,
		expectedAllocatable: nil,
	}}

	copyResourceList := func(rl versioned.ResourceList) versioned.ResourceList {
		if rl == nil {
			return nil
		}
		copy := make(versioned.ResourceList, len(rl))
		for k, v := range rl {
			copy[k] = *v.Copy()
		}
		return copy
	}

	resourceListsEqual := func(a versioned.ResourceList, b versioned.ResourceList) bool {
		if len(a) != len(b) {
			return false
		}
		for k, v := range a {
			vb, found := b[k]
			if !found {
				return false
			}
			if v.Cmp(vb) != 0 {
				return false
			}
		}
		return true
	}

	for i, testcase := range tests {
		node := versioned.Node{
			Status: versioned.NodeStatus{
				Capacity:    copyResourceList(testcase.capacity),
				Allocatable: copyResourceList(testcase.allocatable),
			},
		}
		node2 := roundTrip(t, runtime.Object(&node)).(*versioned.Node)
		actual := node2.Status.Allocatable
		expected := testcase.expectedAllocatable
		if !resourceListsEqual(expected, actual) {
			t.Errorf("[%d] Expected NodeStatus.Allocatable: %+v; Got: %+v", i, expected, actual)
		}
	}
}
func TestResourceListConversion(t *testing.T) {
	bigMilliQuantity := resource.NewQuantity(resource.MaxMilliValue, resource.DecimalSI)
	bigMilliQuantity.Add(resource.MustParse("12345m"))

	tests := []struct {
		input    versioned.ResourceList
		expected api.ResourceList
	}{
		{ // No changes necessary.
			input: versioned.ResourceList{
				versioned.ResourceMemory:  resource.MustParse("30M"),
				versioned.ResourceCPU:     resource.MustParse("100m"),
				versioned.ResourceStorage: resource.MustParse("1G"),
			},
			expected: api.ResourceList{
				api.ResourceMemory:  resource.MustParse("30M"),
				api.ResourceCPU:     resource.MustParse("100m"),
				api.ResourceStorage: resource.MustParse("1G"),
			},
		},
		{ // Nano-scale values should be rounded up to milli-scale.
			input: versioned.ResourceList{
				versioned.ResourceCPU:    resource.MustParse("3.000023m"),
				versioned.ResourceMemory: resource.MustParse("500.000050m"),
			},
			expected: api.ResourceList{
				api.ResourceCPU:    resource.MustParse("4m"),
				api.ResourceMemory: resource.MustParse("501m"),
			},
		},
		{ // Large values should still be accurate.
			input: versioned.ResourceList{
				versioned.ResourceCPU:     *bigMilliQuantity.Copy(),
				versioned.ResourceStorage: *bigMilliQuantity.Copy(),
			},
			expected: api.ResourceList{
				api.ResourceCPU:     *bigMilliQuantity.Copy(),
				api.ResourceStorage: *bigMilliQuantity.Copy(),
			},
		},
	}

	output := api.ResourceList{}
	for i, test := range tests {
		err := api.Scheme.Convert(&test.input, &output)
		if err != nil {
			t.Fatalf("unexpected error for case %d: %v", i, err)
		}
		if !api.Semantic.DeepEqual(test.expected, output) {
			t.Errorf("unexpected conversion for case %d: Expected %+v; Got %+v", i, test.expected, output)
		}
	}
}