Files @ 2058a2c1bf4c
Branch filter:

Location: CSY/reowolf/src/runtime2/tests/sync_failure.rs

2058a2c1bf4c 3.1 KiB application/rls-services+xml Show Annotation Show as Raw Download as Raw
MH
One more bug fixed, one very rare one still pending
// 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_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_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_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");
        }
    })
}