Files @ 390da0a44204
Branch filter:

Location: CSY/reowolf/src/runtime2/tests/mod.rs - annotation

390da0a44204 8.9 KiB application/rls-services+xml Show Source Show as Raw Download as Raw
mh
Update to tests
53d3950d9b6b
53d3950d9b6b
53d3950d9b6b
bf4c0ee5ba65
bf4c0ee5ba65
38c129959044
1f78496722d1
38c129959044
2811715674ea
1f78496722d1
1f78496722d1
38c129959044
1f78496722d1
1f78496722d1
1f78496722d1
1f78496722d1
390da0a44204
1f78496722d1
1f78496722d1
1f78496722d1
1f78496722d1
1f78496722d1
bf4c0ee5ba65
bf4c0ee5ba65
bf4c0ee5ba65
38c129959044
bf4c0ee5ba65
113e4349a706
38c129959044
bf4c0ee5ba65
bf4c0ee5ba65
bf4c0ee5ba65
1f78496722d1
53d3950d9b6b
53d3950d9b6b
53d3950d9b6b
53d3950d9b6b
2811715674ea
53d3950d9b6b
53d3950d9b6b
53d3950d9b6b
53d3950d9b6b
1f78496722d1
53d3950d9b6b
637115283740
bf4c0ee5ba65
0781cf1b7abf
0781cf1b7abf
0781cf1b7abf
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
2811715674ea
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
2811715674ea
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
2811715674ea
113e4349a706
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
1f78496722d1
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
2811715674ea
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
2811715674ea
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
1f78496722d1
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
2811715674ea
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
637115283740
1f78496722d1
637115283740
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
2811715674ea
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
2811715674ea
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
1f78496722d1
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
2811715674ea
113e4349a706
113e4349a706
2811715674ea
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
2811715674ea
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
2811715674ea
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
2811715674ea
113e4349a706
113e4349a706
113e4349a706
2811715674ea
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
2811715674ea
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
2811715674ea
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
2811715674ea
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
2811715674ea
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
1f78496722d1
113e4349a706
53d3950d9b6b
use crate::protocol::*;
use crate::protocol::eval::*;
use crate::runtime2::runtime::*;
use crate::runtime2::component::{CompCtx, CompPDL};

mod messaging;
mod error_handling;
mod transfer_ports;
mod internet;

const LOG_LEVEL: LogLevel = LogLevel::Debug;
const NUM_THREADS: u32 = 1;

pub(crate) fn compile_and_create_component(source: &str, routine_name: &str, args: ValueGroup) {
    let protocol = ProtocolDescription::parse(source.as_bytes())
        .expect("successful compilation");
    let runtime = Runtime::new(NUM_THREADS, LOG_LEVEL, protocol)
        .expect("successful runtime startup");
    create_component(&runtime, "", routine_name, args);
}

pub(crate) fn create_component(rt: &Runtime, module_name: &str, routine_name: &str, args: ValueGroup) {
    let prompt = rt.inner.protocol.new_component(
        module_name.as_bytes(), routine_name.as_bytes(), args
    ).expect("create prompt");
    let reserved = rt.inner.start_create_component();
    let ctx = CompCtx::new(&reserved);
    let component = Box::new(CompPDL::new(prompt, 0));
    let (key, _) = rt.inner.finish_create_component(reserved, component, ctx, false);
    rt.inner.enqueue_work(key);
}

pub(crate) fn no_args() -> ValueGroup { ValueGroup::new_stack(Vec::new()) }

