Files @ f030cfda190d
Branch filter:

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

f030cfda190d 5.5 KiB application/rls-services+xml Show Source Show as Raw Download as Raw
MH
WIP on consensus/issues documentation
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
7e5f19869dd2
1cc3bd69b119
1cc3bd69b119
7e5f19869dd2
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
7c5078fc4f81
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
7e5f19869dd2
7c5078fc4f81
1cc3bd69b119
d65eb4f44f1a
7c5078fc4f81
1cc3bd69b119
7c5078fc4f81
1cc3bd69b119
7c5078fc4f81
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
7e5f19869dd2
7c5078fc4f81
1cc3bd69b119
7c5078fc4f81
1cc3bd69b119
d65eb4f44f1a
d65eb4f44f1a
d65eb4f44f1a
7c5078fc4f81
1cc3bd69b119
7c5078fc4f81
1cc3bd69b119
1cc3bd69b119
7e5f19869dd2
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
1cc3bd69b119
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
339b493050e2
1cc3bd69b119
use super::*;

// silly test to make sure that the PDL will never be an issue when doing TCP
// stuff with the actual components
#[test]
fn test_stdlib_file() {
    compile_and_create_component("
    import std.internet as inet;

    comp fake_listener_once(out<inet::TcpConnection> tx) {
        channel cmd_tx -> cmd_rx;
        channel data_tx -> data_rx;
        new fake_socket(cmd_rx, data_tx);
        sync put(tx, inet::TcpConnection{
            tx: cmd_tx,
            rx: data_rx,
        });
    }

    comp fake_socket(in<inet::ClientCmd> cmds, out<u8[]> tx) {
        auto to_send = {};

        auto shutdown = false;
        while (!shutdown) {
            auto keep_going = true;
            sync {
                while (keep_going) {
                    auto cmd = get(cmds);
                    if (let inet::ClientCmd::Send(data) = cmd) {
                        to_send = data;
                        keep_going = false;
                    } else if (let inet::ClientCmd::Receive = cmd) {
                        put(tx, to_send);
                    } else if (let inet::ClientCmd::Finish = cmd) {
                        keep_going = false;
                    } else if (let inet::ClientCmd::Shutdown = cmd) {
                        keep_going = false;
                        shutdown = true;
                    }
                }
            }
        }
    }

    comp fake_client(inet::TcpConnection conn) {
        sync put(conn.tx, inet::ClientCmd::Send({1, 3, 3, 7}));
        sync {
            put(conn.tx, inet::ClientCmd::Receive);
            auto val = get(conn.rx);
            while (val[0] != 1 || val[1] != 3 || val[2] != 3 || val[3] != 7) {
                print(\"this is going very wrong\");
            }
            put(conn.tx, inet::ClientCmd::Finish);
        }
        sync put(conn.tx, inet::ClientCmd::Shutdown);
    }

    comp constructor() {
        channel conn_tx -> conn_rx;
        new fake_listener_once(conn_tx);

        // Same crap as before:
        channel cmd_tx -> unused_cmd_rx;
        channel unused_data_tx -> data_rx;
        auto connection = inet::TcpConnection{ tx: cmd_tx, rx: data_rx };

        sync {
            connection = get(conn_rx);
        }

        new fake_client(connection);
    }
    ", "constructor", no_args());
}

#[test]
fn test_tcp_listener_and_client() {
    compile_and_create_component("
    import std.internet::*;

    func listen_port() -> u16 {
        return 2393;
    }

    comp server(u32 num_connections) {
        // Start tcp listener
        channel listen_cmd_tx -> listen_cmd_rx;
        channel listen_conn_tx -> listen_conn_rx;
        new tcp_listener({}, listen_port(), listen_cmd_rx, listen_conn_tx);

        // Fake channels such that we can create a dummy connection variable
        channel client_cmd_tx -> unused_client_cmd_rx;
        channel unused_client_data_tx -> client_data_rx;
        auto new_connection = TcpConnection{
            tx: client_cmd_tx,
            rx: client_data_rx,
        };

        auto connection_counter = 0;
        while (connection_counter < num_connections) {
            // Wait until we get a connection
            print(\"server: waiting for an accepted connection\");
            sync {
                put(listen_cmd_tx, ListenerCmd::Accept);
                new_connection = get(listen_conn_rx);
            }

            // We have a new connection, spawn an 'echoer' for it
            print(\"server: spawning an echo'ing component\");
            new echo_machine(new_connection);
            connection_counter += 1;
        }

        // Shut down the listener
        print(\"server: shutting down listener\");
    }

    // Waits for a single TCP byte (to simplify potentially having to
    // concatenate requests) and echos it
    comp echo_machine(TcpConnection conn) {
        auto data_to_echo = {};

        // Wait for a message
        sync {
            print(\"echo: receiving data\");
            put(conn.tx, ClientCmd::Receive);
            data_to_echo = get(conn.rx);
            put(conn.tx, ClientCmd::Finish);
        }

        // Echo the message
        print(\"echo: sending back data\");
        sync put(conn.tx, ClientCmd::Send(data_to_echo));

        // Ask the tcp connection to shut down
        print(\"echo: shutting down\");
        sync put(conn.tx, ClientCmd::Shutdown);
    }

    comp echo_requester(u8 byte_to_send) {
        channel cmd_tx -> cmd_rx;
        channel data_tx -> data_rx;
        new tcp_client({127, 0, 0, 1}, listen_port(), cmd_rx, data_tx);

        // Send the message
        print(\"requester: sending bytes\");
        sync put(cmd_tx, ClientCmd::Send({ byte_to_send }));

        // Receive the echo'd byte
        auto received_byte = byte_to_send + 1;
        sync {
            print(\"requester: receiving echo response\");
            put(cmd_tx, ClientCmd::Receive);
            received_byte = get(data_rx)[0];
            put(cmd_tx, ClientCmd::Finish);
        }

        // Silly check, as always
        while (byte_to_send != received_byte) {
            print(\"requester: Oh no! The echo is an otherworldly distorter\");
        }

        // Shut down the TCP connection
        print(\"requester: shutting down TCP component\");
        sync put(cmd_tx, ClientCmd::Shutdown);
    }

    comp constructor() {
        auto num_connections = 1;
        new server(num_connections);

        auto connection_index = 0;
        while (connection_index < num_connections) {
            new echo_requester(cast(connection_index));
        }
    }
    ", "constructor", no_args());
}