You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

strategy_test.go 6.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. package test
  2. import (
  3. "fmt"
  4. "gitlink.org.cn/JointCloud/pcm-coordinator/api/internal/scheduler/entity"
  5. "gitlink.org.cn/JointCloud/pcm-coordinator/api/internal/scheduler/service/collector"
  6. "gitlink.org.cn/JointCloud/pcm-coordinator/api/internal/scheduler/strategy"
  7. "math/rand"
  8. "testing"
  9. "time"
  10. )
  11. func TestReplication(t *testing.T) {
  12. parts := []entity.Participant{
  13. {Name: "test1", Participant_id: 1},
  14. {Name: "test2", Participant_id: 2},
  15. {Name: "test3", Participant_id: 3},
  16. }
  17. rsc := []*collector.ResourceStats{
  18. {
  19. ClusterId: "1",
  20. Name: "test1",
  21. },
  22. {
  23. ClusterId: "2",
  24. Name: "test2"},
  25. {
  26. ClusterId: "3",
  27. Name: "test3"},
  28. }
  29. tests := []struct {
  30. name string
  31. replica int32
  32. ps []entity.Participant
  33. res []*collector.ResourceStats
  34. }{
  35. {
  36. name: "test1",
  37. replica: 1,
  38. ps: parts,
  39. },
  40. {
  41. name: "test2",
  42. replica: 2,
  43. ps: parts,
  44. },
  45. }
  46. for _, tt := range tests {
  47. t.Run(tt.name, func(t *testing.T) {
  48. var clusterIds []string
  49. for _, stats := range rsc {
  50. clusterIds = append(clusterIds, stats.ClusterId)
  51. }
  52. repl := strategy.NewReplicationStrategy(clusterIds, 0)
  53. schedule, err := repl.Schedule()
  54. if err != nil {
  55. return
  56. }
  57. for _, cluster := range schedule {
  58. fmt.Println(cluster)
  59. }
  60. })
  61. }
  62. }
  63. func TestStaticWeight(t *testing.T) {
  64. parts := map[string]int32{
  65. "test1": 6,
  66. "test2": 5,
  67. "test3": 2,
  68. }
  69. tests := []struct {
  70. name string
  71. replica int32
  72. ps map[string]int32
  73. }{
  74. {
  75. name: "test1",
  76. replica: 1,
  77. ps: parts,
  78. },
  79. {
  80. name: "test2",
  81. replica: 5,
  82. ps: parts,
  83. },
  84. {
  85. name: "test2",
  86. replica: 6,
  87. ps: parts,
  88. },
  89. }
  90. for _, tt := range tests {
  91. t.Run(tt.name, func(t *testing.T) {
  92. repl := strategy.NewStaticWeightStrategy(tt.ps, tt.replica)
  93. schedule, err := repl.Schedule()
  94. if err != nil {
  95. return
  96. }
  97. for _, cluster := range schedule {
  98. fmt.Println(cluster)
  99. }
  100. })
  101. }
  102. }
  103. func TestRandom(t *testing.T) {
  104. // 使用当前时间作为随机数种子,确保每次程序运行产生的随机数序列都不同
  105. rand.Seed(time.Now().UnixNano())
  106. /*randomNum := randInt(1, 100)
  107. fmt.Println("Random number:", randomNum)*/
  108. total := 5 // 假设总数是5
  109. first, second := splitIntoTwoRandomParts(total)
  110. fmt.Printf("第一部分的数量: %d, 第二部分的数量: %d\n", first, second)
  111. }
  112. // randInt 生成一个指定范围内的随机整数,包括min但不包括max
  113. func randInt(min, max int) int {
  114. return min + rand.Intn(max-min)
  115. }
  116. func splitIntoTwoRandomParts(total int) (int, int) {
  117. if total < 2 {
  118. // 如果总数小于2,则无法分成两部分
  119. return 0, 0
  120. }
  121. // 生成一个随机数作为第一部分的数量(范围在[1, total-1]之间)
  122. firstPart := rand.Intn(total-1) + 1
  123. // 第二部分的数量就是总数减去第一部分的数量
  124. secondPart := total - firstPart
  125. return firstPart, secondPart
  126. }
  127. func splitIntoRandomParts(total int) (int, int) {
  128. if total < 2 {
  129. // 如果总数小于2,则无法分成两部分
  130. return 0, 0
  131. }
  132. // 生成一个随机数作为第一部分的数量(范围在[1, total-1]之间)
  133. firstPart := rand.Intn(total-1) + 1
  134. // 第二部分的数量就是总数减去第一部分的数量
  135. secondPart := total - firstPart
  136. return firstPart, secondPart
  137. }
  138. func TestRandoms(t *testing.T) {
  139. // 使用当前时间作为随机数种子,确保每次程序运行产生的随机数序列都不同
  140. rand.Seed(time.Now().UnixNano())
  141. /*randomNum := randInt(1, 100)
  142. fmt.Println("Random number:", randomNum)*/
  143. total := 10 // 假设总数是5
  144. parts := splitRandomParts(total)
  145. fmt.Println("分配结果:", parts)
  146. }
  147. // splitIntoRandomParts 将总数total随机分成多个部分,并返回这些部分的切片
  148. func splitRandomParts(total int) []int {
  149. if total < 2 {
  150. // 如果总数小于2,则无法分成多个部分
  151. return []int{total}
  152. }
  153. // 创建一个切片来保存每个部分的数量
  154. var parts []int
  155. // 剩余要分配的副本数
  156. remaining := total
  157. // 随机决定要分成的部分数量(至少2个部分)
  158. numParts := rand.Intn(total-1) + 2
  159. // 确保每个部分至少获得1个副本
  160. for i := 0; i < numParts-1; i++ {
  161. // 生成一个随机数(1到剩余副本数之间)
  162. // 为了避免最后一个部分太小,我们可能需要调整随机数范围
  163. minPartSize := 1
  164. if remaining <= numParts-i {
  165. // 如果剩余副本数不足以让每个部分都至少获得1个,则调整最小部分大小
  166. minPartSize = remaining / (numParts - i)
  167. if remaining%(numParts-i) > 0 {
  168. minPartSize++
  169. }
  170. }
  171. // 生成一个大于等于minPartSize且小于等于remaining的随机数
  172. partSize := minPartSize + rand.Intn(remaining-minPartSize+1)
  173. parts = append(parts, partSize)
  174. remaining -= partSize
  175. }
  176. // 最后一个部分的数量就是剩余的副本数
  177. parts = append(parts, remaining)
  178. return parts
  179. }
  180. func TestNumRandom(t *testing.T) {
  181. total := 10 // 假设副本数是10
  182. numParts := 2 // 假设要分成5个集群
  183. parts, err := splitIntoParts(total, numParts)
  184. if err != nil {
  185. fmt.Println("Error:", err)
  186. return
  187. }
  188. fmt.Println("分配结果:", parts)
  189. }
  190. // splitIntoParts 将总数total随机分成numParts个部分,并返回这些部分的切片
  191. func splitIntoParts(total int, numParts int) ([]int, error) {
  192. if total < 1 || numParts < 1 {
  193. // 总数或部分数量不能小于1
  194. return nil, fmt.Errorf("total and numParts must be greater than 0")
  195. }
  196. if numParts > total {
  197. // 部分数量不能大于总数
  198. return nil, fmt.Errorf("numParts cannot be greater than total")
  199. }
  200. // 创建一个切片来保存每个部分的数量
  201. parts := make([]int, numParts)
  202. // 首先将每个部分都分配至少一个副本
  203. for i := range parts {
  204. parts[i] = 1
  205. total--
  206. }
  207. // 剩余要分配的副本数
  208. remaining := total
  209. // 随机分配剩余的副本
  210. for remaining > 0 {
  211. // 随机选择一个部分(索引从0到numParts-1)
  212. partIndex := rand.Intn(numParts)
  213. // 如果该部分加上一个副本后不会超过总数,则分配一个副本
  214. if parts[partIndex]+1 <= total {
  215. parts[partIndex]++
  216. remaining--
  217. }
  218. }
  219. return parts, nil
  220. }

PCM is positioned as Software stack over Cloud, aiming to build the standards and ecology of heterogeneous cloud collaboration for JCC in a non intrusive and autonomous peer-to-peer manner.