// Testing the api component. // // These tests explicitly do not use the "NUM_INSTANCES" constant because we're // doing some communication with the native component. Hence only expect one use super::*; #[test] fn test_put_and_get() { const CODE: &'static str = " primitive handler(in request, out response, u32 loops) { u32 index = 0; while (index < loops) { synchronous { auto value = get(request); put(response, value * 2); } index += 1; } } "; let pd = ProtocolDescription::parse(CODE.as_bytes()).unwrap(); let rt = Runtime::new(NUM_THREADS, pd); let mut api = rt.create_interface(); let req_chan = api.create_channel().unwrap(); let resp_chan = api.create_channel().unwrap(); api.create_connector("", "handler", ValueGroup::new_stack(vec![ Value::Input(PortId::new(req_chan.getter_id.index)), Value::Output(PortId::new(resp_chan.putter_id.index)), Value::UInt32(NUM_LOOPS), ])).unwrap(); for loop_idx in 0..NUM_LOOPS { api.perform_sync_round(vec![ ApplicationSyncAction::Put(req_chan.putter_id, ValueGroup::new_stack(vec![Value::UInt32(loop_idx)])), ApplicationSyncAction::Get(resp_chan.getter_id) ]).expect("start sync round"); let result = api.wait().expect("finish sync round"); assert!(result.len() == 1); if let Value::UInt32(gotten) = result[0].values[0] { assert_eq!(gotten, loop_idx * 2); } else { assert!(false); } } } #[test] fn test_getting_from_component() { const CODE: &'static str =" primitive loop_sender(out numbers, u32 cur, u32 last) { while (cur < last) { synchronous { put(numbers, cur); cur += 1; } } }"; let pd = ProtocolDescription::parse(CODE.as_bytes()).unwrap(); let rt = Runtime::new(NUM_THREADS, pd); let mut api = rt.create_interface(); let channel = api.create_channel().unwrap(); api.create_connector("", "loop_sender", ValueGroup::new_stack(vec![ Value::Output(PortId::new(channel.putter_id.index)), Value::UInt32(1337), Value::UInt32(1337 + NUM_LOOPS) ])).unwrap(); for loop_idx in 0..NUM_LOOPS { api.perform_sync_round(vec![ ApplicationSyncAction::Get(channel.getter_id), ]).expect("start sync round"); let result = api.wait().expect("finish sync round"); assert!(result.len() == 1 && result[0].values.len() == 1); if let Value::UInt32(gotten) = result[0].values[0] { assert_eq!(gotten, 1337 + loop_idx); } else { assert!(false); } } } #[test] fn test_putting_to_component() { const CODE: &'static str = " primitive loop_receiver(in numbers, u32 cur, u32 last) { while (cur < last) { synchronous { auto number = get(numbers); assert(number == cur); cur += 1; } } } "; let pd = ProtocolDescription::parse(CODE.as_bytes()).unwrap(); let rt = Runtime::new(NUM_THREADS, pd); let mut api = rt.create_interface(); let channel = api.create_channel().unwrap(); api.create_connector("", "loop_receiver", ValueGroup::new_stack(vec![ Value::Input(PortId::new(channel.getter_id.index)), Value::UInt32(42), Value::UInt32(42 + NUM_LOOPS) ])).unwrap(); for loop_idx in 0..NUM_LOOPS { api.perform_sync_round(vec![ ApplicationSyncAction::Put(channel.putter_id, ValueGroup::new_stack(vec![Value::UInt32(42 + loop_idx)])), ]).expect("start sync round"); // Note: if we finish a round, then it must have succeeded :) api.wait().expect("finish sync round"); } }