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  }