Files
@ 665aa326769e
Branch filter:
Location: CSY/reowolf/src/runtime2/tests/mod.rs
665aa326769e
4.1 KiB
application/rls-services+xml
add 'print' fn for testing, first test for new runtime
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | 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);
}
}
}"
);
}
|