Files
@ 339b493050e2
Branch filter:
Location: CSY/reowolf/src/runtime2/tests/internet.rs
339b493050e2
5.5 KiB
application/rls-services+xml
WIP on tcp listener/socket test
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | 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());
}
|