Procházet zdrojové kódy

Add two more tests: CPU usage is really high.

Jing Yang před 5 roky
rodič
revize
7914cb3efa
2 změnil soubory, kde provedl 102 přidání a 1 odebrání
  1. 5 1
      tests/config/mod.rs
  2. 97 0
      tests/persist_tests.rs

+ 5 - 1
tests/config/mod.rs

@@ -327,6 +327,10 @@ impl Config {
             .unwrap()
     }
 
+    pub fn is_server_alive(&self, index: usize) -> bool {
+        self.state.lock().rafts[index].is_some()
+    }
+
     pub fn total_rpcs(&self) -> usize {
         unlock(&self.network).get_total_rpc_count()
     }
@@ -447,7 +451,7 @@ pub fn sleep_millis(mills: u64) {
     std::thread::sleep(std::time::Duration::from_millis(mills))
 }
 
-const LONG_ELECTION_TIMEOUT_MILLIS: u64 = 1000;
+pub const LONG_ELECTION_TIMEOUT_MILLIS: u64 = 1000;
 pub fn sleep_election_timeouts(count: u64) {
     sleep_millis(LONG_ELECTION_TIMEOUT_MILLIS * count)
 }

+ 97 - 0
tests/persist_tests.rs

@@ -4,6 +4,8 @@ extern crate bytes;
 extern crate labrpc;
 extern crate ruaft;
 
+use rand::{thread_rng, Rng};
+
 mod config;
 
 #[test]
@@ -108,3 +110,98 @@ fn persist2() -> config::Result<()> {
     drop(_guard);
     Ok(())
 }
+
+#[test]
+fn persist3() -> config::Result<()> {
+    const SERVERS: usize = 3;
+    let cfg = config::make_config(SERVERS, false);
+    let _guard = cfg.deferred_cleanup();
+
+    cfg.begin(
+        "Test (2C): partitioned leader and one follower crash, leader restarts",
+    );
+
+    cfg.one(101, 3, true)?;
+
+    let leader = cfg.check_one_leader()?;
+    cfg.disconnect((leader + 2) % SERVERS);
+
+    cfg.one(102, 2, true)?;
+
+    cfg.crash1((leader + 0) % SERVERS);
+    cfg.crash1((leader + 1) % SERVERS);
+    cfg.connect((leader + 2) % SERVERS);
+    cfg.start1((leader + 0) % SERVERS)?;
+    cfg.connect((leader + 0) % SERVERS);
+
+    cfg.one(103, 2, true)?;
+
+    cfg.start1((leader + 1) % SERVERS)?;
+    cfg.connect((leader + 1) % SERVERS);
+
+    cfg.one(104, SERVERS, true)?;
+
+    drop(_guard);
+
+    Ok(())
+}
+
+#[test]
+fn figure8() -> config::Result<()> {
+    const SERVERS: usize = 5;
+    let cfg = config::make_config(SERVERS, false);
+    let _guard = cfg.deferred_cleanup();
+
+    cfg.begin("Test (2C): Figure 8");
+
+    cfg.one(thread_rng().gen(), 1, true)?;
+
+    let mut nup = SERVERS;
+    for _ in 0..1000 {
+        let mut leader = None;
+        for i in 0..SERVERS {
+            if cfg.is_server_alive(i) {
+                if let Some(_) = cfg.leader_start(i, thread_rng().gen()) {
+                    leader = Some(i);
+                }
+            }
+        }
+
+        let millis_upper = if thread_rng().gen_ratio(100, 1000) {
+            config::LONG_ELECTION_TIMEOUT_MILLIS >> 1
+        } else {
+            // Magic number 13?
+            13
+        };
+        let millis = thread_rng().gen_range(0, millis_upper);
+        config::sleep_millis(millis);
+
+        if let Some(leader) = leader {
+            cfg.crash1(leader);
+            nup -= 1;
+        }
+
+        if nup < 3 {
+            let index = thread_rng().gen_range(0, SERVERS);
+            if !cfg.is_server_alive(index) {
+                cfg.start1(index)?;
+                cfg.connect(index);
+                nup += 1
+            }
+        }
+    }
+
+    for index in 0..SERVERS {
+        if !cfg.is_server_alive(index) {
+            cfg.start1(index)?;
+            cfg.connect(index);
+        }
+    }
+
+    cfg.one(thread_rng().gen(), SERVERS, true)?;
+
+    cfg.end();
+
+    drop(_guard);
+    Ok(())
+}