Files @ 7e5f19869dd2
Branch filter:

Location: CSY/reowolf/src/runtime/tests/api_component.rs

7e5f19869dd2 4.9 KiB application/rls-services+xml Show Annotation Show as Raw Download as Raw
MH
Remove distinction between primitive/composite
// 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 = "
    comp handler(in<u32> request, out<u32> response, u32 loops) {
        u32 index = 0;
        while (index < loops) {
            sync {
                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 ="
    comp loop_sender(out<u32> numbers, u32 cur, u32 last) {
        while (cur < last) {
            sync {
                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 = "
    comp loop_receiver(in<u32> numbers, u32 cur, u32 last) {
        while (cur < last) {
            sync {
                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");
    }
}

#[test]
fn test_doing_nothing() {
    const CODE: &'static str = "
    comp getter(in<bool> input, u32 num_loops) {
        u32 index = 0;
        while (index < num_loops) {
            sync {}
            sync { auto res = get(input); assert(res); }
            index += 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("", "getter", ValueGroup::new_stack(vec![
        Value::Input(PortId::new(channel.getter_id.index)),
        Value::UInt32(NUM_LOOPS),
    ])).unwrap();

    for _ in 0..NUM_LOOPS {
        api.perform_sync_round(vec![]).expect("start silent sync round");
        api.wait().expect("finish silent sync round");
        api.perform_sync_round(vec![
            ApplicationSyncAction::Put(channel.putter_id, ValueGroup::new_stack(vec![Value::Bool(true)]))
        ]).expect("start firing sync round");
        let res = api.wait().expect("finish firing sync round");
        assert!(res.is_empty());
    }
}