diff --git a/src/runtime2/tests/sync_failure.rs b/src/runtime2/tests/sync_failure.rs new file mode 100644 index 0000000000000000000000000000000000000000..392b8a22fa18fbf5c6fe934059189f7bfd84bea9 --- /dev/null +++ b/src/runtime2/tests/sync_failure.rs @@ -0,0 +1,73 @@ +// 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"); + }) +} + +#[test] +fn test_shared_sync_failure() { + // Same as above. One of the components should fail, the other should follow + // suit because it cannot complete a sync round. + const CODE: &'static str = " + enum Location { BeforeSync, AfterPut, AfterGet, AfterSync, Never } + primitive failing_at_location(in input, out 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(Location loc) { + channel output_a -> input_a; + channel output_b -> input_b; + new failing_at_location(input_a, output_b, Location::Never); + new failing_at_location(input_b, output_a, loc); + } + "; + + run_test_in_runtime(CODE, |api| { + for variant in 0..1 { + // Create the channels + api.create_connector("", "constructor", ValueGroup::new_stack(vec![ + Value::Enum(variant) + ])).expect("create connector"); + } + }) +} \ No newline at end of file