Files
@ bdf284174817
Branch filter:
Location: CSY/reowolf/src/runtime2/tests/sync_failure.rs
bdf284174817
4.5 KiB
application/rls-services+xml
Update header in readme
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | // sync_failure.rs
//
// Various tests to ensure that failing components fail in a consistent way.
use super::*;
#[test]
fn test_local_sync_failure() {
// If the component exits cleanly, then the runtime exits cleanly, and the
// test will finish
const CODE: &'static str = "
primitive immediate_failure_inside_sync() {
u32[] only_allows_index_0 = { 1 };
while (true) sync { // note the infinite loop
auto value = only_allows_index_0[1];
}
}
primitive immediate_failure_outside_sync() {
u32[] only_allows_index_0 = { 1 };
auto never_gonna_get = only_allows_index_0[1];
while (true) sync {}
}
";
// let thing = TestTimer::new("local_sync_failure");
run_test_in_runtime(CODE, |api| {
api.create_connector("", "immediate_failure_outside_sync", ValueGroup::new_stack(Vec::new()))
.expect("create component");
api.create_connector("", "immediate_failure_inside_sync", ValueGroup::new_stack(Vec::new()))
.expect("create component");
})
}
const SHARED_SYNC_CODE: &'static str = "
enum Location { BeforeSync, AfterPut, AfterGet, AfterSync, Never }
primitive failing_at_location(in<bool> input, out<bool> output, Location loc) {
u32[] failure_array = {};
while (true) {
if (loc == Location::BeforeSync) failure_array[0];
sync {
put(output, true);
if (loc == Location::AfterPut) failure_array[0];
auto received = get(input);
assert(received);
if (loc == Location::AfterGet) failure_array[0];
}
if (loc == Location::AfterSync) failure_array[0];
}
}
composite constructor_pair_a(Location loc) {
channel output_a -> input_a;
channel output_b -> input_b;
new failing_at_location(input_b, output_a, loc);
new failing_at_location(input_a, output_b, Location::Never);
}
composite constructor_pair_b(Location loc) {
channel output_a -> input_a;
channel output_b -> input_b;
new failing_at_location(input_b, output_a, Location::Never);
new failing_at_location(input_a, output_b, loc);
}
composite constructor_ring(u32 ring_size, u32 fail_a, Location loc_a, u32 fail_b, Location loc_b) {
channel output_first -> input_old;
channel output_cur -> input_new;
u32 ring_index = 0;
while (ring_index < ring_size) {
auto cur_loc = Location::Never;
if (ring_index == fail_a) cur_loc = loc_a;
if (ring_index == fail_b) cur_loc = loc_b;
new failing_at_location(input_old, output_cur, cur_loc);
if (ring_index == ring_size - 2) {
// Don't create a new channel, join up the last one
output_cur = output_first;
input_old = input_new;
} else if (ring_index != ring_size - 1) {
channel output_fresh -> input_fresh;
input_old = input_new;
output_cur = output_fresh;
input_new = input_fresh;
}
ring_index += 1;
}
}
";
#[test]
fn test_shared_sync_failure_pair_variant_a() {
// One fails, the other one should somehow detect it and fail as well. This
// variant constructs the failing component first.
run_test_in_runtime(SHARED_SYNC_CODE, |api| {
for variant in 0..4 { // all `Location` enum variants, except `Never`.
// Create the channels
api.create_connector("", "constructor_pair_a", ValueGroup::new_stack(vec![
Value::Enum(variant)
])).expect("create connector");
}
})
}
#[test]
fn test_shared_sync_failure_pair_variant_b() {
// One fails, the other one should somehow detect it and fail as well. This
// variant constructs the successful component first.
run_test_in_runtime(SHARED_SYNC_CODE, |api| {
for variant in 0..4 {
api.create_connector("", "constructor_pair_b", ValueGroup::new_stack(vec![
Value::Enum(variant)
])).expect("create connector");
}
})
}
#[test]
fn test_shared_sync_failure_ring_variant_a() {
// Only one component in the ring should fail
const RING_SIZE: u32 = 4;
run_test_in_runtime(SHARED_SYNC_CODE, |api| {
for variant in 0..4 {
api.create_connector("", "constructor_ring", ValueGroup::new_stack(vec![
Value::UInt32(RING_SIZE),
Value::UInt32(RING_SIZE / 2), Value::Enum(variant), // fail "halfway" the ring
Value::UInt32(RING_SIZE), Value::Enum(0), // never occurs, index is equal to ring size
])).expect("create connector");
}
})
}
|