#[test]
fn test_component_creation() {
    let pd = ProtocolDescription::parse(b"
    comp nothing_at_all() {
        s32 a = 5;
        auto b = 5 + a;
    }
    ").expect("compilation");
    let rt = Runtime::new(1, LOG_LEVEL, pd).unwrap();

    for _i in 0..20 {
        create_component(&rt, "", "nothing_at_all", no_args());
    }
}

#[test]
fn test_simple_select() {
    let pd = ProtocolDescription::parse(b"
    func infinite_assert<T>(T val, T expected) -> () {
        while (val != expected) { print(\"nope!\"); }
        return ();
    }

    comp receiver(in<u32> in_a, in<u32> in_b, u32 num_sends) {
        auto num_from_a = 0;
        auto num_from_b = 0;
        while (num_from_a + num_from_b < 2 * num_sends) {
            sync select {
                auto v = get(in_a) -> {
                    print(\"got something from A\");
                    auto _ = infinite_assert(v, num_from_a);
                    num_from_a += 1;
                }
                auto v = get(in_b) -> {
                    print(\"got something from B\");
                    auto _ = infinite_assert(v, num_from_b);
                    num_from_b += 1;
                }
            }
        }
    }

    comp sender(out<u32> tx, u32 num_sends) {
        auto index = 0;
        while (index < num_sends) {
            sync {
                put(tx, index);
                index += 1;
            }
        }
    }

    comp constructor() {
        auto num_sends = 1;
        channel tx_a -> rx_a;
        channel tx_b -> rx_b;
        new sender(tx_a, num_sends);
        new receiver(rx_a, rx_b, num_sends);
        new sender(tx_b, num_sends);
    }
    ").expect("compilation");
    let rt = Runtime::new(3, LOG_LEVEL, pd).unwrap();
    create_component(&rt, "", "constructor", no_args());
}

#[test]
fn test_unguarded_select() {
    let pd = ProtocolDescription::parse(b"
    comp constructor_outside_select() {
        u32 index = 0;
        while (index < 5) {
            sync select { auto v = () -> print(\"hello\"); }
            index += 1;
        }
    }

    comp constructor_inside_select() {
        u32 index = 0;
        while (index < 5) {
            sync select { auto v = () -> index += 1; }
        }
    }
    ").expect("compilation");
    let rt = Runtime::new(3, LOG_LEVEL, pd).unwrap();
    create_component(&rt, "", "constructor_outside_select", no_args());
    create_component(&rt, "", "constructor_inside_select", no_args());
}

#[test]
fn test_empty_select() {
    let pd = ProtocolDescription::parse(b"
    comp constructor() {
        u32 index = 0;
        while (index < 5) {
            sync select {}
            index += 1;
        }
    }
    ").expect("compilation");
    let rt = Runtime::new(3, LOG_LEVEL, pd).unwrap();
    create_component(&rt, "", "constructor", no_args());
}

#[test]
fn test_random_u32_temporary_thingo() {
    let pd = ProtocolDescription::parse(b"
    import std.random::random_u32;

    comp random_taker(in<u32> generator, u32 num_values) {
        auto i = 0;
        while (i < num_values) {
            sync {
                auto a = get(generator);
            }
            i += 1;
        }
    }

    comp constructor() {
        channel tx -> rx;
        auto num_values = 25;
        new random_u32(tx, 1, 100, num_values);
        new random_taker(rx, num_values);
    }
    ").expect("compilation");
    let rt = Runtime::new(1, LOG_LEVEL, pd).unwrap();
    create_component(&rt, "", "constructor", no_args());
}

#[test]
fn test_tcp_socket_http_request() {
    let _pd = ProtocolDescription::parse(b"
    import std.internet::*;

    comp requester(out<ClientCmd> cmd_tx, in<u8[]> data_rx) {
        print(\"*** TCPSocket: Sending request\");
        sync {
            put(cmd_tx, ClientCmd::Send(b\"GET / HTTP/1.1\\r\\n\\r\\n\"));
        }

        print(\"*** TCPSocket: Receiving response\");
        auto buffer = {};
        auto done_receiving = false;
        sync while (!done_receiving) {
            put(cmd_tx, ClientCmd::Receive);
            auto data = get(data_rx);
            buffer @= data;

            // Completely crap detection of end-of-document. But here we go, we
            // try to detect the trailing </html>. Proper way would be to parse
            // for 'content-length' or 'content-encoding'
            s32 index = 0;
            s32 partial_length = cast(length(data) - 7);
            while (index < partial_length) {
                // No string conversion yet, so check byte buffer one byte at
                // a time.
                auto c1 = data[index];
                if (c1 == cast('<')) {
                    auto c2 = data[index + 1];
                    auto c3 = data[index + 2];
                    auto c4 = data[index + 3];
                    auto c5 = data[index + 4];
                    auto c6 = data[index + 5];
                    auto c7 = data[index + 6];
                    if ( // i.e. if (data[index..] == '</html>'
                        c2 == cast('/') && c3 == cast('h') && c4 == cast('t') &&
                        c5 == cast('m') && c6 == cast('l') && c7 == cast('>')
                    ) {
                        print(\"*** TCPSocket: Detected </html>\");
                        put(cmd_tx, ClientCmd::Finish);
                        done_receiving = true;
                    }
                }
                index += 1;
            }
        }

        print(\"*** TCPSocket: Requesting shutdown\");
        sync {
            put(cmd_tx, ClientCmd::Shutdown);
        }
    }

    comp main() {
        channel cmd_tx -> cmd_rx;
        channel data_tx -> data_rx;
        new tcp_client({142, 250, 179, 163}, 80, cmd_rx, data_tx); // port 80 of google
        new requester(cmd_tx, data_rx);
    }
    ").expect("compilation");

    // This test is disabled because it performs a HTTP request to google.
    // let rt = Runtime::new(1, LOG_LEVEL, _pd).unwrap();
    // create_component(&rt, "", "main", no_args());
}

#[test]
fn test_sending_receiving_union() {
    let pd = ProtocolDescription::parse(b"
    union Cmd {
        Set(u8[]),
        Get,
        Shutdown,
    }

    comp database(in<Cmd> rx, out<u8[]> tx) {
        auto stored = {};
        auto done = false;
        while (!done) {
            sync {
                auto command = get(rx);
                if (let Cmd::Set(bytes) = command) {
                    print(\"database: storing value\");
                    stored = bytes;
                } else if (let Cmd::Get = command) {
                    print(\"database: returning value\");
                    put(tx, stored);
                } else if (let Cmd::Shutdown = command) {
                    print(\"database: shutting down\");
                    done = true;
                } else while (true) print(\"impossible\"); // no other case possible
            }
        }
    }

    comp client(out<Cmd> tx, in<u8[]> rx, u32 num_rounds) {
        auto round = 0;
        while (round < num_rounds) {
            auto set_value = b\"hello there\";
            print(\"client: putting a value\");
            sync put(tx, Cmd::Set(set_value));

            auto retrieved = {};
            print(\"client: retrieving what was sent\");
            sync {
                put(tx, Cmd::Get);
                retrieved = get(rx);
            }

            if (set_value != retrieved) while (true) print(\"wrong!\");

            round += 1;
        }

        sync put(tx, Cmd::Shutdown);
    }

    comp main() {
        auto num_rounds = 5;
        channel cmd_tx -> cmd_rx;
        channel data_tx -> data_rx;
        new database(cmd_rx, data_tx);
        new client(cmd_tx, data_rx, num_rounds);
    }
    ").expect("compilation");
    let rt = Runtime::new(1, LOG_LEVEL, pd).unwrap();
    create_component(&rt, "", "main", no_args());
}