topology_test.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package gocql
  2. import (
  3. "fmt"
  4. "sort"
  5. "testing"
  6. )
  7. func TestPlacementStrategy_SimpleStrategy(t *testing.T) {
  8. host0 := &HostInfo{hostId: "0"}
  9. host25 := &HostInfo{hostId: "25"}
  10. host50 := &HostInfo{hostId: "50"}
  11. host75 := &HostInfo{hostId: "75"}
  12. tokenRing := []hostToken{
  13. {intToken(0), host0},
  14. {intToken(25), host25},
  15. {intToken(50), host50},
  16. {intToken(75), host75},
  17. }
  18. hosts := []*HostInfo{host0, host25, host50, host75}
  19. strat := &simpleStrategy{rf: 2}
  20. tokenReplicas := strat.replicaMap(hosts, tokenRing)
  21. if len(tokenReplicas) != len(tokenRing) {
  22. t.Fatalf("expected replica map to have %d items but has %d", len(tokenRing), len(tokenReplicas))
  23. }
  24. for token, replicas := range tokenReplicas {
  25. if len(replicas) != strat.rf {
  26. t.Errorf("expected to have %d replicas got %d for token=%v", strat.rf, len(replicas), token)
  27. }
  28. }
  29. for i, token := range tokenRing {
  30. replicas, ok := tokenReplicas[token.token]
  31. if !ok {
  32. t.Errorf("token %v not in replica map", token)
  33. }
  34. for j, replica := range replicas {
  35. exp := tokenRing[(i+j)%len(tokenRing)].host
  36. if exp != replica {
  37. t.Errorf("expected host %v to be a replica of %v got %v", exp, token, replica)
  38. }
  39. }
  40. }
  41. }
  42. func TestPlacementStrategy_NetworkStrategy(t *testing.T) {
  43. var (
  44. hosts []*HostInfo
  45. tokens []hostToken
  46. )
  47. const (
  48. totalDCs = 3
  49. racksPerDC = 3
  50. hostsPerDC = 5
  51. )
  52. dcRing := make(map[string][]hostToken, totalDCs)
  53. for i := 0; i < totalDCs; i++ {
  54. var dcTokens []hostToken
  55. dc := fmt.Sprintf("dc%d", i+1)
  56. for j := 0; j < hostsPerDC; j++ {
  57. rack := fmt.Sprintf("rack%d", (j%racksPerDC)+1)
  58. h := &HostInfo{hostId: fmt.Sprintf("%s:%s:%d", dc, rack, j), dataCenter: dc, rack: rack}
  59. token := hostToken{
  60. token: orderedToken([]byte(h.hostId)),
  61. host: h,
  62. }
  63. tokens = append(tokens, token)
  64. dcTokens = append(dcTokens, token)
  65. hosts = append(hosts, h)
  66. }
  67. sort.Sort(&tokenRing{tokens: dcTokens})
  68. dcRing[dc] = dcTokens
  69. }
  70. if len(tokens) != hostsPerDC*totalDCs {
  71. t.Fatalf("expected %d tokens in the ring got %d", hostsPerDC*totalDCs, len(tokens))
  72. }
  73. sort.Sort(&tokenRing{tokens: tokens})
  74. strat := &networkTopology{
  75. dcs: map[string]int{
  76. "dc1": 1,
  77. "dc2": 2,
  78. "dc3": 3,
  79. },
  80. }
  81. var expReplicas int
  82. for _, rf := range strat.dcs {
  83. expReplicas += rf
  84. }
  85. tokenReplicas := strat.replicaMap(hosts, tokens)
  86. if len(tokenReplicas) != len(tokens) {
  87. t.Fatalf("expected replica map to have %d items but has %d", len(tokens), len(tokenReplicas))
  88. }
  89. for token, replicas := range tokenReplicas {
  90. if len(replicas) != expReplicas {
  91. t.Fatalf("expected to have %d replicas got %d for token=%v", expReplicas, len(replicas), token)
  92. }
  93. }
  94. for dc, rf := range strat.dcs {
  95. dcTokens := dcRing[dc]
  96. for i, th := range dcTokens {
  97. token := th.token
  98. allReplicas, ok := tokenReplicas[token]
  99. if !ok {
  100. t.Fatalf("token %v not in replica map", token)
  101. }
  102. var replicas []*HostInfo
  103. for _, replica := range allReplicas {
  104. if replica.dataCenter == dc {
  105. replicas = append(replicas, replica)
  106. }
  107. }
  108. if len(replicas) != rf {
  109. t.Fatalf("expected %d replicas in dc %q got %d", rf, dc, len(replicas))
  110. }
  111. var lastRack string
  112. for j, replica := range replicas {
  113. // expected is in the next rack
  114. var exp *HostInfo
  115. if lastRack == "" {
  116. // primary, first replica
  117. exp = dcTokens[(i+j)%len(dcTokens)].host
  118. } else {
  119. for k := 0; k < len(dcTokens); k++ {
  120. // walk around the ring from i + j to find the next host the
  121. // next rack
  122. p := (i + j + k) % len(dcTokens)
  123. h := dcTokens[p].host
  124. if h.rack != lastRack {
  125. exp = h
  126. break
  127. }
  128. }
  129. if exp.rack == lastRack {
  130. panic("no more racks")
  131. }
  132. }
  133. lastRack = replica.rack
  134. }
  135. }
  136. }
  137. }