int basic_test(int protocol_type) { test_printf("Test: Starting %s test.\n", protocol_type == msg_udp ? "udp" : "tcp"); int status; pid_t child_pid = fork(); if (child_pid == -1) return test_failure; if (child_pid == 0) { // Child process. exit(server(protocol_type)); // TODO Test memory cleanliness (use net_allocs_for_class). } else { // Parent process. test_printf("Client pid=%d server pid=%d\n", getpid(), child_pid); test_printf("Client: starting up.\n"); // tmp int client_failed = client(protocol_type, child_pid); int server_status; wait(&server_status); int server_failed = WEXITSTATUS(server_status); // Help check for memory leaks. test_that(net_allocs_for_class(0) == 0); // TODO Add deeper memory-leak checks via memprofile. test_printf("Test: client_failed=%d server_failed=%d.\n", client_failed, server_failed); return client_failed || server_failed; } }
int server(int protocol_type) { server_done = false; server_event_num = 0; num_msg_recd = 0; char address[256]; snprintf(address, 256, "%s://*:%d", protocol_type == msg_udp ? "udp" : "tcp", protocol_type == msg_udp ? udp_port : tcp_port); server_ctx.address = strdup(address); server_ctx.num_tries = 0; msg_listen(address, server_update); int timeout_in_ms = 10; // Sleep for 1ms to give the client time to send all the messages. usleep(1000); while (!server_done) msg_runloop(timeout_in_ms); test_that(num_msg_recd == 3); free(server_ctx.address); // Sleep for 1ms as the client expects to finish before the server. // (Early server termination could be an error, so we check for it.) usleep(1000); return test_success; }
void client_update(msg_Conn *conn, msg_Event event, msg_Data data) { // We expect to hear events in this order: int expected_events[] = { msg_connection_ready, msg_connection_closed}; Context *ctx = (Context *)conn->conn_context; test_printf("Client: Received event %s\n", event_names[event]); if (event == msg_error) { char *err_str = msg_as_str(data); test_printf("Client: Error: %s\n", err_str); if (strcmp(err_str, "connect: Connection refused") == 0) { if (ctx->num_tries < max_tries) { test_printf("Client: Will wait briefly and try again at address %s.\n", ctx->address); sleep(5); ctx->num_tries++; msg_connect(ctx->address, client_update, ctx); return; // Don't count this as a server event. } else { test_printf("Client: max_tries reached; giving up connecting (at %s).\n", ctx->address); } } } if (event == msg_error) test_printf("Client: Error: %s\n", msg_as_str(data)); test_that(client_event_num < array_size(expected_events)); test_that(event == expected_events[client_event_num]); if (event == msg_connection_ready) { msg_Data data = msg_new_data("why hello"); msg_send(conn, data); msg_send(conn, data); msg_send(conn, data); msg_delete_data(data); client_done = true; } client_event_num++; }
void server_update(msg_Conn *conn, msg_Event event, msg_Data data) { // We expect to hear events in this order. int expected_events[] = { msg_listening, msg_connection_ready, msg_message, msg_message, msg_message, msg_connection_closed}; test_printf("Server: Received event %s\n", event_names[event]); if (event == msg_error) { char *err_str = msg_as_str(data); test_printf("Server: Error: %s\n", err_str); if (strcmp(err_str, "bind: Address already in use") == 0) { if (server_ctx.num_tries < max_tries) { test_printf("Will wait briefly and try again at address %s.\n", server_ctx.address); sleep(5); server_ctx.num_tries++; msg_listen(server_ctx.address, server_update); return; // Don't count this as a server event. } else { test_printf("Server: max_tries reached; giving up listening (at %s).\n", server_ctx.address); } } } test_that(server_event_num < array_size(expected_events)); test_that(event == expected_events[server_event_num]); if (event == msg_message) { char *str = msg_as_str(data); test_str_eq(str, "why hello"); server_done = true; num_msg_recd++; } server_event_num++; }
int main(){ char buf[80]; char *p; int head; int key; char *tokp; int toklen; while (gets(buf)){ head = 0; key = -1; p = buf; printf("==>%s\n", p); while(chop_slen(&p, &len, &tokp, &toklen)){ if (key = test_the(tokp, toklen) > -1) break; if (key = test_this_(tokp, toklen) > -1) break; if (key = test_that_(tokp, toklen) > -1) break; if (key = test_this(tokp, toklen) > -1) break; if (key = test_that(tokp, toklen) > -1) break; } decode_line(buf, key); } return 0; }