Files @ 5e53e3e9d68e
Branch filter:

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

5e53e3e9d68e 4.9 KiB application/rls-services+xml Show Source Show as Raw Download as Raw
Max Henger
Merge branch 'feat-transmitting-ports' into 'master'

feat: transmitting ports

See merge request nl-cwi-csy/reowolf!8
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
2982ea49738a
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
1b179e5f4579
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
2982ea49738a
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
32d9f23a4c87
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
2982ea49738a
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
db94fb636c02
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
a2bfd792a202
1b179e5f4579
// 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<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 ="
    primitive 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 = "
    primitive 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 = "
    primitive 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());
    }
}