github.com/kubewharf/katalyst-core@v0.5.3/pkg/agent/qrm-plugins/util/util_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 util
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	"github.com/stretchr/testify/require"
    24  	v1 "k8s.io/api/core/v1"
    25  	pluginapi "k8s.io/kubelet/pkg/apis/resourceplugin/v1alpha1"
    26  	"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask"
    27  
    28  	"github.com/kubewharf/katalyst-api/pkg/consts"
    29  	"github.com/kubewharf/katalyst-core/pkg/util/machine"
    30  )
    31  
    32  func TestGetQuantityFromResourceReq(t *testing.T) {
    33  	t.Parallel()
    34  
    35  	as := require.New(t)
    36  
    37  	testCases := []struct {
    38  		req    *pluginapi.ResourceRequest
    39  		result int
    40  		err    error
    41  	}{
    42  		{
    43  			req: &pluginapi.ResourceRequest{
    44  				ResourceRequests: map[string]float64{
    45  					string(v1.ResourceCPU): 123,
    46  				},
    47  			},
    48  			result: 123,
    49  		},
    50  		{
    51  			req: &pluginapi.ResourceRequest{
    52  				ResourceRequests: map[string]float64{
    53  					string(consts.ReclaimedResourceMilliCPU): 234001,
    54  				},
    55  			},
    56  			result: 235,
    57  		},
    58  		{
    59  			req: &pluginapi.ResourceRequest{
    60  				ResourceRequests: map[string]float64{
    61  					string(v1.ResourceMemory): 256,
    62  				},
    63  			},
    64  			result: 256,
    65  		},
    66  		{
    67  			req: &pluginapi.ResourceRequest{
    68  				ResourceRequests: map[string]float64{
    69  					string(consts.ReclaimedResourceMemory): 1345,
    70  				},
    71  			},
    72  			result: 1345,
    73  		},
    74  		{
    75  			req: &pluginapi.ResourceRequest{
    76  				ResourceRequests: map[string]float64{
    77  					"test": 1345,
    78  				},
    79  			},
    80  			err: fmt.Errorf("invalid request resource name: %s", "test"),
    81  		},
    82  	}
    83  
    84  	for _, tc := range testCases {
    85  		res, _, err := GetQuantityFromResourceReq(tc.req)
    86  		if tc.err != nil {
    87  			as.NotNil(err)
    88  		} else {
    89  			as.EqualValues(tc.result, res)
    90  		}
    91  	}
    92  }
    93  
    94  func TestDeepCopyTopologyAwareAssignments(t *testing.T) {
    95  	t.Parallel()
    96  
    97  	as := require.New(t)
    98  
    99  	testCases := []struct {
   100  		description              string
   101  		topologyAwareAssignments map[int]machine.CPUSet
   102  	}{
   103  		{
   104  			description: "nil topologyAwareAssignments",
   105  		},
   106  		{
   107  			description: "non-nil topologyAwareAssignments",
   108  			topologyAwareAssignments: map[int]machine.CPUSet{
   109  				0: machine.NewCPUSet(0, 1, 8, 9),
   110  				1: machine.NewCPUSet(2, 3, 10, 11),
   111  				2: machine.NewCPUSet(4, 5, 12, 13),
   112  				3: machine.NewCPUSet(6, 7, 14, 15),
   113  			},
   114  		},
   115  	}
   116  
   117  	for _, tc := range testCases {
   118  		copiedAssignments := machine.DeepcopyCPUAssignment(tc.topologyAwareAssignments)
   119  		as.Equalf(tc.topologyAwareAssignments, copiedAssignments, "failed in test case: %s", tc.description)
   120  	}
   121  }
   122  
   123  func TestHintToIntArray(t *testing.T) {
   124  	t.Parallel()
   125  
   126  	as := require.New(t)
   127  
   128  	testCases := []struct {
   129  		description   string
   130  		hint          *pluginapi.TopologyHint
   131  		expectedArray []int
   132  	}{
   133  		{
   134  			description:   "nil hint",
   135  			expectedArray: []int{},
   136  		},
   137  		{
   138  			description: "empty nodes in hint",
   139  			hint: &pluginapi.TopologyHint{
   140  				Nodes:     []uint64{},
   141  				Preferred: false,
   142  			},
   143  			expectedArray: []int{},
   144  		},
   145  		{
   146  			description: "nil nodes in hint",
   147  			hint: &pluginapi.TopologyHint{
   148  				Nodes:     nil,
   149  				Preferred: false,
   150  			},
   151  			expectedArray: []int{},
   152  		},
   153  		{
   154  			description: "non-empty nodes in hint",
   155  			hint: &pluginapi.TopologyHint{
   156  				Nodes:     []uint64{0, 1, 2, 3},
   157  				Preferred: false,
   158  			},
   159  			expectedArray: []int{0, 1, 2, 3},
   160  		},
   161  	}
   162  
   163  	for _, tc := range testCases {
   164  		actualArray := HintToIntArray(tc.hint)
   165  		as.Equalf(tc.expectedArray, actualArray, "failed in test case: %s", tc.description)
   166  	}
   167  }
   168  
   169  func TestMaskToUInt64Array(t *testing.T) {
   170  	t.Parallel()
   171  
   172  	as := require.New(t)
   173  
   174  	nonEmptyMask, err := bitmask.NewBitMask(0, 1, 2, 3)
   175  	as.Nil(err)
   176  
   177  	testCases := []struct {
   178  		description   string
   179  		mask          bitmask.BitMask
   180  		expectedArray []uint64
   181  	}{
   182  		{
   183  			description:   "empty mask",
   184  			mask:          bitmask.NewEmptyBitMask(),
   185  			expectedArray: []uint64{},
   186  		},
   187  		{
   188  			description:   "non-empty mask",
   189  			mask:          nonEmptyMask,
   190  			expectedArray: []uint64{0, 1, 2, 3},
   191  		},
   192  	}
   193  
   194  	for _, tc := range testCases {
   195  		actualArray := machine.MaskToUInt64Array(tc.mask)
   196  		as.Equalf(tc.expectedArray, actualArray, "failed in test case: %s", tc.description)
   197  	}
   198  }
   199  
   200  func TestTransformTopologyAwareQuantity(t *testing.T) {
   201  	t.Parallel()
   202  
   203  	as := require.New(t)
   204  
   205  	testCases := []struct {
   206  		description          string
   207  		assignments          map[int]machine.CPUSet
   208  		expectedQuantityList []*pluginapi.TopologyAwareQuantity
   209  	}{
   210  		{
   211  			description: "nil assignments",
   212  		},
   213  		{
   214  			description: "singe numa",
   215  			assignments: map[int]machine.CPUSet{0: machine.NewCPUSet(0, 1, 8, 9)},
   216  			expectedQuantityList: []*pluginapi.TopologyAwareQuantity{
   217  				{ResourceValue: 4, Node: 0},
   218  			},
   219  		},
   220  		{
   221  			description: "multi-numas",
   222  			assignments: map[int]machine.CPUSet{
   223  				0: machine.NewCPUSet(0, 1, 8, 9),
   224  				1: machine.NewCPUSet(2, 10),
   225  			},
   226  			expectedQuantityList: []*pluginapi.TopologyAwareQuantity{
   227  				{ResourceValue: 4, Node: 0},
   228  				{ResourceValue: 2, Node: 1},
   229  			},
   230  		},
   231  		{
   232  			description: "full numas",
   233  			assignments: map[int]machine.CPUSet{
   234  				0: machine.NewCPUSet(0, 1, 8, 9),
   235  				1: machine.NewCPUSet(2, 3, 10, 11),
   236  				2: machine.NewCPUSet(4, 5, 12, 13),
   237  				3: machine.NewCPUSet(6, 7, 14, 15),
   238  			},
   239  			expectedQuantityList: []*pluginapi.TopologyAwareQuantity{
   240  				{ResourceValue: 4, Node: 0},
   241  				{ResourceValue: 4, Node: 1},
   242  				{ResourceValue: 4, Node: 2},
   243  				{ResourceValue: 4, Node: 3},
   244  			},
   245  		},
   246  	}
   247  
   248  	for _, tc := range testCases {
   249  		actualQuantityList := GetTopologyAwareQuantityFromAssignments(tc.assignments)
   250  		as.Equalf(tc.expectedQuantityList, actualQuantityList, "failed in test case: %s", tc.description)
   251  	}
   252  }