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:
Artyom Lukianov 2021-03-04 14:49:56 +02:00
parent 960da7895c
commit bb6d5b1f95
2 changed files with 776 additions and 1 deletions

View File

@ -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 {

View File

@ -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{
{