|
@@ -9,6 +9,7 @@ fn no_disruptive_rejoin() -> config::Result<()> {
|
|
|
const SERVERS: usize = 5;
|
|
const SERVERS: usize = 5;
|
|
|
let cfg = make_config!(SERVERS, false);
|
|
let cfg = make_config!(SERVERS, false);
|
|
|
defer!(cfg.cleanup());
|
|
defer!(cfg.cleanup());
|
|
|
|
|
+
|
|
|
let initial_leader = cfg.check_one_leader()?;
|
|
let initial_leader = cfg.check_one_leader()?;
|
|
|
cfg.one(100, SERVERS, false)?;
|
|
cfg.one(100, SERVERS, false)?;
|
|
|
let initial_term =
|
|
let initial_term =
|
|
@@ -48,3 +49,38 @@ fn no_disruptive_rejoin() -> config::Result<()> {
|
|
|
|
|
|
|
|
Ok(())
|
|
Ok(())
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+#[test]
|
|
|
|
|
+fn disruptive_liveness() -> config::Result<()> {
|
|
|
|
|
+ const SERVERS: usize = 5;
|
|
|
|
|
+ let cfg = make_config!(SERVERS, false);
|
|
|
|
|
+ defer!(cfg.cleanup());
|
|
|
|
|
+
|
|
|
|
|
+ let initial_leader = cfg.check_one_leader()?;
|
|
|
|
|
+ cfg.one(100, SERVERS, false)?;
|
|
|
|
|
+ cfg.check_terms()?.expect("Servers should agree on term");
|
|
|
|
|
+
|
|
|
|
|
+ // 3 <--> 2 4
|
|
|
|
|
+ // ^ ^
|
|
|
|
|
+ // | |
|
|
|
|
|
+ // | v
|
|
|
|
|
+ // -----> 1 <--> 0
|
|
|
|
|
+
|
|
|
|
|
+ // Disconnect 4
|
|
|
|
|
+ let disruptor = (initial_leader + 4) % SERVERS;
|
|
|
|
|
+ cfg.disconnect(disruptor);
|
|
|
|
|
+
|
|
|
|
|
+ // Disconnect (0, 2) and (0, 3)
|
|
|
|
|
+ cfg.disconnect_pair(initial_leader, (initial_leader + 2) % SERVERS);
|
|
|
|
|
+ cfg.disconnect_pair(initial_leader, (initial_leader + 3) % SERVERS);
|
|
|
|
|
+
|
|
|
|
|
+ sleep_election_timeouts(1);
|
|
|
|
|
+
|
|
|
|
|
+ let leader = cfg.check_one_leader()?;
|
|
|
|
|
+ cfg.one(200, 3, false)?;
|
|
|
|
|
+
|
|
|
|
|
+ assert_ne!(initial_leader, leader);
|
|
|
|
|
+ assert_ne!(disruptor, leader);
|
|
|
|
|
+
|
|
|
|
|
+ Ok(())
|
|
|
|
|
+}
|