github.com/projecteru2/core@v0.0.0-20240321043226-06bcc1c23f58/strategy/communism_test.go (about)

     1  package strategy
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"sort"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  func TestCommunismPlan(t *testing.T) {
    13  	nodes := deployedNodes()
    14  	r, err := CommunismPlan(context.Background(), nodes, 1, 100, 0)
    15  	assert.NoError(t, err)
    16  	assert.ElementsMatch(t, []int{3, 3, 5, 7}, getFinalStatus(r, nodes))
    17  
    18  	r, err = CommunismPlan(context.Background(), nodes, 2, 1, 0)
    19  	assert.Error(t, err)
    20  
    21  	r, err = CommunismPlan(context.Background(), nodes, 2, 100, 0)
    22  	assert.NoError(t, err)
    23  	assert.ElementsMatch(t, []int{3, 4, 5, 7}, getFinalStatus(r, nodes))
    24  
    25  	r, err = CommunismPlan(context.Background(), nodes, 3, 100, 0)
    26  	assert.ElementsMatch(t, []int{4, 4, 5, 7}, getFinalStatus(r, nodes))
    27  
    28  	r, err = CommunismPlan(context.Background(), nodes, 4, 100, 0)
    29  	assert.NoError(t, err)
    30  	assert.ElementsMatch(t, []int{4, 5, 5, 7}, getFinalStatus(r, nodes))
    31  
    32  	r, err = CommunismPlan(context.Background(), nodes, 29, 100, 0)
    33  	assert.NoError(t, err)
    34  	assert.ElementsMatch(t, []int{11, 11, 12, 12}, getFinalStatus(r, nodes))
    35  
    36  	r, err = CommunismPlan(context.Background(), nodes, 37, 100, 0)
    37  	assert.NoError(t, err)
    38  	assert.ElementsMatch(t, []int{12, 13, 14, 15}, getFinalStatus(r, nodes))
    39  
    40  	r, err = CommunismPlan(context.Background(), nodes, 40, 100, 0)
    41  	assert.NoError(t, err)
    42  	assert.ElementsMatch(t, []int{12, 13, 15, 17}, getFinalStatus(r, nodes))
    43  }
    44  
    45  func TestCommunismPlanCapacityPriority(t *testing.T) {
    46  	nodes := genNodesByCapCount([]int{1, 2, 1, 5, 10}, []int{0, 0, 0, 0, 0})
    47  	deploy, err := CommunismPlan(context.Background(), nodes, 3, 15, 0)
    48  	assert.Nil(t, err)
    49  	assert.ElementsMatch(t, []int{0, 0, 1, 1, 1}, getFinalStatus(deploy, nodes))
    50  	assert.EqualValues(t, 1, deploy["1"])
    51  	assert.EqualValues(t, 1, deploy["3"])
    52  	assert.EqualValues(t, 1, deploy["4"])
    53  
    54  	nodes = genNodesByCapCount([]int{10, 4, 4}, []int{1, 1, 10})
    55  	deploy, err = CommunismPlan(context.Background(), nodes, 5, 100, 0)
    56  	assert.Nil(t, err)
    57  	assert.ElementsMatch(t, []int{3, 4, 10}, getFinalStatus(deploy, nodes))
    58  	assert.EqualValues(t, 3, deploy["0"])
    59  	assert.EqualValues(t, 2, deploy["1"])
    60  
    61  	nodes = genNodesByCapCount([]int{4, 5, 4, 10}, []int{2, 2, 4, 0})
    62  	deploy, err = CommunismPlan(context.Background(), nodes, 3, 100, 0)
    63  	assert.Nil(t, err)
    64  	assert.ElementsMatch(t, []int{2, 2, 3, 4}, getFinalStatus(deploy, nodes))
    65  	assert.EqualValues(t, 3, deploy["3"])
    66  
    67  	nodes = genNodesByCapCount([]int{3, 4, 5, 10}, []int{0, 0, 0, 0})
    68  	deploy, err = CommunismPlan(context.Background(), nodes, 3, 100, 0)
    69  	assert.Nil(t, err)
    70  	assert.ElementsMatch(t, []int{0, 1, 1, 1}, getFinalStatus(deploy, nodes))
    71  	assert.EqualValues(t, 1, deploy["3"])
    72  	assert.EqualValues(t, 1, deploy["2"])
    73  	assert.EqualValues(t, 1, deploy["1"])
    74  
    75  	// test limit
    76  	nodes = genNodesByCapCount([]int{3, 4, 5, 10}, []int{3, 5, 7, 10})
    77  	deploy, err = CommunismPlan(context.Background(), nodes, 3, 10, 5)
    78  	assert.Contains(t, err.Error(), "reached nodelimit, a node can host at most 5 instances")
    79  	deploy, err = CommunismPlan(context.Background(), nodes, 3, 10, 6)
    80  	assert.Nil(t, err)
    81  }
    82  
    83  //
    84  //func randomDeployStatus(scheduleInfos []resourcetypes.ScheduleInfo, maxDeployed int) (sis []Info) {
    85  //	s := rand.NewSource(int64(1024))
    86  //	r := rand.New(s)
    87  //	for range scheduleInfos {
    88  //		sis = append(sis, Info{
    89  //			Capacity: maxDeployed,
    90  //			Count:    r.Intn(maxDeployed),
    91  //		})
    92  //	}
    93  //	return
    94  //}
    95  
    96  //	func Benchmark_CommunismPlan(b *testing.B) {
    97  //		b.StopTimer()
    98  //		var count = 10000
    99  //		var maxDeployed = 1024
   100  //		var volTotal = maxDeployed * count
   101  //		var need = volTotal - 1
   102  //		// Simulate `count` nodes with difference deploy status, each one can deploy `maxDeployed` workloads
   103  //		// and then we deploy `need` workloads
   104  //		for i := 0; i < b.N; i++ {
   105  //			// 24 core, 128G memory, 10 pieces per core
   106  //			t := utils.GenerateScheduleInfos(count, 1, 1, 0, 10)
   107  //			hugePod := randomDeployStatus(t, maxDeployed)
   108  //			b.StartTimer()
   109  //			_, err := CommunismPlan(context.Background(), hugePod, need, 100, 0)
   110  //			b.StopTimer()
   111  //			assert.NoError(b, err)
   112  //		}
   113  //	}
   114  func genNodesByCapCount(caps, counts []int) (infos []Info) {
   115  	for i := range caps {
   116  		infos = append(infos, Info{
   117  			Nodename: fmt.Sprintf("%d", i),
   118  			Capacity: caps[i],
   119  			Count:    counts[i],
   120  		})
   121  	}
   122  	return
   123  }
   124  
   125  func getFinalStatus(deploy map[string]int, infos []Info) (counts []int) {
   126  	for _, info := range infos {
   127  		counts = append(counts, info.Count+deploy[info.Nodename])
   128  	}
   129  	sort.Ints(counts)
   130  	return
   131  }