github.com/projecteru2/core@v0.0.0-20240321043226-06bcc1c23f58/resource/plugins/cpumem/calculate_test.go (about) 1 package cpumem 2 3 import ( 4 "context" 5 "fmt" 6 "testing" 7 8 "github.com/cockroachdb/errors" 9 "github.com/docker/go-units" 10 "github.com/projecteru2/core/resource/plugins/cpumem/types" 11 plugintypes "github.com/projecteru2/core/resource/plugins/types" 12 coretypes "github.com/projecteru2/core/types" 13 "github.com/stretchr/testify/assert" 14 ) 15 16 func TestCalculateDeploy(t *testing.T) { 17 ctx := context.Background() 18 cm := initCPUMEM(ctx, t) 19 nodes := generateNodes(ctx, t, cm, 1, 2, 4*units.GB, 100, 0) 20 node := nodes[0] 21 22 // invalid opts 23 req := plugintypes.WorkloadResourceRequest{ 24 "cpu-bind": true, 25 "cpu-request": -1, 26 } 27 _, err := cm.CalculateDeploy(ctx, node, 100, req) 28 assert.True(t, errors.Is(err, types.ErrInvalidCPU)) 29 30 // non-existent node 31 req = plugintypes.WorkloadResourceRequest{ 32 "cpu-bind": true, 33 "cpu-request": 1, 34 } 35 _, err = cm.CalculateDeploy(ctx, "xxx", 100, req) 36 assert.True(t, errors.Is(err, coretypes.ErrInvaildCount)) 37 38 // cpu bind 39 req = plugintypes.WorkloadResourceRequest{ 40 "cpu-bind": true, 41 "cpu-request": 1.1, 42 } 43 _, err = cm.CalculateDeploy(ctx, node, 1, req) 44 assert.Nil(t, err) 45 46 // cpu bind & insufficient resource 47 req = plugintypes.WorkloadResourceRequest{ 48 "cpu-bind": true, 49 "cpu-request": 2.2, 50 } 51 _, err = cm.CalculateDeploy(ctx, node, 1, req) 52 assert.True(t, errors.Is(err, coretypes.ErrInsufficientCapacity)) 53 54 req = plugintypes.WorkloadResourceRequest{ 55 "cpu-bind": true, 56 "cpu-request": 1, 57 } 58 _, err = cm.CalculateDeploy(ctx, node, 3, req) 59 assert.True(t, errors.Is(err, coretypes.ErrInsufficientCapacity)) 60 61 // alloc by memory 62 req = plugintypes.WorkloadResourceRequest{ 63 "memory-request": fmt.Sprintf("%v", units.GB), 64 } 65 _, err = cm.CalculateDeploy(ctx, node, 1, req) 66 assert.Nil(t, err) 67 68 // alloc by memory & insufficient cpu 69 req = plugintypes.WorkloadResourceRequest{ 70 "memory-request": fmt.Sprintf("%v", units.GB), 71 "cpu-request": 1000, 72 } 73 _, err = cm.CalculateDeploy(ctx, node, 1, req) 74 assert.True(t, errors.Is(err, coretypes.ErrInsufficientCapacity)) 75 76 // alloc by memory & insufficient mem 77 req = plugintypes.WorkloadResourceRequest{ 78 "memory-request": fmt.Sprintf("%v", 5*units.GB), 79 "cpu-request": 1, 80 } 81 _, err = cm.CalculateDeploy(ctx, node, 1, req) 82 assert.True(t, errors.Is(err, coretypes.ErrInsufficientCapacity)) 83 84 // mem_request == 0 85 req = plugintypes.WorkloadResourceRequest{ 86 "memory-request": "0", 87 "cpu-request": 1, 88 } 89 _, err = cm.CalculateDeploy(ctx, node, 1, req) 90 assert.Nil(t, err) 91 92 // numa node 93 resource := plugintypes.NodeResource{ 94 "cpu": 4.0, 95 "cpu_map": map[string]int64{ 96 "0": 100, 97 "1": 100, 98 "2": 100, 99 "3": 100, 100 }, 101 "memory": 4 * units.GB, 102 "numa_memory": map[string]int64{ 103 "0": 2 * units.GB, 104 "1": 2 * units.GB, 105 }, 106 "numa": map[string]string{ 107 "0": "0", 108 "2": "0", 109 "1": "1", 110 "3": "1", 111 }, 112 } 113 114 _, err = cm.SetNodeResourceCapacity(ctx, node, resource, nil, false, true) 115 assert.Nil(t, err) 116 117 req = plugintypes.WorkloadResourceRequest{ 118 "cpu-bind": true, 119 "memory": fmt.Sprintf("%v", units.GB), 120 "cpu-request": 1.3, 121 } 122 r, err := cm.CalculateDeploy(ctx, node, 1, req) 123 assert.Nil(t, err) 124 assert.NotNil(t, r.WorkloadsResource) 125 } 126 127 func TestCalculateRealloc(t *testing.T) { 128 ctx := context.Background() 129 cm := initCPUMEM(ctx, t) 130 nodes := generateNodes(ctx, t, cm, 1, 2, 4*units.GB, 100, 0) 131 node := nodes[0] 132 133 // numa node 134 resource := plugintypes.NodeResource{ 135 "cpu": 2.0, 136 "cpu_map": map[string]int64{ 137 "0": 100, 138 "1": 100, 139 }, 140 "memory": 4 * units.GB, 141 "numa_memory": map[string]int64{ 142 "0": units.GB, 143 "1": units.GB, 144 }, 145 "numa": map[string]string{ 146 "0": "0", 147 "1": "1", 148 }, 149 } 150 151 _, err := cm.SetNodeResourceCapacity(ctx, node, resource, nil, false, true) 152 assert.Nil(t, err) 153 154 origin := plugintypes.WorkloadResource{} 155 req := plugintypes.WorkloadResourceRequest{} 156 157 // non-existent node 158 _, err = cm.CalculateRealloc(ctx, "xxx", origin, req) 159 assert.True(t, errors.Is(err, coretypes.ErrInvaildCount)) 160 161 // invalid resource opts 162 origin = plugintypes.WorkloadResource{ 163 "cpu_request": 1, 164 "cpu_limit": 1, 165 "memory_request": units.GB, 166 "memory_limit": units.GB, 167 "cpu_map": types.CPUMap{"0": 100}, 168 "numa_memory": types.NUMAMemory{"0": units.GB}, 169 "numa_node": "0", 170 } 171 req = plugintypes.WorkloadResourceRequest{ 172 "keep-cpu-bind": true, 173 "cpu-request": -3, 174 } 175 _, err = cm.CalculateRealloc(ctx, node, origin, req) 176 assert.True(t, errors.Is(err, types.ErrInvalidCPU)) 177 178 // insufficient cpu 179 req = plugintypes.WorkloadResourceRequest{ 180 "keep-cpu-bind": true, 181 "cpu-request": 2, 182 } 183 _, err = cm.CalculateRealloc(ctx, node, origin, req) 184 assert.True(t, errors.Is(err, coretypes.ErrInsufficientResource)) 185 186 // normal case (with cpu-bind) 187 req = plugintypes.WorkloadResourceRequest{ 188 "keep-cpu-bind": true, 189 "cpu-request": -0.5, 190 "cpu-limit": -0.5, 191 } 192 _, err = cm.CalculateRealloc(ctx, node, origin, req) 193 assert.Nil(t, err) 194 195 // normal case (without cpu-bind) 196 req = plugintypes.WorkloadResourceRequest{} 197 _, err = cm.CalculateRealloc(ctx, node, origin, req) 198 assert.Nil(t, err) 199 200 // insufficient mem 201 req = plugintypes.WorkloadResourceRequest{ 202 "memory-request": fmt.Sprintf("%v", units.PB), 203 "memory-limit": fmt.Sprintf("%v", units.PB), 204 } 205 _, err = cm.CalculateRealloc(ctx, node, origin, req) 206 assert.True(t, errors.Is(err, coretypes.ErrInsufficientCapacity)) 207 } 208 209 func TestCalculateRemap(t *testing.T) { 210 ctx := context.Background() 211 cm := initCPUMEM(ctx, t) 212 nodes := generateNodes(ctx, t, cm, 1, 4, 4*units.GB, 100, 0) 213 node := nodes[0] 214 215 resource := plugintypes.NodeResource{ 216 "cpu_map": map[string]int64{ 217 "0": 100, 218 "1": 100, 219 }, 220 } 221 _, err := cm.SetNodeResourceUsage(ctx, node, resource, nil, nil, false, true) 222 assert.Nil(t, err) 223 224 workloadsResource := map[string]plugintypes.WorkloadResource{ 225 "id1": { 226 "cpu_request": 1, 227 "cpu_limit": 1, 228 "memory_request": units.GB, 229 "memory_limit": units.GB, 230 }, 231 "id2": { 232 "cpu_request": 1, 233 "cpu_limit": 1, 234 "memory_request": units.GB, 235 "memory_limit": units.GB, 236 }, 237 "id3": { 238 "cpu_map": types.CPUMap{"0": 100, "1": 100}, 239 "cpu_request": 2, 240 "cpu_limit": 2, 241 "memory_request": units.GB, 242 "memory_limit": units.GB, 243 }, 244 } 245 246 // non-existent node 247 _, err = cm.CalculateRemap(ctx, "xxx", workloadsResource) 248 assert.True(t, errors.Is(err, coretypes.ErrInvaildCount)) 249 250 // normal case 251 r, err := cm.CalculateRemap(ctx, node, workloadsResource) 252 assert.Nil(t, err) 253 assert.Len(t, r.EngineParamsMap, 2) 254 w1 := r.EngineParamsMap["id1"] 255 w2 := r.EngineParamsMap["id2"] 256 assert.Len(t, w1["cpu_map"], 2) 257 assert.Len(t, w2["cpu_map"], 2) 258 259 // empty share cpu map 260 workloadsResource["id4"] = plugintypes.WorkloadResource{ 261 "cpu_map": types.CPUMap{"2": 100, "3": 100}, 262 "cpu_request": 2, 263 "cpu_limit": 2, 264 "memory_request": units.GB, 265 "memory_limit": units.GB, 266 } 267 268 resource = plugintypes.NodeResource{ 269 "cpu_map": map[string]int64{ 270 "0": 100, 271 "1": 100, 272 "2": 100, 273 "3": 100, 274 }, 275 } 276 _, err = cm.SetNodeResourceUsage(ctx, node, resource, nil, nil, false, true) 277 assert.Nil(t, err) 278 279 r, err = cm.CalculateRemap(ctx, node, workloadsResource) 280 assert.Nil(t, err) 281 assert.Len(t, r.EngineParamsMap, 2) 282 w1 = r.EngineParamsMap["id1"] 283 w2 = r.EngineParamsMap["id2"] 284 assert.Len(t, w1["cpu_map"], 4) 285 assert.Len(t, w2["cpu_map"], 4) 286 }