/******************************************/ /* tester.c 0.0.0 (1999-Dec-16-Thu) */ /* Adam M. Costello */ /******************************************/ /* Example test loop. */ /* This is ANSI C code. */ #include #include #include #include #include "deliver_packet.h" #include "network.h" #include "network_config.h" #include "random.h" #include "streamers.h" #include "timer.h" #include "timer_expire.h" #include "transport.h" #include "warnf.h" static struct network_address source_address = { 1, { 1 } }, sink_address = { 1, { 2 } }; static void *transport_source, *transport_sink; void deliver_packet(struct network_packet packet) { unsigned short length; unsigned char *address; length = packet.destination.length; address = packet.destination.address; if (length == source_address.length && !memcmp(address, source_address.address, length)) { transport_source_receive_packet(transport_source, packet); return; } if (length == sink_address.length && !memcmp(address, sink_address.address, length)) { transport_sink_receive_packet(transport_sink, packet); return; } assert(0); /* Cannot reach here. */ } static int randint(int n) /* Returns a uniform random integer from 0 to n-1. */ { return random_discrete_uniform(0, n-1); } typedef unsigned long ul; int main() { void *byte_source, *byte_sink; struct transport_connection connection; struct network_path_parameters net_params; struct streamer_parameters source_params, sink_params; double rates[] = { 1e2, 1e4, 1e6, 1e8, 1e10 }, probs[] = { 0.0, 0.05, 0.5 }, delays[] = { 6e-4, 6e-3, 0.06, 0.6, 6, 60 }, start, stop; unsigned long bursts[] = { 1, 19, 93, 866, 2191, 82031 }, lengths[] = { 320, 1407, 7538, 65535 }, min, total, sent, received; size_t buffers[] = { 1, 10, 155, 5863, 67391 }, source_buffer, sink_buffer; int num_rates = sizeof rates / sizeof (double), num_probs = sizeof probs / sizeof (double), num_delays = sizeof delays / sizeof (double), num_bursts = sizeof bursts / sizeof (ul), num_buffers = sizeof buffers / sizeof (ul), num_lengths = sizeof lengths / sizeof (ul), flow_control, flow_violation; flow_control = (transport_extensions() & transport_flow_control_efficiency) != 0; transport_source = transport_source_create(source_address); transport_sink = transport_sink_create(sink_address); connection.source.address = source_address; connection.source.port = 101; connection.sink.address = sink_address; connection.sink.port = 102; for (;;) { net_params.max_payload_length = lengths[randint(num_lengths)]; net_params.bit_error_rate = 1.0 - pow(1.0 - probs[randint(num_probs)], 0.125 / net_params.max_payload_length); net_params.drop_probability = probs[randint(num_probs)]; net_params.duplicate_probability = probs[randint(num_probs)]; net_params.delay_constant = delays[randint(num_delays)]; net_params.delay_per_bit = 0.0; net_params.delay_random_max = delays[randint(num_delays)]; network_path_config(source_address, sink_address, net_params); network_path_config(sink_address, source_address, net_params); source_buffer = buffers[randint(num_buffers)]; sink_buffer = buffers[randint(num_buffers)]; source_params.rate = rates[randint(num_rates)]; source_params.burst_min = bursts[randint(num_bursts)]; source_params.burst_max = bursts[randint(num_bursts)]; if (source_params.burst_min > source_params.burst_max) { ul tmp = source_params.burst_min; source_params.burst_min = source_params.burst_max; source_params.burst_max = tmp; } sink_params.rate = rates[randint(num_rates)]; sink_params.burst_min = bursts[randint(num_bursts)]; sink_params.burst_max = bursts[randint(num_bursts)]; if (sink_params.burst_min > sink_params.burst_max) { ul tmp = sink_params.burst_min; sink_params.burst_min = sink_params.burst_max; sink_params.burst_max = tmp; } min = source_params.burst_min; if (min > sink_params.burst_min) min = sink_params.burst_min; if (min > source_buffer) min = source_buffer; if (min > sink_buffer) min = sink_buffer; if (min > net_params.max_payload_length) min = net_params.max_payload_length; total = min * 200 + 1; source_params.total_bytes = sink_params.total_bytes = total; source_params.seed = sink_params.seed = randint(32767); byte_source = byte_source_create(); byte_sink = byte_sink_create(); byte_source_config(byte_source, source_params); byte_sink_config(byte_sink, sink_params); transport_source_create_connection( transport_source, connection, byte_source, byte_source_go_ahead, source_buffer ); transport_sink_create_connection( transport_sink, connection, byte_sink, byte_sink_transfer, sink_buffer ); byte_source_talk_to( byte_source, transport_source, transport_source_receive_bytes ); byte_sink_listen_to( byte_sink, transport_sink, transport_sink_okay_to_deliver ); start = timer_now(); flow_violation = 0; warnf("\nstarting test...\n"); while (timer_expire() && byte_sink_received(byte_sink) < total) { if (flow_control) { sent = byte_source_sent(byte_source); received = byte_sink_received(byte_sink); if (sent - received > source_buffer + sink_buffer) flow_violation = 1; } } stop = timer_now() + (timer_now() - start); while (timer_next() <= stop && timer_expire()); sent = byte_source_sent(byte_source); received = byte_sink_received(byte_sink); if (flow_violation || received != total) { warnf("\ntest failed:\n"); warnf("network path parameters:\n"); warnf(" max_payload_length = %lu\n", (ul) net_params.max_payload_length); warnf(" bit_error_rate = %.4g\n", net_params.bit_error_rate); warnf(" drop_probability = %.2g\n", net_params.drop_probability); warnf(" duplicate_probability = %.2g\n", net_params.duplicate_probability); warnf(" delay_constant = %.2g\n", net_params.delay_constant); warnf(" delay_per_bit = %.2g\n", net_params.delay_per_bit); warnf(" delay_random_max = %.2g\n", net_params.delay_random_max); warnf("byte source parameters:\n"); warnf(" total_bytes = %lu\n", (ul) source_params.total_bytes); warnf(" rate = %.2g\n", source_params.rate); warnf(" seed = %lu\n", (ul) source_params.seed); warnf(" burst_min = %lu\n", (ul) source_params.burst_min); warnf(" burst_max = %lu\n", (ul) source_params.burst_max); warnf("byte sink parameters:\n"); warnf(" total_bytes = %lu\n", (ul) sink_params.total_bytes); warnf(" rate = %.2g\n", sink_params.rate); warnf(" seed = %lu\n", (ul) sink_params.seed); warnf(" burst_min = %lu\n", (ul) sink_params.burst_min); warnf(" burst_max = %lu\n", (ul) sink_params.burst_max); warnf("transport source buffer_max = %lu\n", (ul) source_buffer); warnf("transport sink buffer_max = %lu\n", (ul) sink_buffer); warnf("byte source sent %lu bytes\n", (ul) sent); warnf("byte sink received %lu bytes\n", (ul) received); if (flow_violation) warnf("transport buffer limits were exceeded\n"); } transport_source_delete_connection(transport_source, byte_source); transport_sink_delete_connection(transport_sink, byte_sink); byte_source_delete(byte_source); byte_sink_delete(byte_sink); /* Flush the network of packets: */ stop = timer_now() + 120.0; while(timer_now() <= stop && timer_expire()); } }