Browse Source

Add the last agreement test.

Jing Yang 5 years ago
parent
commit
274bd0cdc8
2 changed files with 90 additions and 5 deletions
  1. 86 2
      tests/agreement_tests.rs
  2. 4 3
      tests/election_tests.rs

+ 86 - 2
tests/agreement_tests.rs

@@ -1,7 +1,9 @@
-extern crate labrpc;
-extern crate ruaft;
 #[macro_use]
 extern crate anyhow;
+extern crate labrpc;
+extern crate ruaft;
+
+use rand::{thread_rng, Rng};
 
 mod config;
 
@@ -24,6 +26,7 @@ fn basic_agreement() -> config::Result<()> {
         );
     }
 
+    drop(_guard);
     Ok(())
 }
 
@@ -58,6 +61,7 @@ fn fail_agree() -> config::Result<()> {
 
     cfg.end();
 
+    drop(_guard);
     Ok(())
 }
 
@@ -108,6 +112,7 @@ fn fail_no_agree() -> config::Result<()> {
 
     cfg.end();
 
+    drop(_guard);
     Ok(())
 }
 
@@ -152,3 +157,82 @@ fn rejoin() -> config::Result<()> {
     drop(_guard);
     Ok(())
 }
+
+#[test]
+fn backup() -> config::Result<()> {
+    const SERVERS: usize = 3;
+    let cfg = config::make_config(SERVERS, false);
+    let _guard = cfg.deferred_cleanup();
+
+    cfg.begin(
+        "Test (2B): leader backs up quickly over incorrect follower logs",
+    );
+
+    cfg.one(thread_rng().gen(), SERVERS, true)?;
+
+    // put leader and one follower in a partition
+    let leader1 = cfg.check_one_leader()?;
+    cfg.disconnect((leader1 + 2) % SERVERS);
+    cfg.disconnect((leader1 + 3) % SERVERS);
+    cfg.disconnect((leader1 + 4) % SERVERS);
+
+    // submit lots of commands that won't commit
+    for _ in 0..SERVERS {
+        cfg.leader_start(leader1, thread_rng().gen());
+    }
+
+    config::sleep_election_timeouts(2);
+
+    cfg.disconnect((leader1 + 0) % SERVERS);
+    cfg.disconnect((leader1 + 1) % SERVERS);
+
+    // allow other partition to recover
+    cfg.connect((leader1 + 2) % SERVERS);
+    cfg.connect((leader1 + 3) % SERVERS);
+    cfg.connect((leader1 + 4) % SERVERS);
+
+    // lots of successful commands to new group.
+    for _ in 0..50 {
+        cfg.one(thread_rng().gen(), 3, true)?;
+    }
+
+    // now another partitioned leader and one follower
+    let leader2 = cfg.check_one_leader()?;
+    let mut other = (leader1 + 2) % SERVERS;
+    if leader2 == other {
+        other = (leader2 + 1) % SERVERS;
+    }
+    cfg.disconnect(other);
+
+    // lots more commands that won't commit
+    for _ in 0..50 {
+        cfg.leader_start(leader2, thread_rng().gen());
+    }
+
+    config::sleep_election_timeouts(2);
+
+    // bring original leader back to life,
+    for i in 0..SERVERS {
+        cfg.disconnect(i);
+    }
+
+    cfg.connect((leader1 + 0) % SERVERS);
+    cfg.connect((leader1 + 1) % SERVERS);
+    cfg.connect(other);
+
+    // lots of successful commands to new group.
+    for _ in 0..50 {
+        cfg.one(thread_rng().gen(), 3, true)?;
+    }
+
+    // now everyone
+    for i in 0..SERVERS {
+        cfg.connect(i);
+    }
+    cfg.one(thread_rng().gen(), SERVERS, true)?;
+
+    cfg.end();
+
+    drop(_guard);
+    Ok(())
+}

+ 4 - 3
tests/election_tests.rs

@@ -1,7 +1,7 @@
-extern crate labrpc;
-extern crate ruaft;
 #[macro_use]
 extern crate anyhow;
+extern crate labrpc;
+extern crate ruaft;
 
 mod config;
 
@@ -38,7 +38,7 @@ fn initial_election() -> config::Result<()> {
 fn re_election() -> config::Result<()> {
     const SERVERS: usize = 3;
     let cfg = config::make_config(SERVERS, false);
-    let _guard = ruaft::utils::DropGuard::new(|| cfg.cleanup());
+    let _guard = cfg.deferred_cleanup();
 
     cfg.begin("Test (2A): election after network failure");
 
@@ -64,5 +64,6 @@ fn re_election() -> config::Result<()> {
 
     cfg.end();
 
+    drop(_guard);
     Ok(())
 }