mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 14:37:00 +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"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
cadvisorapi "github.com/google/cadvisor/info/v1"
|
cadvisorapi "github.com/google/cadvisor/info/v1"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
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/containermap"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state"
|
"k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager"
|
"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) {
|
func TestValidateReservedMemory(t *testing.T) {
|
||||||
machineInfo := &cadvisorapi.MachineInfo{
|
machineInfo := &cadvisorapi.MachineInfo{
|
||||||
Topology: []cadvisorapi.Node{
|
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 {
|
func returnMachineInfo() cadvisorapi.MachineInfo {
|
||||||
|
@ -21,6 +21,8 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
cadvisorapi "github.com/google/cadvisor/info/v1"
|
cadvisorapi "github.com/google/cadvisor/info/v1"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/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) {
|
func TestStaticPolicyRemoveContainer(t *testing.T) {
|
||||||
testCases := []testStaticPolicy{
|
testCases := []testStaticPolicy{
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user