github.com/kubewharf/katalyst-core@v0.5.3/pkg/agent/orm/pod_resource_test.go (about)

     1  /*
     2  Copyright 2022 The Katalyst Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package orm
    18  
    19  import (
    20  	"testing"
    21  
    22  	"github.com/stretchr/testify/assert"
    23  	"k8s.io/apimachinery/pkg/util/sets"
    24  	"k8s.io/klog/v2"
    25  	pluginapi "k8s.io/kubelet/pkg/apis/resourceplugin/v1alpha1"
    26  
    27  	"github.com/kubewharf/katalyst-core/pkg/agent/orm/checkpoint"
    28  )
    29  
    30  func TestPodResources(t *testing.T) {
    31  	t.Parallel()
    32  
    33  	podResource := newPodResourcesChk()
    34  
    35  	resourceAllocationInfo := generateResourceAllocationInfo()
    36  
    37  	podResource.insert("testPod", "testContainer", "cpu", resourceAllocationInfo)
    38  
    39  	containerResources := podResource.podResources("testPod")
    40  	assert.NotNil(t, containerResources)
    41  	assert.Equal(t, len(containerResources), 1)
    42  	containerResources = podResource.podResources("nonPod")
    43  	assert.Nil(t, containerResources)
    44  
    45  	containerAllResources := podResource.containerAllResources("testPod", "testContainer")
    46  	assert.NotNil(t, containerAllResources)
    47  	assert.Equal(t, len(containerAllResources), 1)
    48  	containerAllResources = podResource.containerAllResources("nonPod", "testContainer")
    49  	assert.Nil(t, containerAllResources)
    50  	containerAllResources = podResource.containerAllResources("testPod", "nonContainer")
    51  	assert.Nil(t, containerAllResources)
    52  
    53  	podSet := podResource.pods()
    54  	assert.Equal(t, podSet, sets.NewString("testPod"))
    55  	resourceSet := podResource.allAllocatedResourceNames()
    56  	assert.Equal(t, resourceSet, sets.NewString("cpu"))
    57  
    58  	podResource.insert("testPod", "testContainer", "memory", resourceAllocationInfo)
    59  	podResource.insert("testPod2", "testContainer2", "cpu", resourceAllocationInfo)
    60  	entries := podResource.toCheckpointData()
    61  	assert.Equal(t, len(entries), 3)
    62  
    63  	podResource.deletePod("testPod")
    64  	podResource.deletePod("testPod2")
    65  	containerResources = podResource.podResources("testPod")
    66  	assert.Nil(t, containerResources)
    67  
    68  	podResource.insert("testPod", "testContainer", "cpu", resourceAllocationInfo)
    69  	podResource.delete([]string{"testPod"})
    70  	containerResources = podResource.podResources("testPod")
    71  	assert.Nil(t, containerResources)
    72  
    73  	podResource.insert("testPod", "testContainer", "cpu", resourceAllocationInfo)
    74  	podResource.deleteResourceAllocationInfo("testPod", "testContainer", "cpu")
    75  	containerAllResources = podResource.containerAllResources("testPod", "testContainer")
    76  	assert.NotNil(t, containerAllResources)
    77  	assert.Equal(t, len(containerAllResources), 0)
    78  }
    79  
    80  func TestCheckpointMarshal(t *testing.T) {
    81  	t.Parallel()
    82  	/* ----  use allocationInfo.Marshal  ----- */
    83  	podResources := newPodResourcesChk()
    84  	podResources.resources = map[string]ContainerResources{
    85  		"testPodUid": map[string]ResourceAllocation{
    86  			"testContainer": map[string]*pluginapi.ResourceAllocationInfo{
    87  				"memory": {
    88  					OciPropertyName:   "CpusetMems",
    89  					IsNodeResource:    true,
    90  					IsScalarResource:  true,
    91  					AllocatedQuantity: 400000000, // more than 1000
    92  					AllocationResult:  "0",
    93  				},
    94  			},
    95  		},
    96  	}
    97  
    98  	var entries []checkpoint.PodResourcesEntry
    99  	for podUID, containerResources := range podResources.resources {
   100  		for conName, resourcesAllocation := range containerResources {
   101  			for resourceName, allocationInfo := range resourcesAllocation {
   102  				// use allocationInfo.Marshal()
   103  				allocRespBytes, err := allocationInfo.Marshal()
   104  				if err != nil {
   105  					klog.Errorf("Can't marshal allocationInfo for %v %v %v: %v", podUID, conName, resourceName, err)
   106  					continue
   107  				}
   108  				entries = append(entries, checkpoint.PodResourcesEntry{
   109  					PodUID:         podUID,
   110  					ContainerName:  conName,
   111  					ResourceName:   resourceName,
   112  					AllocationInfo: string(allocRespBytes),
   113  				})
   114  			}
   115  		}
   116  	}
   117  	data := checkpoint.New(entries)
   118  	value, err := data.MarshalCheckpoint()
   119  	assert.NoError(t, err)
   120  
   121  	resEntries := make([]checkpoint.PodResourcesEntry, 0)
   122  	cp := checkpoint.New(resEntries)
   123  	err = cp.UnmarshalCheckpoint(value)
   124  	assert.NoError(t, err)
   125  	// we just marshal and unmarshal the data, checksum should be the same.
   126  	err = cp.VerifyChecksum()
   127  	assert.Error(t, err) // here we got an error, actually we can not get checkpoint data from file.
   128  
   129  	/* ----  use json.Marshal  ----- */
   130  	podResources = newPodResourcesChk()
   131  	podResources.resources = map[string]ContainerResources{
   132  		"testPodUid": map[string]ResourceAllocation{
   133  			"testContainer": map[string]*pluginapi.ResourceAllocationInfo{
   134  				"memory": {
   135  					OciPropertyName:   "CpusetMems",
   136  					IsNodeResource:    true,
   137  					IsScalarResource:  true,
   138  					AllocatedQuantity: 400000000, // more than 1000
   139  					AllocationResult:  "0",
   140  				},
   141  			},
   142  		},
   143  	}
   144  
   145  	data = checkpoint.New(podResources.toCheckpointData()) // the only difference is than we use json.Marshal
   146  	value, err = data.MarshalCheckpoint()
   147  	assert.NoError(t, err)
   148  
   149  	resEntries = make([]checkpoint.PodResourcesEntry, 0)
   150  	cp = checkpoint.New(resEntries)
   151  	err = cp.UnmarshalCheckpoint(value)
   152  	assert.NoError(t, err)
   153  	// we just marshal and unmarshal the data, checksum should be the same.
   154  	err = cp.VerifyChecksum()
   155  	assert.NoError(t, err)
   156  }
   157  
   158  func generateResourceAllocationInfo() *pluginapi.ResourceAllocationInfo {
   159  	return &pluginapi.ResourceAllocationInfo{
   160  		OciPropertyName:   "CpusetCpus",
   161  		IsNodeResource:    true,
   162  		IsScalarResource:  true,
   163  		AllocatedQuantity: 3,
   164  		AllocationResult:  "5-6,10",
   165  		Envs:              map[string]string{"mock_key": "mock_env"},
   166  		Annotations:       map[string]string{"mock_key": "mock_ano"},
   167  		ResourceHints:     &pluginapi.ListOfTopologyHints{},
   168  	}
   169  }