123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979 |
- /*
- Copyright 2018 The Kubernetes Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package nodeinfo
- import (
- "fmt"
- "reflect"
- "strings"
- "testing"
- "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/api/resource"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/types"
- utilfeature "k8s.io/apiserver/pkg/util/feature"
- featuregatetesting "k8s.io/component-base/featuregate/testing"
- "k8s.io/kubernetes/pkg/features"
- )
- func TestNewResource(t *testing.T) {
- tests := []struct {
- resourceList v1.ResourceList
- expected *Resource
- }{
- {
- resourceList: map[v1.ResourceName]resource.Quantity{},
- expected: &Resource{},
- },
- {
- resourceList: map[v1.ResourceName]resource.Quantity{
- v1.ResourceCPU: *resource.NewScaledQuantity(4, -3),
- v1.ResourceMemory: *resource.NewQuantity(2000, resource.BinarySI),
- v1.ResourcePods: *resource.NewQuantity(80, resource.BinarySI),
- v1.ResourceEphemeralStorage: *resource.NewQuantity(5000, resource.BinarySI),
- "scalar.test/" + "scalar1": *resource.NewQuantity(1, resource.DecimalSI),
- v1.ResourceHugePagesPrefix + "test": *resource.NewQuantity(2, resource.BinarySI),
- },
- expected: &Resource{
- MilliCPU: 4,
- Memory: 2000,
- EphemeralStorage: 5000,
- AllowedPodNumber: 80,
- ScalarResources: map[v1.ResourceName]int64{"scalar.test/scalar1": 1, "hugepages-test": 2},
- },
- },
- }
- for _, test := range tests {
- r := NewResource(test.resourceList)
- if !reflect.DeepEqual(test.expected, r) {
- t.Errorf("expected: %#v, got: %#v", test.expected, r)
- }
- }
- }
- func TestResourceList(t *testing.T) {
- tests := []struct {
- resource *Resource
- expected v1.ResourceList
- }{
- {
- resource: &Resource{},
- expected: map[v1.ResourceName]resource.Quantity{
- v1.ResourceCPU: *resource.NewScaledQuantity(0, -3),
- v1.ResourceMemory: *resource.NewQuantity(0, resource.BinarySI),
- v1.ResourcePods: *resource.NewQuantity(0, resource.BinarySI),
- v1.ResourceEphemeralStorage: *resource.NewQuantity(0, resource.BinarySI),
- },
- },
- {
- resource: &Resource{
- MilliCPU: 4,
- Memory: 2000,
- EphemeralStorage: 5000,
- AllowedPodNumber: 80,
- ScalarResources: map[v1.ResourceName]int64{
- "scalar.test/scalar1": 1,
- "hugepages-test": 2,
- "attachable-volumes-aws-ebs": 39,
- },
- },
- expected: map[v1.ResourceName]resource.Quantity{
- v1.ResourceCPU: *resource.NewScaledQuantity(4, -3),
- v1.ResourceMemory: *resource.NewQuantity(2000, resource.BinarySI),
- v1.ResourcePods: *resource.NewQuantity(80, resource.BinarySI),
- v1.ResourceEphemeralStorage: *resource.NewQuantity(5000, resource.BinarySI),
- "scalar.test/" + "scalar1": *resource.NewQuantity(1, resource.DecimalSI),
- "attachable-volumes-aws-ebs": *resource.NewQuantity(39, resource.DecimalSI),
- v1.ResourceHugePagesPrefix + "test": *resource.NewQuantity(2, resource.BinarySI),
- },
- },
- }
- for _, test := range tests {
- rl := test.resource.ResourceList()
- if !reflect.DeepEqual(test.expected, rl) {
- t.Errorf("expected: %#v, got: %#v", test.expected, rl)
- }
- }
- }
- func TestResourceClone(t *testing.T) {
- tests := []struct {
- resource *Resource
- expected *Resource
- }{
- {
- resource: &Resource{},
- expected: &Resource{},
- },
- {
- resource: &Resource{
- MilliCPU: 4,
- Memory: 2000,
- EphemeralStorage: 5000,
- AllowedPodNumber: 80,
- ScalarResources: map[v1.ResourceName]int64{"scalar.test/scalar1": 1, "hugepages-test": 2},
- },
- expected: &Resource{
- MilliCPU: 4,
- Memory: 2000,
- EphemeralStorage: 5000,
- AllowedPodNumber: 80,
- ScalarResources: map[v1.ResourceName]int64{"scalar.test/scalar1": 1, "hugepages-test": 2},
- },
- },
- }
- for _, test := range tests {
- r := test.resource.Clone()
- // Modify the field to check if the result is a clone of the origin one.
- test.resource.MilliCPU += 1000
- if !reflect.DeepEqual(test.expected, r) {
- t.Errorf("expected: %#v, got: %#v", test.expected, r)
- }
- }
- }
- func TestResourceAddScalar(t *testing.T) {
- tests := []struct {
- resource *Resource
- scalarName v1.ResourceName
- scalarQuantity int64
- expected *Resource
- }{
- {
- resource: &Resource{},
- scalarName: "scalar1",
- scalarQuantity: 100,
- expected: &Resource{
- ScalarResources: map[v1.ResourceName]int64{"scalar1": 100},
- },
- },
- {
- resource: &Resource{
- MilliCPU: 4,
- Memory: 2000,
- EphemeralStorage: 5000,
- AllowedPodNumber: 80,
- ScalarResources: map[v1.ResourceName]int64{"hugepages-test": 2},
- },
- scalarName: "scalar2",
- scalarQuantity: 200,
- expected: &Resource{
- MilliCPU: 4,
- Memory: 2000,
- EphemeralStorage: 5000,
- AllowedPodNumber: 80,
- ScalarResources: map[v1.ResourceName]int64{"hugepages-test": 2, "scalar2": 200},
- },
- },
- }
- for _, test := range tests {
- test.resource.AddScalar(test.scalarName, test.scalarQuantity)
- if !reflect.DeepEqual(test.expected, test.resource) {
- t.Errorf("expected: %#v, got: %#v", test.expected, test.resource)
- }
- }
- }
- func TestSetMaxResource(t *testing.T) {
- tests := []struct {
- resource *Resource
- resourceList v1.ResourceList
- expected *Resource
- }{
- {
- resource: &Resource{},
- resourceList: map[v1.ResourceName]resource.Quantity{
- v1.ResourceCPU: *resource.NewScaledQuantity(4, -3),
- v1.ResourceMemory: *resource.NewQuantity(2000, resource.BinarySI),
- v1.ResourceEphemeralStorage: *resource.NewQuantity(5000, resource.BinarySI),
- },
- expected: &Resource{
- MilliCPU: 4,
- Memory: 2000,
- EphemeralStorage: 5000,
- },
- },
- {
- resource: &Resource{
- MilliCPU: 4,
- Memory: 4000,
- EphemeralStorage: 5000,
- ScalarResources: map[v1.ResourceName]int64{"scalar.test/scalar1": 1, "hugepages-test": 2},
- },
- resourceList: map[v1.ResourceName]resource.Quantity{
- v1.ResourceCPU: *resource.NewScaledQuantity(4, -3),
- v1.ResourceMemory: *resource.NewQuantity(2000, resource.BinarySI),
- v1.ResourceEphemeralStorage: *resource.NewQuantity(7000, resource.BinarySI),
- "scalar.test/scalar1": *resource.NewQuantity(4, resource.DecimalSI),
- v1.ResourceHugePagesPrefix + "test": *resource.NewQuantity(5, resource.BinarySI),
- },
- expected: &Resource{
- MilliCPU: 4,
- Memory: 4000,
- EphemeralStorage: 7000,
- ScalarResources: map[v1.ResourceName]int64{"scalar.test/scalar1": 4, "hugepages-test": 5},
- },
- },
- }
- for _, test := range tests {
- test.resource.SetMaxResource(test.resourceList)
- if !reflect.DeepEqual(test.expected, test.resource) {
- t.Errorf("expected: %#v, got: %#v", test.expected, test.resource)
- }
- }
- }
- type testingMode interface {
- Fatalf(format string, args ...interface{})
- }
- func makeBasePod(t testingMode, nodeName, objName, cpu, mem, extended string, ports []v1.ContainerPort) *v1.Pod {
- req := v1.ResourceList{}
- if cpu != "" {
- req = v1.ResourceList{
- v1.ResourceCPU: resource.MustParse(cpu),
- v1.ResourceMemory: resource.MustParse(mem),
- }
- if extended != "" {
- parts := strings.Split(extended, ":")
- if len(parts) != 2 {
- t.Fatalf("Invalid extended resource string: \"%s\"", extended)
- }
- req[v1.ResourceName(parts[0])] = resource.MustParse(parts[1])
- }
- }
- return &v1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- UID: types.UID(objName),
- Namespace: "node_info_cache_test",
- Name: objName,
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{{
- Resources: v1.ResourceRequirements{
- Requests: req,
- },
- Ports: ports,
- }},
- NodeName: nodeName,
- },
- }
- }
- func TestNewNodeInfo(t *testing.T) {
- nodeName := "test-node"
- pods := []*v1.Pod{
- makeBasePod(t, nodeName, "test-1", "100m", "500", "", []v1.ContainerPort{{HostIP: "127.0.0.1", HostPort: 80, Protocol: "TCP"}}),
- makeBasePod(t, nodeName, "test-2", "200m", "1Ki", "", []v1.ContainerPort{{HostIP: "127.0.0.1", HostPort: 8080, Protocol: "TCP"}}),
- }
- expected := &NodeInfo{
- requestedResource: &Resource{
- MilliCPU: 300,
- Memory: 1524,
- EphemeralStorage: 0,
- AllowedPodNumber: 0,
- ScalarResources: map[v1.ResourceName]int64(nil),
- },
- nonzeroRequest: &Resource{
- MilliCPU: 300,
- Memory: 1524,
- EphemeralStorage: 0,
- AllowedPodNumber: 0,
- ScalarResources: map[v1.ResourceName]int64(nil),
- },
- TransientInfo: NewTransientSchedulerInfo(),
- allocatableResource: &Resource{},
- generation: 2,
- usedPorts: HostPortInfo{
- "127.0.0.1": map[ProtocolPort]struct{}{
- {Protocol: "TCP", Port: 80}: {},
- {Protocol: "TCP", Port: 8080}: {},
- },
- },
- imageStates: map[string]*ImageStateSummary{},
- pods: []*v1.Pod{
- {
- ObjectMeta: metav1.ObjectMeta{
- Namespace: "node_info_cache_test",
- Name: "test-1",
- UID: types.UID("test-1"),
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Resources: v1.ResourceRequirements{
- Requests: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("100m"),
- v1.ResourceMemory: resource.MustParse("500"),
- },
- },
- Ports: []v1.ContainerPort{
- {
- HostIP: "127.0.0.1",
- HostPort: 80,
- Protocol: "TCP",
- },
- },
- },
- },
- NodeName: nodeName,
- },
- },
- {
- ObjectMeta: metav1.ObjectMeta{
- Namespace: "node_info_cache_test",
- Name: "test-2",
- UID: types.UID("test-2"),
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Resources: v1.ResourceRequirements{
- Requests: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("200m"),
- v1.ResourceMemory: resource.MustParse("1Ki"),
- },
- },
- Ports: []v1.ContainerPort{
- {
- HostIP: "127.0.0.1",
- HostPort: 8080,
- Protocol: "TCP",
- },
- },
- },
- },
- NodeName: nodeName,
- },
- },
- },
- }
- gen := generation
- ni := NewNodeInfo(pods...)
- if ni.generation <= gen {
- t.Errorf("generation is not incremented. previous: %v, current: %v", gen, ni.generation)
- }
- expected.generation = ni.generation
- if !reflect.DeepEqual(expected, ni) {
- t.Errorf("expected: %#v, got: %#v", expected, ni)
- }
- }
- func TestNodeInfoClone(t *testing.T) {
- nodeName := "test-node"
- tests := []struct {
- nodeInfo *NodeInfo
- expected *NodeInfo
- }{
- {
- nodeInfo: &NodeInfo{
- requestedResource: &Resource{},
- nonzeroRequest: &Resource{},
- TransientInfo: NewTransientSchedulerInfo(),
- allocatableResource: &Resource{},
- generation: 2,
- usedPorts: HostPortInfo{
- "127.0.0.1": map[ProtocolPort]struct{}{
- {Protocol: "TCP", Port: 80}: {},
- {Protocol: "TCP", Port: 8080}: {},
- },
- },
- imageStates: map[string]*ImageStateSummary{},
- pods: []*v1.Pod{
- {
- ObjectMeta: metav1.ObjectMeta{
- Namespace: "node_info_cache_test",
- Name: "test-1",
- UID: types.UID("test-1"),
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Resources: v1.ResourceRequirements{
- Requests: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("100m"),
- v1.ResourceMemory: resource.MustParse("500"),
- },
- },
- Ports: []v1.ContainerPort{
- {
- HostIP: "127.0.0.1",
- HostPort: 80,
- Protocol: "TCP",
- },
- },
- },
- },
- NodeName: nodeName,
- },
- },
- {
- ObjectMeta: metav1.ObjectMeta{
- Namespace: "node_info_cache_test",
- Name: "test-2",
- UID: types.UID("test-2"),
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Resources: v1.ResourceRequirements{
- Requests: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("200m"),
- v1.ResourceMemory: resource.MustParse("1Ki"),
- },
- },
- Ports: []v1.ContainerPort{
- {
- HostIP: "127.0.0.1",
- HostPort: 8080,
- Protocol: "TCP",
- },
- },
- },
- },
- NodeName: nodeName,
- },
- },
- },
- },
- expected: &NodeInfo{
- requestedResource: &Resource{},
- nonzeroRequest: &Resource{},
- TransientInfo: NewTransientSchedulerInfo(),
- allocatableResource: &Resource{},
- generation: 2,
- usedPorts: HostPortInfo{
- "127.0.0.1": map[ProtocolPort]struct{}{
- {Protocol: "TCP", Port: 80}: {},
- {Protocol: "TCP", Port: 8080}: {},
- },
- },
- imageStates: map[string]*ImageStateSummary{},
- pods: []*v1.Pod{
- {
- ObjectMeta: metav1.ObjectMeta{
- Namespace: "node_info_cache_test",
- Name: "test-1",
- UID: types.UID("test-1"),
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Resources: v1.ResourceRequirements{
- Requests: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("100m"),
- v1.ResourceMemory: resource.MustParse("500"),
- },
- },
- Ports: []v1.ContainerPort{
- {
- HostIP: "127.0.0.1",
- HostPort: 80,
- Protocol: "TCP",
- },
- },
- },
- },
- NodeName: nodeName,
- },
- },
- {
- ObjectMeta: metav1.ObjectMeta{
- Namespace: "node_info_cache_test",
- Name: "test-2",
- UID: types.UID("test-2"),
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Resources: v1.ResourceRequirements{
- Requests: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("200m"),
- v1.ResourceMemory: resource.MustParse("1Ki"),
- },
- },
- Ports: []v1.ContainerPort{
- {
- HostIP: "127.0.0.1",
- HostPort: 8080,
- Protocol: "TCP",
- },
- },
- },
- },
- NodeName: nodeName,
- },
- },
- },
- },
- },
- }
- for _, test := range tests {
- ni := test.nodeInfo.Clone()
- // Modify the field to check if the result is a clone of the origin one.
- test.nodeInfo.generation += 10
- test.nodeInfo.usedPorts.Remove("127.0.0.1", "TCP", 80)
- if !reflect.DeepEqual(test.expected, ni) {
- t.Errorf("expected: %#v, got: %#v", test.expected, ni)
- }
- }
- }
- func TestNodeInfoAddPod(t *testing.T) {
- defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodOverhead, true)()
- nodeName := "test-node"
- pods := []*v1.Pod{
- {
- ObjectMeta: metav1.ObjectMeta{
- Namespace: "node_info_cache_test",
- Name: "test-1",
- UID: types.UID("test-1"),
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Resources: v1.ResourceRequirements{
- Requests: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("100m"),
- v1.ResourceMemory: resource.MustParse("500"),
- },
- },
- Ports: []v1.ContainerPort{
- {
- HostIP: "127.0.0.1",
- HostPort: 80,
- Protocol: "TCP",
- },
- },
- },
- },
- NodeName: nodeName,
- Overhead: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("500m"),
- },
- },
- },
- {
- ObjectMeta: metav1.ObjectMeta{
- Namespace: "node_info_cache_test",
- Name: "test-2",
- UID: types.UID("test-2"),
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Resources: v1.ResourceRequirements{
- Requests: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("200m"),
- },
- },
- Ports: []v1.ContainerPort{
- {
- HostIP: "127.0.0.1",
- HostPort: 8080,
- Protocol: "TCP",
- },
- },
- },
- },
- NodeName: nodeName,
- Overhead: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("500m"),
- v1.ResourceMemory: resource.MustParse("500"),
- },
- },
- },
- }
- expected := &NodeInfo{
- node: &v1.Node{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test-node",
- },
- },
- requestedResource: &Resource{
- MilliCPU: 1300,
- Memory: 1000,
- EphemeralStorage: 0,
- AllowedPodNumber: 0,
- ScalarResources: map[v1.ResourceName]int64(nil),
- },
- nonzeroRequest: &Resource{
- MilliCPU: 1300,
- Memory: 209716200, //200MB + 1000 specified in requests/overhead
- EphemeralStorage: 0,
- AllowedPodNumber: 0,
- ScalarResources: map[v1.ResourceName]int64(nil),
- },
- TransientInfo: NewTransientSchedulerInfo(),
- allocatableResource: &Resource{},
- generation: 2,
- usedPorts: HostPortInfo{
- "127.0.0.1": map[ProtocolPort]struct{}{
- {Protocol: "TCP", Port: 80}: {},
- {Protocol: "TCP", Port: 8080}: {},
- },
- },
- imageStates: map[string]*ImageStateSummary{},
- pods: []*v1.Pod{
- {
- ObjectMeta: metav1.ObjectMeta{
- Namespace: "node_info_cache_test",
- Name: "test-1",
- UID: types.UID("test-1"),
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Resources: v1.ResourceRequirements{
- Requests: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("100m"),
- v1.ResourceMemory: resource.MustParse("500"),
- },
- },
- Ports: []v1.ContainerPort{
- {
- HostIP: "127.0.0.1",
- HostPort: 80,
- Protocol: "TCP",
- },
- },
- },
- },
- NodeName: nodeName,
- Overhead: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("500m"),
- },
- },
- },
- {
- ObjectMeta: metav1.ObjectMeta{
- Namespace: "node_info_cache_test",
- Name: "test-2",
- UID: types.UID("test-2"),
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Resources: v1.ResourceRequirements{
- Requests: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("200m"),
- },
- },
- Ports: []v1.ContainerPort{
- {
- HostIP: "127.0.0.1",
- HostPort: 8080,
- Protocol: "TCP",
- },
- },
- },
- },
- NodeName: nodeName,
- Overhead: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("500m"),
- v1.ResourceMemory: resource.MustParse("500"),
- },
- },
- },
- },
- }
- ni := fakeNodeInfo()
- gen := ni.generation
- for _, pod := range pods {
- ni.AddPod(pod)
- if ni.generation <= gen {
- t.Errorf("generation is not incremented. Prev: %v, current: %v", gen, ni.generation)
- }
- gen = ni.generation
- }
- expected.generation = ni.generation
- if !reflect.DeepEqual(expected, ni) {
- t.Errorf("expected: %#v, got: %#v", expected, ni)
- }
- }
- func TestNodeInfoRemovePod(t *testing.T) {
- defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodOverhead, true)()
- nodeName := "test-node"
- pods := []*v1.Pod{
- makeBasePod(t, nodeName, "test-1", "100m", "500", "", []v1.ContainerPort{{HostIP: "127.0.0.1", HostPort: 80, Protocol: "TCP"}}),
- makeBasePod(t, nodeName, "test-2", "200m", "1Ki", "", []v1.ContainerPort{{HostIP: "127.0.0.1", HostPort: 8080, Protocol: "TCP"}}),
- }
- // add pod Overhead
- for _, pod := range pods {
- pod.Spec.Overhead = v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("500m"),
- v1.ResourceMemory: resource.MustParse("500"),
- }
- }
- tests := []struct {
- pod *v1.Pod
- errExpected bool
- expectedNodeInfo *NodeInfo
- }{
- {
- pod: makeBasePod(t, nodeName, "non-exist", "0", "0", "", []v1.ContainerPort{{}}),
- errExpected: true,
- expectedNodeInfo: &NodeInfo{
- node: &v1.Node{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test-node",
- },
- },
- requestedResource: &Resource{
- MilliCPU: 1300,
- Memory: 2524,
- EphemeralStorage: 0,
- AllowedPodNumber: 0,
- ScalarResources: map[v1.ResourceName]int64(nil),
- },
- nonzeroRequest: &Resource{
- MilliCPU: 1300,
- Memory: 2524,
- EphemeralStorage: 0,
- AllowedPodNumber: 0,
- ScalarResources: map[v1.ResourceName]int64(nil),
- },
- TransientInfo: NewTransientSchedulerInfo(),
- allocatableResource: &Resource{},
- generation: 2,
- usedPorts: HostPortInfo{
- "127.0.0.1": map[ProtocolPort]struct{}{
- {Protocol: "TCP", Port: 80}: {},
- {Protocol: "TCP", Port: 8080}: {},
- },
- },
- imageStates: map[string]*ImageStateSummary{},
- pods: []*v1.Pod{
- {
- ObjectMeta: metav1.ObjectMeta{
- Namespace: "node_info_cache_test",
- Name: "test-1",
- UID: types.UID("test-1"),
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Resources: v1.ResourceRequirements{
- Requests: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("100m"),
- v1.ResourceMemory: resource.MustParse("500"),
- },
- },
- Ports: []v1.ContainerPort{
- {
- HostIP: "127.0.0.1",
- HostPort: 80,
- Protocol: "TCP",
- },
- },
- },
- },
- NodeName: nodeName,
- Overhead: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("500m"),
- v1.ResourceMemory: resource.MustParse("500"),
- },
- },
- },
- {
- ObjectMeta: metav1.ObjectMeta{
- Namespace: "node_info_cache_test",
- Name: "test-2",
- UID: types.UID("test-2"),
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Resources: v1.ResourceRequirements{
- Requests: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("200m"),
- v1.ResourceMemory: resource.MustParse("1Ki"),
- },
- },
- Ports: []v1.ContainerPort{
- {
- HostIP: "127.0.0.1",
- HostPort: 8080,
- Protocol: "TCP",
- },
- },
- },
- },
- NodeName: nodeName,
- Overhead: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("500m"),
- v1.ResourceMemory: resource.MustParse("500"),
- },
- },
- },
- },
- },
- },
- {
- pod: &v1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- Namespace: "node_info_cache_test",
- Name: "test-1",
- UID: types.UID("test-1"),
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Resources: v1.ResourceRequirements{
- Requests: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("100m"),
- v1.ResourceMemory: resource.MustParse("500"),
- },
- },
- Ports: []v1.ContainerPort{
- {
- HostIP: "127.0.0.1",
- HostPort: 80,
- Protocol: "TCP",
- },
- },
- },
- },
- NodeName: nodeName,
- Overhead: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("500m"),
- v1.ResourceMemory: resource.MustParse("500"),
- },
- },
- },
- errExpected: false,
- expectedNodeInfo: &NodeInfo{
- node: &v1.Node{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test-node",
- },
- },
- requestedResource: &Resource{
- MilliCPU: 700,
- Memory: 1524,
- EphemeralStorage: 0,
- AllowedPodNumber: 0,
- ScalarResources: map[v1.ResourceName]int64(nil),
- },
- nonzeroRequest: &Resource{
- MilliCPU: 700,
- Memory: 1524,
- EphemeralStorage: 0,
- AllowedPodNumber: 0,
- ScalarResources: map[v1.ResourceName]int64(nil),
- },
- TransientInfo: NewTransientSchedulerInfo(),
- allocatableResource: &Resource{},
- generation: 3,
- usedPorts: HostPortInfo{
- "127.0.0.1": map[ProtocolPort]struct{}{
- {Protocol: "TCP", Port: 8080}: {},
- },
- },
- imageStates: map[string]*ImageStateSummary{},
- pods: []*v1.Pod{
- {
- ObjectMeta: metav1.ObjectMeta{
- Namespace: "node_info_cache_test",
- Name: "test-2",
- UID: types.UID("test-2"),
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Resources: v1.ResourceRequirements{
- Requests: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("200m"),
- v1.ResourceMemory: resource.MustParse("1Ki"),
- },
- },
- Ports: []v1.ContainerPort{
- {
- HostIP: "127.0.0.1",
- HostPort: 8080,
- Protocol: "TCP",
- },
- },
- },
- },
- NodeName: nodeName,
- Overhead: v1.ResourceList{
- v1.ResourceCPU: resource.MustParse("500m"),
- v1.ResourceMemory: resource.MustParse("500"),
- },
- },
- },
- },
- },
- },
- }
- for _, test := range tests {
- ni := fakeNodeInfo(pods...)
- gen := ni.generation
- err := ni.RemovePod(test.pod)
- if err != nil {
- if test.errExpected {
- expectedErrorMsg := fmt.Errorf("no corresponding pod %s in pods of node %s", test.pod.Name, ni.Node().Name)
- if expectedErrorMsg == err {
- t.Errorf("expected error: %v, got: %v", expectedErrorMsg, err)
- }
- } else {
- t.Errorf("expected no error, got: %v", err)
- }
- } else {
- if ni.generation <= gen {
- t.Errorf("generation is not incremented. Prev: %v, current: %v", gen, ni.generation)
- }
- }
- test.expectedNodeInfo.generation = ni.generation
- if !reflect.DeepEqual(test.expectedNodeInfo, ni) {
- t.Errorf("expected: %#v, got: %#v", test.expectedNodeInfo, ni)
- }
- }
- }
- func fakeNodeInfo(pods ...*v1.Pod) *NodeInfo {
- ni := NewNodeInfo(pods...)
- ni.SetNode(&v1.Node{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test-node",
- },
- })
- return ni
- }
|