Kaynağa Gözat

Add the unreliable test.

Jing Yang 5 yıl önce
ebeveyn
işleme
2f41f782ba
2 değiştirilmiş dosya ile 52 ekleme ve 11 silme
  1. 15 11
      tests/config/mod.rs
  2. 37 0
      tests/persist_tests.rs

+ 15 - 11
tests/config/mod.rs

@@ -22,6 +22,7 @@ struct LogState {
     committed_logs: Vec<Vec<i32>>,
     results: Vec<Result<()>>,
     max_index: usize,
+    saved: Vec<Arc<persister::Persister>>,
 }
 
 pub struct Config {
@@ -29,7 +30,6 @@ pub struct Config {
     server_count: usize,
     state: Mutex<ConfigState>,
     log: Arc<Mutex<LogState>>,
-    saved: std::cell::RefCell<Vec<Arc<persister::Persister>>>,
 }
 
 impl Config {
@@ -274,13 +274,14 @@ impl Config {
             let mut state = self.state.lock();
             state.rafts[index].take()
         };
-        let mut saved = self.saved.borrow_mut();
-        let data = saved[index].read_state();
+
+        let mut log = self.log.lock();
+        let data = log.saved[index].read_state();
         if let Some(raft) = raft {
             raft.kill();
         }
-        saved[index] = Arc::new(persister::Persister::new());
-        saved[index].save_state(data);
+        log.saved[index] = Arc::new(persister::Persister::new());
+        log.saved[index].save_state(data);
     }
 
     pub fn start1(&self, index: usize) -> Result<()> {
@@ -298,7 +299,7 @@ impl Config {
                 )))
             }
         }
-        let persister = self.saved.borrow()[index].clone();
+        let persister = self.log.lock().saved[index].clone();
 
         let log_clone = self.log.clone();
         let raft =
@@ -335,6 +336,10 @@ impl Config {
         unlock(&self.network).get_total_rpc_count()
     }
 
+    pub fn set_unreliable(&self, yes: bool) {
+        unlock(&self.network).set_reliable(!yes);
+    }
+
     pub fn end(&self) {}
 
     pub fn cleanup(&self) {
@@ -421,23 +426,22 @@ pub fn make_config(server_count: usize, unreliable: bool) -> Config {
         rafts: vec![None; server_count],
         connected: vec![true; server_count],
     });
+
+    let mut saved = vec![];
+    saved.resize_with(server_count, || Arc::new(persister::Persister::new()));
     let log = Arc::new(Mutex::new(LogState {
         committed_logs: vec![vec![]; server_count],
         results: vec![],
         max_index: 0,
+        saved,
     }));
     log.lock().results.resize_with(server_count, || Ok(()));
 
-    let saved = std::cell::RefCell::new(vec![]);
-    saved
-        .borrow_mut()
-        .resize_with(server_count, || Arc::new(persister::Persister::new()));
     let cfg = Config {
         network,
         server_count,
         state,
         log,
-        saved,
     };
 
     for i in 0..server_count {

+ 37 - 0
tests/persist_tests.rs

@@ -5,6 +5,7 @@ extern crate labrpc;
 extern crate ruaft;
 
 use rand::{thread_rng, Rng};
+use std::sync::Arc;
 
 mod config;
 
@@ -205,3 +206,39 @@ fn figure8() -> config::Result<()> {
     drop(_guard);
     Ok(())
 }
+
+#[test]
+fn unreliable_agree() -> config::Result<()> {
+    const SERVERS: usize = 5;
+    let cfg = Arc::new(config::make_config(SERVERS, true));
+    let guard_cfg = cfg.clone();
+    let _guard = guard_cfg.deferred_cleanup();
+
+    cfg.begin("Test (2C): unreliable agreement");
+
+    let mut handles = vec![];
+    let cfg = Arc::new(cfg);
+    for iters in 1..50 {
+        for j in 0..4 {
+            let cfg = cfg.clone();
+            let handle =
+                std::thread::spawn(move || cfg.one(100 * iters + j, 1, true));
+            handles.push(handle);
+        }
+
+        cfg.one(iters, 1, true)?;
+    }
+
+    cfg.set_unreliable(false);
+
+    for handle in handles {
+        handle.join().expect("Thread join should not fail")?;
+    }
+
+    cfg.one(100, SERVERS, true)?;
+
+    cfg.end();
+
+    drop(_guard);
+    Ok(())
+}