persist_tests.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #[macro_use]
  2. extern crate anyhow;
  3. extern crate bytes;
  4. extern crate labrpc;
  5. extern crate ruaft;
  6. use rand::{thread_rng, Rng};
  7. mod config;
  8. #[test]
  9. fn persist() -> config::Result<()> {
  10. const SERVERS: usize = 5;
  11. let cfg = config::make_config(SERVERS, false);
  12. let _guard = cfg.deferred_cleanup();
  13. cfg.begin("Test (2C): basic persistence");
  14. cfg.one(11, SERVERS, true)?;
  15. // crash and re-start all
  16. for i in 0..SERVERS {
  17. cfg.start1(i)?;
  18. }
  19. for i in 0..SERVERS {
  20. cfg.disconnect(i);
  21. cfg.connect(i);
  22. }
  23. cfg.one(12, SERVERS, true)?;
  24. let leader1 = cfg.check_one_leader()?;
  25. cfg.disconnect(leader1);
  26. cfg.start1(leader1)?;
  27. cfg.connect(leader1);
  28. cfg.one(13, SERVERS, true)?;
  29. let leader2 = cfg.check_one_leader()?;
  30. cfg.disconnect(leader2);
  31. cfg.one(14, SERVERS - 1, true)?;
  32. cfg.start1(leader2)?;
  33. cfg.connect(leader2);
  34. // wait for leader2 to join before killing i3
  35. cfg.wait(4, SERVERS, None)?;
  36. let i3 = (cfg.check_one_leader()? + 1) % SERVERS;
  37. cfg.disconnect(i3);
  38. cfg.one(15, SERVERS - 1, true)?;
  39. cfg.start1(i3)?;
  40. cfg.connect(i3);
  41. cfg.one(16, SERVERS, true)?;
  42. cfg.end();
  43. drop(_guard);
  44. Ok(())
  45. }
  46. #[test]
  47. fn persist2() -> config::Result<()> {
  48. const SERVERS: usize = 5;
  49. let cfg = config::make_config(SERVERS, false);
  50. let _guard = cfg.deferred_cleanup();
  51. cfg.begin("Test (2C): more persistence");
  52. let mut index = 1;
  53. for _ in 0..5 {
  54. cfg.one(10 + index, SERVERS, true)?;
  55. index += 1;
  56. let leader1 = cfg.check_one_leader()?;
  57. cfg.disconnect((leader1 + 1) % SERVERS);
  58. cfg.disconnect((leader1 + 2) % SERVERS);
  59. cfg.one(10 + index, SERVERS - 2, true)?;
  60. index += 1;
  61. cfg.disconnect((leader1 + 0) % SERVERS);
  62. cfg.disconnect((leader1 + 3) % SERVERS);
  63. cfg.disconnect((leader1 + 4) % SERVERS);
  64. cfg.start1((leader1 + 1) % SERVERS)?;
  65. cfg.start1((leader1 + 2) % SERVERS)?;
  66. cfg.connect((leader1 + 1) % SERVERS);
  67. cfg.connect((leader1 + 2) % SERVERS);
  68. config::sleep_election_timeouts(1);
  69. cfg.start1((leader1 + 3) % SERVERS)?;
  70. cfg.connect((leader1 + 3) % SERVERS);
  71. cfg.one(10 + index, SERVERS - 2, true)?;
  72. index += 1;
  73. cfg.connect((leader1 + 4) % SERVERS);
  74. cfg.connect((leader1 + 0) % SERVERS);
  75. }
  76. cfg.one(1000, SERVERS, true)?;
  77. cfg.end();
  78. drop(_guard);
  79. Ok(())
  80. }
  81. #[test]
  82. fn persist3() -> config::Result<()> {
  83. const SERVERS: usize = 3;
  84. let cfg = config::make_config(SERVERS, false);
  85. let _guard = cfg.deferred_cleanup();
  86. cfg.begin(
  87. "Test (2C): partitioned leader and one follower crash, leader restarts",
  88. );
  89. cfg.one(101, 3, true)?;
  90. let leader = cfg.check_one_leader()?;
  91. cfg.disconnect((leader + 2) % SERVERS);
  92. cfg.one(102, 2, true)?;
  93. cfg.crash1((leader + 0) % SERVERS);
  94. cfg.crash1((leader + 1) % SERVERS);
  95. cfg.connect((leader + 2) % SERVERS);
  96. cfg.start1((leader + 0) % SERVERS)?;
  97. cfg.connect((leader + 0) % SERVERS);
  98. cfg.one(103, 2, true)?;
  99. cfg.start1((leader + 1) % SERVERS)?;
  100. cfg.connect((leader + 1) % SERVERS);
  101. cfg.one(104, SERVERS, true)?;
  102. drop(_guard);
  103. Ok(())
  104. }
  105. #[test]
  106. fn figure8() -> config::Result<()> {
  107. const SERVERS: usize = 5;
  108. let cfg = config::make_config(SERVERS, false);
  109. let _guard = cfg.deferred_cleanup();
  110. cfg.begin("Test (2C): Figure 8");
  111. cfg.one(thread_rng().gen(), 1, true)?;
  112. let mut nup = SERVERS;
  113. for _ in 0..1000 {
  114. let mut leader = None;
  115. for i in 0..SERVERS {
  116. if cfg.is_server_alive(i) {
  117. if let Some(_) = cfg.leader_start(i, thread_rng().gen()) {
  118. leader = Some(i);
  119. }
  120. }
  121. }
  122. let millis_upper = if thread_rng().gen_ratio(100, 1000) {
  123. config::LONG_ELECTION_TIMEOUT_MILLIS >> 1
  124. } else {
  125. // Magic number 13?
  126. 13
  127. };
  128. let millis = thread_rng().gen_range(0, millis_upper);
  129. config::sleep_millis(millis);
  130. if let Some(leader) = leader {
  131. cfg.crash1(leader);
  132. nup -= 1;
  133. }
  134. if nup < 3 {
  135. let index = thread_rng().gen_range(0, SERVERS);
  136. if !cfg.is_server_alive(index) {
  137. cfg.start1(index)?;
  138. cfg.connect(index);
  139. nup += 1
  140. }
  141. }
  142. }
  143. for index in 0..SERVERS {
  144. if !cfg.is_server_alive(index) {
  145. cfg.start1(index)?;
  146. cfg.connect(index);
  147. }
  148. }
  149. cfg.one(thread_rng().gen(), SERVERS, true)?;
  150. cfg.end();
  151. drop(_guard);
  152. Ok(())
  153. }