diff --git a/src/runtime2/tests/sync_failure.rs b/src/runtime2/tests/sync_failure.rs index f3acdabcf1fbbd962ce73e7fe41de47edde701db..ae6becc1f9226fcd4a2a1b3247d8f3c6027eedf0 100644 --- a/src/runtime2/tests/sync_failure.rs +++ b/src/runtime2/tests/sync_failure.rs @@ -33,41 +33,58 @@ fn test_local_sync_failure() { }) } -#[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. We intentionally have an - // infinite loop in the while condition because we need at least two loops - // for the last error to get picked up. - 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]; +const SHARED_SYNC_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); - } - "; +composite constructor_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); +} - run_test_in_runtime(CODE, |api| { +composite constructor_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); +}"; + +#[test] +fn test_shared_sync_failure_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", ValueGroup::new_stack(vec![ + api.create_connector("", "constructor_a", ValueGroup::new_stack(vec![ + Value::Enum(variant) + ])).expect("create connector"); + } + }) +} + +#[test] +fn test_shared_sync_failure_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_b", ValueGroup::new_stack(vec![ Value::Enum(variant) ])).expect("create connector"); }