about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBen Blum <bblum@andrew.cmu.edu>2012-07-18 21:57:29 -0400
committerBen Blum <bblum@andrew.cmu.edu>2012-07-18 21:57:56 -0400
commit22f492ab092b6d4948a69eb20037a7409c6119d3 (patch)
tree544aae3c2a22ff8dd88cb32586933e2c83e47912 /src
parent20831d394ac5488ba28cd0370d7ec03cd908fcae (diff)
downloadrust-22f492ab092b6d4948a69eb20037a7409c6119d3.tar.gz
rust-22f492ab092b6d4948a69eb20037a7409c6119d3.zip
Linked failure: add {un,}linked {un,}parented fail-{up,down} tests.
Diffstat (limited to 'src')
-rw-r--r--src/libcore/task.rs77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/libcore/task.rs b/src/libcore/task.rs
index 3f7f855ee94..69ea441ecfb 100644
--- a/src/libcore/task.rs
+++ b/src/libcore/task.rs
@@ -1153,6 +1153,83 @@ fn test_spawn_raw_unsupervise() {
     }
 }
 
+// The following 8 tests test the following 2^3 combinations:
+// {un,}linked {un,}supervised failure propagation {up,down}wards.
+
+#[test] #[ignore(cfg(windows))]
+fn test_spawn_unlinked_unsup_no_fail_down() { // grandchild sends on a port
+    let po = comm::port();
+    let ch = comm::chan(po);
+    let builder = task::builder();
+    task::unsupervise(builder);
+    do task::run(builder) {
+        let builder = task::builder();
+        task::unsupervise(builder);
+        do task::run(builder) {
+            // Give middle task a chance to fail-but-not-kill-us.
+            for iter::repeat(8192) { task::yield(); }
+            comm::send(ch, ()); // If killed first, grandparent hangs.
+        }
+        fail; // Shouldn't kill either (grand)parent or (grand)child.
+    }
+    comm::recv(po);
+}
+#[test] #[ignore(cfg(windows))]
+fn test_spawn_unlinked_unsup_no_fail_up() { // child unlinked fails
+    let builder = task::builder();
+    task::unsupervise(builder);
+    do task::run(builder) { fail; }
+}
+#[test] #[ignore(cfg(windows))]
+fn test_spawn_unlinked_sup_no_fail_up() { // child unlinked fails
+    let builder = task::builder();
+    task::unsupervise(builder);
+    task::parent(builder);
+    do task::run(builder) { fail; }
+    // Give child a chance to fail-but-not-kill-us.
+    for iter::repeat(8192) { task::yield(); }
+}
+#[test] #[should_fail] #[ignore(cfg(windows))]
+fn test_spawn_unlinked_sup_fail_down() {
+    let builder = task::builder();
+    task::unsupervise(builder);
+    task::parent(builder);
+    do task::run(builder) { loop { task::yield(); } }
+    fail; // Shouldn't leave a child hanging around.
+}
+
+#[test] #[should_fail] #[ignore(cfg(windows))]
+fn test_spawn_linked_sup_fail_up() { // child fails; parent fails
+    let po = comm::port::<()>();
+    let _ch = comm::chan(po);
+    let builder = task::builder();
+    task::parent(builder);
+    // Unidirectional "parenting" shouldn't override bidirectional linked.
+    do task::run(builder) { fail; }
+    comm::recv(po); // We should get punted awake
+}
+#[test] #[should_fail] #[ignore(cfg(windows))]
+fn test_spawn_linked_sup_fail_down() { // parent fails; child fails
+    let builder = task::builder();
+    task::parent(builder);
+    do task::run(builder) { loop { task::yield(); } }
+    fail; // *both* mechanisms would be wrong if this didn't kill the child...
+}
+#[test] #[should_fail] #[ignore(cfg(windows))]
+fn test_spawn_linked_unsup_fail_up() { // child fails; parent fails
+    let po = comm::port::<()>();
+    let _ch = comm::chan(po);
+    // Default options are to spawn linked & unsupervised.
+    do task::spawn { fail; }
+    comm::recv(po); // We should get punted awake
+}
+#[test] #[should_fail] #[ignore(cfg(windows))]
+fn test_spawn_linked_unsup_fail_down() { // parent fails; child fails
+    // Default options are to spawn linked & unsupervised.
+    do task::spawn { loop { task::yield(); } }
+    fail;
+}
+
 #[test]
 #[ignore(cfg(windows))]
 fn test_spawn_raw_notify() {