package threadTest import ( "simple-kv-store/internal/nodes" "strconv" "testing" "time" ) func TestNormalReplication(t *testing.T) { n := 5 var peerIds []string for i := 0; i < n; i++ { peerIds = append(peerIds, strconv.Itoa(i + 1)) } // 结点启动 var quitCollections []chan struct{} var nodeCollections []*nodes.Node threadTransport := nodes.NewThreadTransport() for i := 0; i < n; i++ { n, quitChan := ExecuteStaticNodeI(strconv.Itoa(i + 1), false, peerIds, threadTransport) quitCollections = append(quitCollections, quitChan) nodeCollections = append(nodeCollections, n) } StopElectionReset(nodeCollections, quitCollections) // 通知所有node结束 defer func(){ for _, quitChan := range quitCollections { close(quitChan) } }() for i := 0; i < n; i++ { nodeCollections[i].State = nodes.Follower } nodeCollections[0].StartElection() time.Sleep(time.Second) CheckOneLeader(t, nodeCollections) CheckIsLeader(t, nodeCollections[0]) CheckTerm(t, nodeCollections[0], 2) for i := 0; i < 10; i++ { key := strconv.Itoa(i) newlog := nodes.LogEntry{Key: key, Value: "hello"} SendKvCall(&nodes.LogEntryCall{LogE: newlog}, nodeCollections[0]) } time.Sleep(time.Second) for i := 0; i < n; i++ { CheckLogNum(t, nodeCollections[i], 10) } } func TestParallelReplication(t *testing.T) { n := 5 var peerIds []string for i := 0; i < n; i++ { peerIds = append(peerIds, strconv.Itoa(i + 1)) } // 结点启动 var quitCollections []chan struct{} var nodeCollections []*nodes.Node threadTransport := nodes.NewThreadTransport() for i := 0; i < n; i++ { n, quitChan := ExecuteStaticNodeI(strconv.Itoa(i + 1), false, peerIds, threadTransport) quitCollections = append(quitCollections, quitChan) nodeCollections = append(nodeCollections, n) } StopElectionReset(nodeCollections, quitCollections) // 通知所有node结束 defer func(){ for _, quitChan := range quitCollections { close(quitChan) } }() for i := 0; i < n; i++ { nodeCollections[i].State = nodes.Follower } nodeCollections[0].StartElection() time.Sleep(time.Second) CheckOneLeader(t, nodeCollections) CheckIsLeader(t, nodeCollections[0]) CheckTerm(t, nodeCollections[0], 2) for i := 0; i < 10; i++ { key := strconv.Itoa(i) newlog := nodes.LogEntry{Key: key, Value: "hello"} go SendKvCall(&nodes.LogEntryCall{LogE: newlog}, nodeCollections[0]) go nodeCollections[0].BroadCastKV() } time.Sleep(time.Second) for i := 0; i < n; i++ { CheckLogNum(t, nodeCollections[i], 10) } } func TestFollowerLagging(t *testing.T) { n := 5 var peerIds []string for i := 0; i < n; i++ { peerIds = append(peerIds, strconv.Itoa(i + 1)) } // 结点启动 var quitCollections []chan struct{} var nodeCollections []*nodes.Node threadTransport := nodes.NewThreadTransport() for i := 0; i < n; i++ { n, quitChan := ExecuteStaticNodeI(strconv.Itoa(i + 1), false, peerIds, threadTransport) quitCollections = append(quitCollections, quitChan) nodeCollections = append(nodeCollections, n) } StopElectionReset(nodeCollections, quitCollections) // 通知所有node结束 defer func(){ for _, quitChan := range quitCollections { close(quitChan) } }() for i := 0; i < n; i++ { nodeCollections[i].State = nodes.Follower } nodeCollections[0].StartElection() time.Sleep(time.Second) CheckOneLeader(t, nodeCollections) CheckIsLeader(t, nodeCollections[0]) CheckTerm(t, nodeCollections[0], 2) close(quitCollections[1]) for i := 0; i < 10; i++ { key := strconv.Itoa(i) newlog := nodes.LogEntry{Key: key, Value: "hello"} go SendKvCall(&nodes.LogEntryCall{LogE: newlog}, nodeCollections[0]) } node, q := ExecuteStaticNodeI("2", true, peerIds, threadTransport) quitCollections[1] = q nodeCollections[1] = node nodeCollections[1].State = nodes.Follower StopElectionReset(nodeCollections[1:2], quitCollections[1:2]) time.Sleep(time.Second) for i := 0; i < n; i++ { CheckLogNum(t, nodeCollections[i], 10) } }