mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 12:15:52 +00:00
memory manager: provide unittests for init containers re-use
- provide tests for static policy allocation, when init containers requested memory bigger than the memory requested by app containers - provide tests for static policy allocation, when init containers requested memory smaller than the memory requested by app containers - provide tests to verify that init containers removed from the state file once the app container started Signed-off-by: Artyom Lukianov <alukiano@redhat.com>
This commit is contained in:
parent
960da7895c
commit
bb6d5b1f95
@ -24,15 +24,17 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
cadvisorapi "github.com/google/cadvisor/info/v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
||||
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
|
||||
"k8s.io/kubernetes/pkg/kubelet/cm/containermap"
|
||||
"k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state"
|
||||
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager"
|
||||
@ -149,6 +151,18 @@ func getPod(podUID string, containerName string, requirements *v1.ResourceRequir
|
||||
}
|
||||
}
|
||||
|
||||
func getPodWithInitContainers(podUID string, containers []v1.Container, initContainers []v1.Container) *v1.Pod {
|
||||
return &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
UID: types.UID(podUID),
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
InitContainers: initContainers,
|
||||
Containers: containers,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateReservedMemory(t *testing.T) {
|
||||
machineInfo := &cadvisorapi.MachineInfo{
|
||||
Topology: []cadvisorapi.Node{
|
||||
@ -2146,7 +2160,211 @@ func TestGetTopologyHints(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllocateAndAddPodWithInitContainers(t *testing.T) {
|
||||
testCases := []testMemoryManager{
|
||||
{
|
||||
description: "should remove init containers from the state file, once app container started",
|
||||
policyName: policyTypeStatic,
|
||||
machineInfo: returnMachineInfo(),
|
||||
assignments: state.ContainerMemoryAssignments{},
|
||||
expectedAssignments: state.ContainerMemoryAssignments{
|
||||
"pod1": map[string][]state.Block{
|
||||
"container1": {
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: v1.ResourceMemory,
|
||||
Size: 4 * gb,
|
||||
},
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: hugepages1Gi,
|
||||
Size: 4 * gb,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
machineState: state.NUMANodeMap{
|
||||
0: &state.NUMANodeState{
|
||||
MemoryMap: map[v1.ResourceName]*state.MemoryTable{
|
||||
v1.ResourceMemory: {
|
||||
Allocatable: 9728 * mb,
|
||||
Free: 9728 * mb,
|
||||
Reserved: 0,
|
||||
SystemReserved: 512 * mb,
|
||||
TotalMemSize: 10 * gb,
|
||||
},
|
||||
hugepages1Gi: {
|
||||
Allocatable: 5 * gb,
|
||||
Free: 5 * gb,
|
||||
Reserved: 0,
|
||||
SystemReserved: 0,
|
||||
TotalMemSize: 5 * gb,
|
||||
},
|
||||
},
|
||||
Cells: []int{0},
|
||||
},
|
||||
1: &state.NUMANodeState{
|
||||
MemoryMap: map[v1.ResourceName]*state.MemoryTable{
|
||||
v1.ResourceMemory: {
|
||||
Allocatable: 9728 * mb,
|
||||
Free: 9728 * mb,
|
||||
Reserved: 0,
|
||||
SystemReserved: 512 * mb,
|
||||
TotalMemSize: 10 * gb,
|
||||
},
|
||||
hugepages1Gi: {
|
||||
Allocatable: 5 * gb,
|
||||
Free: 5 * gb,
|
||||
Reserved: 0,
|
||||
SystemReserved: 0,
|
||||
TotalMemSize: 5 * gb,
|
||||
},
|
||||
},
|
||||
Cells: []int{1},
|
||||
},
|
||||
},
|
||||
expectedMachineState: state.NUMANodeMap{
|
||||
0: &state.NUMANodeState{
|
||||
MemoryMap: map[v1.ResourceName]*state.MemoryTable{
|
||||
v1.ResourceMemory: {
|
||||
Allocatable: 9728 * mb,
|
||||
Free: 5632 * mb,
|
||||
Reserved: 4 * gb,
|
||||
SystemReserved: 512 * mb,
|
||||
TotalMemSize: 10 * gb,
|
||||
},
|
||||
hugepages1Gi: {
|
||||
Allocatable: 5 * gb,
|
||||
Free: gb,
|
||||
Reserved: 4 * gb,
|
||||
SystemReserved: 0,
|
||||
TotalMemSize: 5 * gb,
|
||||
},
|
||||
},
|
||||
Cells: []int{0},
|
||||
NumberOfAssignments: 2,
|
||||
},
|
||||
1: &state.NUMANodeState{
|
||||
MemoryMap: map[v1.ResourceName]*state.MemoryTable{
|
||||
v1.ResourceMemory: {
|
||||
Allocatable: 9728 * mb,
|
||||
Free: 9728 * mb,
|
||||
Reserved: 0,
|
||||
SystemReserved: 512 * mb,
|
||||
TotalMemSize: 10 * gb,
|
||||
},
|
||||
hugepages1Gi: {
|
||||
Allocatable: 5 * gb,
|
||||
Free: 5 * gb,
|
||||
Reserved: 0,
|
||||
SystemReserved: 0,
|
||||
TotalMemSize: 5 * gb,
|
||||
},
|
||||
},
|
||||
Cells: []int{1},
|
||||
},
|
||||
},
|
||||
reserved: systemReservedMemory{
|
||||
0: map[v1.ResourceName]uint64{
|
||||
v1.ResourceMemory: 512 * mb,
|
||||
},
|
||||
},
|
||||
podAllocate: getPodWithInitContainers(
|
||||
"pod1",
|
||||
[]v1.Container{
|
||||
{
|
||||
Name: "container1",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("4Gi"),
|
||||
hugepages1Gi: resource.MustParse("4Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("4Gi"),
|
||||
hugepages1Gi: resource.MustParse("4Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
[]v1.Container{
|
||||
{
|
||||
Name: "initContainer1",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("7Gi"),
|
||||
hugepages1Gi: resource.MustParse("5Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("7Gi"),
|
||||
hugepages1Gi: resource.MustParse("5Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.description, func(t *testing.T) {
|
||||
klog.InfoS("TestAllocateAndAddPodWithInitContainers", "test name", testCase.description)
|
||||
mgr := &manager{
|
||||
policy: returnPolicyByName(testCase),
|
||||
state: state.NewMemoryState(),
|
||||
containerMap: containermap.NewContainerMap(),
|
||||
containerRuntime: mockRuntimeService{
|
||||
err: nil,
|
||||
},
|
||||
activePods: func() []*v1.Pod { return []*v1.Pod{testCase.podAllocate} },
|
||||
podStatusProvider: mockPodStatusProvider{},
|
||||
}
|
||||
mgr.sourcesReady = &sourcesReadyStub{}
|
||||
mgr.state.SetMachineState(testCase.machineState.Clone())
|
||||
mgr.state.SetMemoryAssignments(testCase.assignments.Clone())
|
||||
|
||||
// Allocates memory for init containers
|
||||
for i := range testCase.podAllocate.Spec.InitContainers {
|
||||
err := mgr.Allocate(testCase.podAllocate, &testCase.podAllocate.Spec.InitContainers[i])
|
||||
if !reflect.DeepEqual(err, testCase.expectedError) {
|
||||
t.Fatalf("The actual error %v is different from the expected one %v", err, testCase.expectedError)
|
||||
}
|
||||
}
|
||||
|
||||
// Allocates memory for apps containers
|
||||
for i := range testCase.podAllocate.Spec.Containers {
|
||||
err := mgr.Allocate(testCase.podAllocate, &testCase.podAllocate.Spec.Containers[i])
|
||||
if !reflect.DeepEqual(err, testCase.expectedError) {
|
||||
t.Fatalf("The actual error %v is different from the expected one %v", err, testCase.expectedError)
|
||||
}
|
||||
}
|
||||
|
||||
// Calls AddContainer for init containers
|
||||
for i, initContainer := range testCase.podAllocate.Spec.InitContainers {
|
||||
mgr.AddContainer(testCase.podAllocate, &testCase.podAllocate.Spec.InitContainers[i], initContainer.Name)
|
||||
}
|
||||
|
||||
// Calls AddContainer for apps containers
|
||||
for i, appContainer := range testCase.podAllocate.Spec.Containers {
|
||||
mgr.AddContainer(testCase.podAllocate, &testCase.podAllocate.Spec.Containers[i], appContainer.Name)
|
||||
}
|
||||
|
||||
assignments := mgr.state.GetMemoryAssignments()
|
||||
if !areContainerMemoryAssignmentsEqual(t, assignments, testCase.expectedAssignments) {
|
||||
t.Fatalf("Actual assignments %v are different from the expected %v", assignments, testCase.expectedAssignments)
|
||||
}
|
||||
|
||||
machineState := mgr.state.GetMachineState()
|
||||
if !areMachineStatesEqual(machineState, testCase.expectedMachineState) {
|
||||
t.Fatalf("The actual machine state %v is different from the expected %v", machineState, testCase.expectedMachineState)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func returnMachineInfo() cadvisorapi.MachineInfo {
|
||||
|
@ -21,6 +21,8 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
cadvisorapi "github.com/google/cadvisor/info/v1"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
@ -1788,6 +1790,561 @@ func TestStaticPolicyAllocate(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestStaticPolicyAllocateWithInitContainers(t *testing.T) {
|
||||
testCases := []testStaticPolicy{
|
||||
{
|
||||
description: "should re-use init containers memory, init containers requests 1Gi and 2Gi, apps containers 3Gi and 4Gi",
|
||||
assignments: state.ContainerMemoryAssignments{},
|
||||
expectedAssignments: state.ContainerMemoryAssignments{
|
||||
"pod1": map[string][]state.Block{
|
||||
"initContainer1": {
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: v1.ResourceMemory,
|
||||
Size: 0,
|
||||
},
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: hugepages1Gi,
|
||||
Size: 0,
|
||||
},
|
||||
},
|
||||
"initContainer2": {
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: v1.ResourceMemory,
|
||||
Size: 0,
|
||||
},
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: hugepages1Gi,
|
||||
Size: 0,
|
||||
},
|
||||
},
|
||||
"container1": {
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: v1.ResourceMemory,
|
||||
Size: 3 * gb,
|
||||
},
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: hugepages1Gi,
|
||||
Size: 3 * gb,
|
||||
},
|
||||
},
|
||||
"container2": {
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: v1.ResourceMemory,
|
||||
Size: 4 * gb,
|
||||
},
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: hugepages1Gi,
|
||||
Size: 4 * gb,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
machineState: state.NUMANodeMap{
|
||||
0: &state.NUMANodeState{
|
||||
MemoryMap: map[v1.ResourceName]*state.MemoryTable{
|
||||
v1.ResourceMemory: {
|
||||
Allocatable: 7680 * mb,
|
||||
Free: 7680 * mb,
|
||||
Reserved: 0,
|
||||
SystemReserved: 512 * mb,
|
||||
TotalMemSize: 8 * gb,
|
||||
},
|
||||
hugepages1Gi: {
|
||||
Allocatable: 8 * gb,
|
||||
Free: 8 * gb,
|
||||
Reserved: 0,
|
||||
SystemReserved: 0,
|
||||
TotalMemSize: 8 * gb,
|
||||
},
|
||||
},
|
||||
Cells: []int{0},
|
||||
},
|
||||
},
|
||||
expectedMachineState: state.NUMANodeMap{
|
||||
0: &state.NUMANodeState{
|
||||
MemoryMap: map[v1.ResourceName]*state.MemoryTable{
|
||||
v1.ResourceMemory: {
|
||||
Allocatable: 7680 * mb,
|
||||
Free: 512 * mb,
|
||||
Reserved: 7 * gb,
|
||||
SystemReserved: 512 * mb,
|
||||
TotalMemSize: 8 * gb,
|
||||
},
|
||||
hugepages1Gi: {
|
||||
Allocatable: 8 * gb,
|
||||
Free: 1 * gb,
|
||||
Reserved: 7 * gb,
|
||||
SystemReserved: 0,
|
||||
TotalMemSize: 8 * gb,
|
||||
},
|
||||
},
|
||||
Cells: []int{0},
|
||||
NumberOfAssignments: 8,
|
||||
},
|
||||
},
|
||||
systemReserved: systemReservedMemory{
|
||||
0: map[v1.ResourceName]uint64{
|
||||
v1.ResourceMemory: 512 * mb,
|
||||
},
|
||||
},
|
||||
pod: getPodWithInitContainers(
|
||||
"pod1",
|
||||
[]v1.Container{
|
||||
{
|
||||
Name: "container1",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("3Gi"),
|
||||
hugepages1Gi: resource.MustParse("3Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("3Gi"),
|
||||
hugepages1Gi: resource.MustParse("3Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "container2",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("4Gi"),
|
||||
hugepages1Gi: resource.MustParse("4Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("4Gi"),
|
||||
hugepages1Gi: resource.MustParse("4Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
[]v1.Container{
|
||||
{
|
||||
Name: "initContainer1",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("1Gi"),
|
||||
hugepages1Gi: resource.MustParse("1Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("1Gi"),
|
||||
hugepages1Gi: resource.MustParse("1Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "initContainer2",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("2Gi"),
|
||||
hugepages1Gi: resource.MustParse("2Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("2Gi"),
|
||||
hugepages1Gi: resource.MustParse("2Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
topologyHint: &topologymanager.TopologyHint{},
|
||||
},
|
||||
{
|
||||
description: "should re-use init containers memory, init containers requests 4Gi and 3Gi, apps containers 2Gi and 1Gi",
|
||||
assignments: state.ContainerMemoryAssignments{},
|
||||
expectedAssignments: state.ContainerMemoryAssignments{
|
||||
"pod1": map[string][]state.Block{
|
||||
"initContainer1": {
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: v1.ResourceMemory,
|
||||
Size: 0,
|
||||
},
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: hugepages1Gi,
|
||||
Size: 0,
|
||||
},
|
||||
},
|
||||
"initContainer2": {
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: v1.ResourceMemory,
|
||||
Size: gb,
|
||||
},
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: hugepages1Gi,
|
||||
Size: gb,
|
||||
},
|
||||
},
|
||||
"container1": {
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: v1.ResourceMemory,
|
||||
Size: 2 * gb,
|
||||
},
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: hugepages1Gi,
|
||||
Size: 2 * gb,
|
||||
},
|
||||
},
|
||||
"container2": {
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: v1.ResourceMemory,
|
||||
Size: gb,
|
||||
},
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: hugepages1Gi,
|
||||
Size: gb,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
machineState: state.NUMANodeMap{
|
||||
0: &state.NUMANodeState{
|
||||
MemoryMap: map[v1.ResourceName]*state.MemoryTable{
|
||||
v1.ResourceMemory: {
|
||||
Allocatable: 7680 * mb,
|
||||
Free: 7680 * mb,
|
||||
Reserved: 0,
|
||||
SystemReserved: 512 * mb,
|
||||
TotalMemSize: 8 * gb,
|
||||
},
|
||||
hugepages1Gi: {
|
||||
Allocatable: 8 * gb,
|
||||
Free: 8 * gb,
|
||||
Reserved: 0,
|
||||
SystemReserved: 0,
|
||||
TotalMemSize: 8 * gb,
|
||||
},
|
||||
},
|
||||
Cells: []int{0},
|
||||
},
|
||||
},
|
||||
expectedMachineState: state.NUMANodeMap{
|
||||
0: &state.NUMANodeState{
|
||||
MemoryMap: map[v1.ResourceName]*state.MemoryTable{
|
||||
v1.ResourceMemory: {
|
||||
Allocatable: 7680 * mb,
|
||||
Free: 3584 * mb,
|
||||
Reserved: 4 * gb,
|
||||
SystemReserved: 512 * mb,
|
||||
TotalMemSize: 8 * gb,
|
||||
},
|
||||
hugepages1Gi: {
|
||||
Allocatable: 8 * gb,
|
||||
Free: 4 * gb,
|
||||
Reserved: 4 * gb,
|
||||
SystemReserved: 0,
|
||||
TotalMemSize: 8 * gb,
|
||||
},
|
||||
},
|
||||
Cells: []int{0},
|
||||
NumberOfAssignments: 8,
|
||||
},
|
||||
},
|
||||
systemReserved: systemReservedMemory{
|
||||
0: map[v1.ResourceName]uint64{
|
||||
v1.ResourceMemory: 512 * mb,
|
||||
},
|
||||
},
|
||||
pod: getPodWithInitContainers(
|
||||
"pod1",
|
||||
[]v1.Container{
|
||||
{
|
||||
Name: "container1",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("2Gi"),
|
||||
hugepages1Gi: resource.MustParse("2Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("2Gi"),
|
||||
hugepages1Gi: resource.MustParse("2Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "container2",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("1Gi"),
|
||||
hugepages1Gi: resource.MustParse("1Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("1Gi"),
|
||||
hugepages1Gi: resource.MustParse("1Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
[]v1.Container{
|
||||
{
|
||||
Name: "initContainer1",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("4Gi"),
|
||||
hugepages1Gi: resource.MustParse("4Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("4Gi"),
|
||||
hugepages1Gi: resource.MustParse("4Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "initContainer2",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("3Gi"),
|
||||
hugepages1Gi: resource.MustParse("3Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("3Gi"),
|
||||
hugepages1Gi: resource.MustParse("3Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
topologyHint: &topologymanager.TopologyHint{},
|
||||
},
|
||||
{
|
||||
description: "should re-use init containers memory, init containers requests 7Gi and 4Gi, apps containers 4Gi and 3Gi",
|
||||
assignments: state.ContainerMemoryAssignments{},
|
||||
expectedAssignments: state.ContainerMemoryAssignments{
|
||||
"pod1": map[string][]state.Block{
|
||||
"initContainer1": {
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: v1.ResourceMemory,
|
||||
Size: 0,
|
||||
},
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: hugepages1Gi,
|
||||
Size: 0,
|
||||
},
|
||||
},
|
||||
"initContainer2": {
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: v1.ResourceMemory,
|
||||
Size: 0,
|
||||
},
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: hugepages1Gi,
|
||||
Size: 0,
|
||||
},
|
||||
},
|
||||
"container1": {
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: v1.ResourceMemory,
|
||||
Size: 4 * gb,
|
||||
},
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: hugepages1Gi,
|
||||
Size: 4 * gb,
|
||||
},
|
||||
},
|
||||
"container2": {
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: v1.ResourceMemory,
|
||||
Size: 3 * gb,
|
||||
},
|
||||
{
|
||||
NUMAAffinity: []int{0},
|
||||
Type: hugepages1Gi,
|
||||
Size: 3 * gb,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
machineState: state.NUMANodeMap{
|
||||
0: &state.NUMANodeState{
|
||||
MemoryMap: map[v1.ResourceName]*state.MemoryTable{
|
||||
v1.ResourceMemory: {
|
||||
Allocatable: 7680 * mb,
|
||||
Free: 7680 * mb,
|
||||
Reserved: 0,
|
||||
SystemReserved: 512 * mb,
|
||||
TotalMemSize: 8 * gb,
|
||||
},
|
||||
hugepages1Gi: {
|
||||
Allocatable: 8 * gb,
|
||||
Free: 8 * gb,
|
||||
Reserved: 0,
|
||||
SystemReserved: 0,
|
||||
TotalMemSize: 8 * gb,
|
||||
},
|
||||
},
|
||||
Cells: []int{0},
|
||||
},
|
||||
},
|
||||
expectedMachineState: state.NUMANodeMap{
|
||||
0: &state.NUMANodeState{
|
||||
MemoryMap: map[v1.ResourceName]*state.MemoryTable{
|
||||
v1.ResourceMemory: {
|
||||
Allocatable: 7680 * mb,
|
||||
Free: 512 * mb,
|
||||
Reserved: 7 * gb,
|
||||
SystemReserved: 512 * mb,
|
||||
TotalMemSize: 8 * gb,
|
||||
},
|
||||
hugepages1Gi: {
|
||||
Allocatable: 8 * gb,
|
||||
Free: 1 * gb,
|
||||
Reserved: 7 * gb,
|
||||
SystemReserved: 0,
|
||||
TotalMemSize: 8 * gb,
|
||||
},
|
||||
},
|
||||
Cells: []int{0},
|
||||
NumberOfAssignments: 8,
|
||||
},
|
||||
},
|
||||
systemReserved: systemReservedMemory{
|
||||
0: map[v1.ResourceName]uint64{
|
||||
v1.ResourceMemory: 512 * mb,
|
||||
},
|
||||
},
|
||||
pod: getPodWithInitContainers(
|
||||
"pod1",
|
||||
[]v1.Container{
|
||||
{
|
||||
Name: "container1",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("4Gi"),
|
||||
hugepages1Gi: resource.MustParse("4Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("4Gi"),
|
||||
hugepages1Gi: resource.MustParse("4Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "container2",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("3Gi"),
|
||||
hugepages1Gi: resource.MustParse("3Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("3Gi"),
|
||||
hugepages1Gi: resource.MustParse("3Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
[]v1.Container{
|
||||
{
|
||||
Name: "initContainer1",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("7Gi"),
|
||||
hugepages1Gi: resource.MustParse("7Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("7Gi"),
|
||||
hugepages1Gi: resource.MustParse("7Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "initContainer2",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("4Gi"),
|
||||
hugepages1Gi: resource.MustParse("4Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1000Mi"),
|
||||
v1.ResourceMemory: resource.MustParse("4Gi"),
|
||||
hugepages1Gi: resource.MustParse("4Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
topologyHint: &topologymanager.TopologyHint{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.description, func(t *testing.T) {
|
||||
klog.InfoS("TestStaticPolicyAllocateWithInitContainers", "test name", testCase.description)
|
||||
p, s, err := initTests(t, &testCase, testCase.topologyHint)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
for i := range testCase.pod.Spec.InitContainers {
|
||||
err = p.Allocate(s, testCase.pod, &testCase.pod.Spec.InitContainers[i])
|
||||
if !reflect.DeepEqual(err, testCase.expectedError) {
|
||||
t.Fatalf("The actual error %v is different from the expected one %v", err, testCase.expectedError)
|
||||
}
|
||||
}
|
||||
|
||||
for i := range testCase.pod.Spec.Containers {
|
||||
err = p.Allocate(s, testCase.pod, &testCase.pod.Spec.Containers[i])
|
||||
if !reflect.DeepEqual(err, testCase.expectedError) {
|
||||
t.Fatalf("The actual error %v is different from the expected one %v", err, testCase.expectedError)
|
||||
}
|
||||
}
|
||||
|
||||
assignments := s.GetMemoryAssignments()
|
||||
if !areContainerMemoryAssignmentsEqual(t, assignments, testCase.expectedAssignments) {
|
||||
t.Fatalf("Actual assignments %v are different from the expected %v", assignments, testCase.expectedAssignments)
|
||||
}
|
||||
|
||||
machineState := s.GetMachineState()
|
||||
if !areMachineStatesEqual(machineState, testCase.expectedMachineState) {
|
||||
t.Fatalf("The actual machine state %v is different from the expected %v", machineState, testCase.expectedMachineState)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStaticPolicyRemoveContainer(t *testing.T) {
|
||||
testCases := []testStaticPolicy{
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user