Files
@ f4f12a71e2e2
Branch filter:
Location: CSY/reowolf/src/runtime2/tests/mod.rs
f4f12a71e2e2
4.1 KiB
application/rls-services+xml
WIP on runtime with error handling and multithreading
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 130 | 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);
}
}
}"
);
}
|