Test the scenarios described in Figure 8 of the extended Raft paper. Each iteration asks a leader, if there is one, to insert a command in the Raft log. If there is a leader, that leader will fail quickly with a high probability (perhaps without committing the command), or crash after a while with
(t *testing.T)
| 716 | // haven't been committed yet. |
| 717 | // |
| 718 | func TestFigure82C(t *testing.T) { |
| 719 | servers := 5 |
| 720 | cfg := make_config(t, servers, false, false) |
| 721 | defer cfg.cleanup() |
| 722 | |
| 723 | cfg.begin("Test (2C): Figure 8") |
| 724 | |
| 725 | cfg.one(rand.Int(), 1, true) |
| 726 | |
| 727 | nup := servers |
| 728 | for iters := 0; iters < 1000; iters++ { |
| 729 | leader := -1 |
| 730 | for i := 0; i < servers; i++ { |
| 731 | if cfg.rafts[i] != nil { |
| 732 | _, _, ok := cfg.rafts[i].Start(rand.Int()) |
| 733 | if ok { |
| 734 | leader = i |
| 735 | } |
| 736 | } |
| 737 | } |
| 738 | |
| 739 | if (rand.Int() % 1000) < 100 { |
| 740 | ms := rand.Int63() % (int64(RaftElectionTimeout/time.Millisecond) / 2) |
| 741 | time.Sleep(time.Duration(ms) * time.Millisecond) |
| 742 | } else { |
| 743 | ms := (rand.Int63() % 13) |
| 744 | time.Sleep(time.Duration(ms) * time.Millisecond) |
| 745 | } |
| 746 | |
| 747 | if leader != -1 { |
| 748 | cfg.crash1(leader) |
| 749 | nup -= 1 |
| 750 | } |
| 751 | |
| 752 | if nup < 3 { |
| 753 | s := rand.Int() % servers |
| 754 | if cfg.rafts[s] == nil { |
| 755 | cfg.start1(s, cfg.applier) |
| 756 | cfg.connect(s) |
| 757 | nup += 1 |
| 758 | } |
| 759 | } |
| 760 | } |
| 761 | |
| 762 | for i := 0; i < servers; i++ { |
| 763 | if cfg.rafts[i] == nil { |
| 764 | cfg.start1(i, cfg.applier) |
| 765 | cfg.connect(i) |
| 766 | } |
| 767 | } |
| 768 | |
| 769 | cfg.one(rand.Int(), servers, true) |
| 770 | |
| 771 | cfg.end() |
| 772 | } |
| 773 | |
| 774 | func TestUnreliableAgree2C(t *testing.T) { |
| 775 | servers := 5 |