topology_test.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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. tokens := []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(&tokenRing{hosts: hosts, tokens: tokens})
  21. if len(tokenReplicas) != len(tokens) {
  22. t.Fatalf("expected replica map to have %d items but has %d", len(tokens), len(tokenReplicas))
  23. }
  24. for _, replicas := range tokenReplicas {
  25. if len(replicas.hosts) != strat.rf {
  26. t.Errorf("expected to have %d replicas got %d for token=%v", strat.rf, len(replicas.hosts), replicas.token)
  27. }
  28. }
  29. for i, token := range tokens {
  30. ht := tokenReplicas.replicasFor(token.token)
  31. if ht.token != token.token {
  32. t.Errorf("token %v not in replica map: %v", token, ht.hosts)
  33. }
  34. for j, replica := range ht.hosts {
  35. exp := tokens[(i+j)%len(tokens)].host
  36. if exp != replica {
  37. t.Errorf("expected host %v to be a replica of %v got %v", exp.hostId, token, replica.hostId)
  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. strats := []*networkTopology{
  75. &networkTopology{
  76. dcs: map[string]int{
  77. "dc1": 1,
  78. "dc2": 2,
  79. "dc3": 3,
  80. },
  81. },
  82. &networkTopology{
  83. dcs: map[string]int{
  84. "dc2": 2,
  85. "dc3": 3,
  86. },
  87. },
  88. }
  89. for _, strat := range strats {
  90. var expReplicas int
  91. for _, rf := range strat.dcs {
  92. expReplicas += rf
  93. }
  94. tokenReplicas := strat.replicaMap(&tokenRing{hosts: hosts, tokens: tokens})
  95. if needTokens := hostsPerDC * len(strat.dcs); len(tokenReplicas) != needTokens {
  96. t.Fatalf("expected replica map to have %d items but has %d", needTokens, len(tokenReplicas))
  97. }
  98. if !sort.IsSorted(tokenReplicas) {
  99. t.Fatal("replica map was not sorted by token")
  100. }
  101. for token, replicas := range tokenReplicas {
  102. if len(replicas.hosts) != expReplicas {
  103. t.Fatalf("expected to have %d replicas got %d for token=%v", expReplicas, len(replicas.hosts), token)
  104. }
  105. }
  106. for dc, rf := range strat.dcs {
  107. dcTokens := dcRing[dc]
  108. for i, th := range dcTokens {
  109. token := th.token
  110. allReplicas := tokenReplicas.replicasFor(token)
  111. if allReplicas.token != token {
  112. t.Fatalf("token %v not in replica map", token)
  113. }
  114. var replicas []*HostInfo
  115. for _, replica := range allReplicas.hosts {
  116. if replica.dataCenter == dc {
  117. replicas = append(replicas, replica)
  118. }
  119. }
  120. if len(replicas) != rf {
  121. t.Fatalf("expected %d replicas in dc %q got %d", rf, dc, len(replicas))
  122. }
  123. var lastRack string
  124. for j, replica := range replicas {
  125. // expected is in the next rack
  126. var exp *HostInfo
  127. if lastRack == "" {
  128. // primary, first replica
  129. exp = dcTokens[(i+j)%len(dcTokens)].host
  130. } else {
  131. for k := 0; k < len(dcTokens); k++ {
  132. // walk around the ring from i + j to find the next host the
  133. // next rack
  134. p := (i + j + k) % len(dcTokens)
  135. h := dcTokens[p].host
  136. if h.rack != lastRack {
  137. exp = h
  138. break
  139. }
  140. }
  141. if exp.rack == lastRack {
  142. panic("no more racks")
  143. }
  144. }
  145. lastRack = replica.rack
  146. }
  147. }
  148. }
  149. }
  150. }