소스 검색

test(ThingBuf): quick mpsc-y loom test

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Eliza Weisman 3 년 전
부모
커밋
3a8a13c7d2
1개의 변경된 파일65개의 추가작업 그리고 15개의 파일을 삭제
  1. 65 15
      src/tests.rs

+ 65 - 15
src/tests.rs

@@ -3,29 +3,79 @@ use crate::loom::{self, thread};
 use std::sync::Arc;
 
 #[test]
+fn push_many_mpsc() {
+    const T1_VALS: &[&str] = &["alice", "bob", "charlie"];
+    const T2_VALS: &[&str] = &["dave", "ellen", "francis"];
+
+    fn producer(vals: &'static [&'static str], q: &Arc<ThingBuf<String>>) -> impl FnOnce() {
+        let q = q.clone();
+        move || {
+            for &val in vals {
+                if let Ok(mut r) = test_dbg!(q.push_ref()) {
+                    r.with_mut(|r| r.push_str(val));
+                } else {
+                    return;
+                }
+            }
+        }
+    }
+
+    loom::model(|| {
+        let q = Arc::new(ThingBuf::new(6));
+
+        let t1 = thread::spawn(producer(T1_VALS, &q));
+        let t2 = thread::spawn(producer(T2_VALS, &q));
+
+        let mut all_vals = Vec::new();
+
+        while Arc::strong_count(&q) > 1 {
+            if let Some(r) = q.pop_ref() {
+                r.with(|val| all_vals.push(val.to_string()));
+            }
+            thread::yield_now();
+        }
+
+        t1.join().unwrap();
+        t2.join().unwrap();
+
+        while let Some(r) = test_dbg!(q.pop_ref()) {
+            r.with(|val| all_vals.push(val.to_string()));
+        }
+
+        test_dbg!(&all_vals);
+        for &val in T1_VALS.iter().chain(T2_VALS.iter()) {
+            assert!(all_vals.contains(&test_dbg!(val).to_string()))
+        }
+
+        assert_eq!(all_vals.len(), T1_VALS.len() + T2_VALS.len());
+    })
+}
+
+#[test]
+#[ignore] // this takes about a million years to run
 fn linearizable() {
     const THREADS: usize = 4;
 
-    fn thread(i: usize, q: Arc<ThingBuf<usize>>) {
-        while q
-            .push_ref()
-            .map(|mut r| r.with_mut(|val| *val = i))
-            .is_err()
-        {}
+    fn thread(i: usize, q: &Arc<ThingBuf<usize>>) -> impl FnOnce() {
+        let q = q.clone();
+        move || {
+            while q
+                .push_ref()
+                .map(|mut r| r.with_mut(|val| *val = i))
+                .is_err()
+            {}
 
-        if let Some(mut r) = q.pop_ref() {
-            r.with_mut(|val| *val = 0);
+            if let Some(mut r) = q.pop_ref() {
+                r.with_mut(|val| *val = 0);
+            }
         }
     }
     loom::model(|| {
         let q = Arc::new(ThingBuf::new(THREADS));
-        let q1 = q.clone();
-        let q2 = q.clone();
-        let q3 = q.clone();
-        let t1 = thread::spawn(move || thread(1, q1));
-        let t2 = thread::spawn(move || thread(2, q2));
-        let t3 = thread::spawn(move || thread(3, q3));
-        thread(4, q);
+        let t1 = thread::spawn(thread(1, &q));
+        let t2 = thread::spawn(thread(2, &q));
+        let t3 = thread::spawn(thread(3, &q));
+        thread(4, &q)();
         t1.join().expect("thread 1 panicked!");
         t2.join().expect("thread 2 panicked!");
         t3.join().expect("thread 3 panicked!");