Files @ a43d61913724
Branch filter:

Location: CSY/reowolf/src/runtime2/tests/mod.rs - annotation

a43d61913724 4.1 KiB application/rls-services+xml Show Source Show as Raw Download as Raw
MH
prepare for debugging
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
ff6ade8b8097
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
f4f12a71e2e2
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
665aa326769e
ff6ade8b8097
use std::sync::Arc;

use super::runtime::*;
use crate::ProtocolDescription;
use crate::protocol::eval::*;

#[test]
fn test_single_message() {
    // Simple test were we have a `putter` component, which will simply send a
    // single message (a boolean), and a `getter` component, which will receive
    // that message.
    // We will write this behaviour in the various ways that the language
    // currently allows. We will cheat a bit by peeking into the runtime to make
    // sure that the getter actually received the message.
    // TODO: Expose ports to a "native application"

    fn check_store_bool(value: &Value, expected: bool) {
        if let Value::Bool(value) = value {
            assert_eq!(*value, expected);
        } else {
            assert!(false);
        }
    }

    fn run_putter_getter(code: &[u8]) {
        // Compile code
        let pd = ProtocolDescription::parse(code)
            .expect("code successfully compiles");
        let pd = Arc::new(pd);

        // Construct runtime and the appropriate ports and connectors
        let mut rt = Runtime::new(pd);
        let (put_port, get_port) = rt.add_channel();

        let mut put_args = ValueGroup::new_stack(vec![
            put_port,
        ]);
        rt.add_component("", "putter", put_args)
            .expect("'putter' component created");

        let mut get_args = ValueGroup::new_stack(vec![
            get_port,
        ]);
        rt.add_component("", "getter", get_args)
            .expect("'getter' component created");

        // Run until completion
        rt.run();

        // Check for success (the 'received' and 'did_receive" flags)
        let getter_component = rt.connectors.get(&1).unwrap();
        let branch = &getter_component.branches[0];
        assert_eq!(branch.branch_state, BranchState::Finished);

        // Note: with the stack structure of the store, the first entry is the
        // "previous stack pos" and the second one is the input port passed to
        // the procedure. Hence the third/fourth entries are the boolean
        // variables on the stack.
        check_store_bool(&branch.code_state.prompt.store.stack[2], true);
        check_store_bool(&branch.code_state.prompt.store.stack[3], true);
    }

    // Without `fires()`, just a single valid behaviour
    run_putter_getter(
        b"primitive putter(out<bool> put_here) {
            synchronous {
                put(put_here, true);
            }
        }

        primitive getter(in<bool> get_here) {
            bool received = false;
            bool did_receive = false;

            synchronous {
                received = get(get_here);
                if (received) {
                    print(\"value was 'true'\");
                } else {
                    print(\"value was 'false'\");
                }
                did_receive = true;
            }
        }");

    // With `fires()`, but eliminating on the putter side
    run_putter_getter(
        b"primitive putter(out<bool> put_here) {
            synchronous {
                if (!fires(put_here)) {
                    assert(false);
                } else {
                    put(put_here, true);
                }
            }
        }

        primitive getter(in<bool> get_here) {
            bool received = false; bool did_receive = false;
            synchronous {
                if (fires(get_here)) {
                    received = get(get_here);
                    did_receive = true;
                }
            }
        }");

    // With `fires()`, but eliminating on the getter side
    run_putter_getter(
        b"primitive putter(out<bool> put_here) {
            synchronous {
                if (fires(put_here)) {
                    put(put_here, true);
                }
            }
        }

        primitive getter(in<bool> get_here) {
            bool received = false; bool did_receive = false;
            synchronous {
                if (fires(get_here)) {
                    received = get(get_here);
                    did_receive = true;
                } else {
                    assert(false);
                }
            }
        }"
    );
}