diff --git a/src/runtime2/tests/mod.rs b/src/runtime2/tests/mod.rs index 5681612271b828550a826118b066917dd7b1bc02..46dbf2abfc1db253f4f6414d548bba4bac9dae36 100644 --- a/src/runtime2/tests/mod.rs +++ b/src/runtime2/tests/mod.rs @@ -1,130 +1,57 @@ use std::sync::Arc; -use super::runtime::*; -use crate::ProtocolDescription; +use super::*; +use crate::{PortId, ProtocolDescription}; +use crate::common::Id; 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(); +fn runtime_for(num_threads: u32, pdl: &str) -> Runtime { + let protocol = ProtocolDescription::parse(pdl.as_bytes()).expect("parse pdl"); + let runtime = Runtime::new(num_threads, protocol); - // 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); + return runtime; +} - // 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); +#[test] +fn test_put_and_get() { + let rt = runtime_for(4, " +primitive putter(out sender, u32 loops) { + u32 index = 0; + while (index < loops) { + synchronous { + print(\"putting!\"); + put(sender, true); + } + index += 1; } - - // Without `fires()`, just a single valid behaviour - run_putter_getter( - b"primitive putter(out put_here) { - synchronous { - put(put_here, true); - } +} + +primitive getter(in receiver, u32 loops) { + u32 index = 0; + while (index < loops) { + synchronous { + print(\"getting!\"); + auto result = get(receiver); + assert(result); } + index += 1; + } +} + "); - primitive getter(in 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 put_here) { - synchronous { - if (!fires(put_here)) { - assert(false); - } else { - put(put_here, true); - } - } - } + let mut api = rt.create_interface(); + let channel = api.create_channel(); + let num_loops = 5; - primitive getter(in get_here) { - bool received = false; bool did_receive = false; - synchronous { - if (fires(get_here)) { - received = get(get_here); - did_receive = true; - } - } - }"); + api.create_connector("", "putter", ValueGroup::new_stack(vec![ + Value::Output(PortId(Id{ connector_id: 0, u32_suffix: channel.putter_id.index })), + Value::UInt32(num_loops) + ])).expect("create putter"); - // With `fires()`, but eliminating on the getter side - run_putter_getter( - b"primitive putter(out put_here) { - synchronous { - if (fires(put_here)) { - put(put_here, true); - } - } - } + api.create_connector("", "getter", ValueGroup::new_stack(vec![ + Value::Input(PortId(Id{ connector_id: 0, u32_suffix: channel.getter_id.index })), + Value::UInt32(num_loops) + ])).expect("create getter"); - primitive getter(in get_here) { - bool received = false; bool did_receive = false; - synchronous { - if (fires(get_here)) { - received = get(get_here); - did_receive = true; - } else { - assert(false); - } - } - }" - ); + println!("Am I running?"); } \ No newline at end of file