| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- package gocql
- import (
- "fmt"
- "sort"
- "testing"
- )
- func TestPlacementStrategy_SimpleStrategy(t *testing.T) {
- host0 := &HostInfo{hostId: "0"}
- host25 := &HostInfo{hostId: "25"}
- host50 := &HostInfo{hostId: "50"}
- host75 := &HostInfo{hostId: "75"}
- tokens := []hostToken{
- {intToken(0), host0},
- {intToken(25), host25},
- {intToken(50), host50},
- {intToken(75), host75},
- }
- hosts := []*HostInfo{host0, host25, host50, host75}
- strat := &simpleStrategy{rf: 2}
- tokenReplicas := strat.replicaMap(&tokenRing{hosts: hosts, tokens: tokens})
- if len(tokenReplicas) != len(tokens) {
- t.Fatalf("expected replica map to have %d items but has %d", len(tokens), len(tokenReplicas))
- }
- for _, replicas := range tokenReplicas {
- if len(replicas.hosts) != strat.rf {
- t.Errorf("expected to have %d replicas got %d for token=%v", strat.rf, len(replicas.hosts), replicas.token)
- }
- }
- for i, token := range tokens {
- ht := tokenReplicas.replicasFor(token.token)
- if ht.token != token.token {
- t.Errorf("token %v not in replica map: %v", token, ht.hosts)
- }
- for j, replica := range ht.hosts {
- exp := tokens[(i+j)%len(tokens)].host
- if exp != replica {
- t.Errorf("expected host %v to be a replica of %v got %v", exp.hostId, token, replica.hostId)
- }
- }
- }
- }
- func TestPlacementStrategy_NetworkStrategy(t *testing.T) {
- var (
- hosts []*HostInfo
- tokens []hostToken
- )
- const (
- totalDCs = 3
- racksPerDC = 3
- hostsPerDC = 5
- )
- dcRing := make(map[string][]hostToken, totalDCs)
- for i := 0; i < totalDCs; i++ {
- var dcTokens []hostToken
- dc := fmt.Sprintf("dc%d", i+1)
- for j := 0; j < hostsPerDC; j++ {
- rack := fmt.Sprintf("rack%d", (j%racksPerDC)+1)
- h := &HostInfo{hostId: fmt.Sprintf("%s:%s:%d", dc, rack, j), dataCenter: dc, rack: rack}
- token := hostToken{
- token: orderedToken([]byte(h.hostId)),
- host: h,
- }
- tokens = append(tokens, token)
- dcTokens = append(dcTokens, token)
- hosts = append(hosts, h)
- }
- sort.Sort(&tokenRing{tokens: dcTokens})
- dcRing[dc] = dcTokens
- }
- if len(tokens) != hostsPerDC*totalDCs {
- t.Fatalf("expected %d tokens in the ring got %d", hostsPerDC*totalDCs, len(tokens))
- }
- sort.Sort(&tokenRing{tokens: tokens})
- strats := []*networkTopology{
- &networkTopology{
- dcs: map[string]int{
- "dc1": 1,
- "dc2": 2,
- "dc3": 3,
- },
- },
- &networkTopology{
- dcs: map[string]int{
- "dc2": 2,
- "dc3": 3,
- },
- },
- }
- for _, strat := range strats {
- var expReplicas int
- for _, rf := range strat.dcs {
- expReplicas += rf
- }
- tokenReplicas := strat.replicaMap(&tokenRing{hosts: hosts, tokens: tokens})
- if needTokens := hostsPerDC * len(strat.dcs); len(tokenReplicas) != needTokens {
- t.Fatalf("expected replica map to have %d items but has %d", needTokens, len(tokenReplicas))
- }
- if !sort.IsSorted(tokenReplicas) {
- t.Fatal("replica map was not sorted by token")
- }
- for token, replicas := range tokenReplicas {
- if len(replicas.hosts) != expReplicas {
- t.Fatalf("expected to have %d replicas got %d for token=%v", expReplicas, len(replicas.hosts), token)
- }
- }
- for dc, rf := range strat.dcs {
- dcTokens := dcRing[dc]
- for i, th := range dcTokens {
- token := th.token
- allReplicas := tokenReplicas.replicasFor(token)
- if allReplicas.token != token {
- t.Fatalf("token %v not in replica map", token)
- }
- var replicas []*HostInfo
- for _, replica := range allReplicas.hosts {
- if replica.dataCenter == dc {
- replicas = append(replicas, replica)
- }
- }
- if len(replicas) != rf {
- t.Fatalf("expected %d replicas in dc %q got %d", rf, dc, len(replicas))
- }
- var lastRack string
- for j, replica := range replicas {
- // expected is in the next rack
- var exp *HostInfo
- if lastRack == "" {
- // primary, first replica
- exp = dcTokens[(i+j)%len(dcTokens)].host
- } else {
- for k := 0; k < len(dcTokens); k++ {
- // walk around the ring from i + j to find the next host the
- // next rack
- p := (i + j + k) % len(dcTokens)
- h := dcTokens[p].host
- if h.rack != lastRack {
- exp = h
- break
- }
- }
- if exp.rack == lastRack {
- panic("no more racks")
- }
- }
- lastRack = replica.rack
- }
- }
- }
- }
- }
|