Files @ dd4e6a5314f7
Branch filter:

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

dd4e6a5314f7 2.6 KiB application/rls-services+xml Show Annotation Show as Raw Download as Raw
MH
WIP on more failure fixing
// 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. 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<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(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..4 { // all `Location` enum variants, except `Never`.
            // Create the channels
            api.create_connector("", "constructor", ValueGroup::new_stack(vec![
                Value::Enum(variant)
            ])).expect("create connector");
        }
    })
}