static void test_case(const char * tapname, const char * request, unsigned count) { SXE * client; tap_ev event; tap_test_case_name(tapname); SXEA1((client = test_new_tcp(NULL, "0.0.0.0", 0, client_connect, client_read, client_close)) != NULL, "Failed to allocate client SXE"); SXEA1(sxe_connect(client, "127.0.0.1", SXE_LOCAL_PORT(listener)) == SXE_RETURN_OK, "Failed to connect to HTTPD"); #ifdef _WIN32 usleep(10000); /* Copied from test-errors.c and which is a TODO item */ #endif is_eq(test_tap_ev_queue_identifier_wait(q_client, TEST_WAIT, &event), "client_connect", "Got a client connected event"); is(tap_ev_arg(event, "this"), client, "It's the client"); is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &event), "h_connect", "Got a server connected event"); test_sxe_send(client, request, strlen(request), client_sent, "client_sent", q_client, TEST_WAIT, &event); if (count == 2) { is_eq(test_tap_ev_queue_identifier_wait(q_httpd , TEST_WAIT, &event), "h_header", "HTTPD: header event (a)" ); is_strncmp(tap_ev_arg(event, "key" ), "Good" , SXE_LITERAL_LENGTH( "Good" ), "HTTPD: header was 'Good'" ); is_strncmp(tap_ev_arg(event, "value"), "Header" , SXE_LITERAL_LENGTH( "Header" ), "HTTPD: header value was 'Header'"); is_eq(test_tap_ev_queue_identifier_wait(q_httpd , TEST_WAIT, &event), "h_header", "HTTPD: header event (b)" ); is_strncmp(tap_ev_arg(event, "key" ), "Another", SXE_LITERAL_LENGTH( "Another"), "HTTPD: header was 'Another'" ); is_strncmp(tap_ev_arg(event, "value"), "Foo" , SXE_LITERAL_LENGTH( "Foo" ), "HTTPD: header value was 'Foo'" ); } is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &event), "h_respond", "HTTPD: respond event"); sxe_close(client); is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &event), "h_close", "HTTPD: close event"); }
int main(void) { #if !TEST_DIRWATCH /* TODO: Implement sxe_dirwatch() on Windows */ /* TODO: Implement sxe_dirwatch() on Apple */ /* TODO: Implement sxe_dirwatch() on FreeBSD */ #else char tempdir1[] = "tmp-XXXXXX"; char tempdir2[] = "tmp-XXXXXX"; char tempdir3[] = "tmp-XXXXXX"; SXE_DIRWATCH dirwatch1; SXE_DIRWATCH dirwatch2; SXE_DIRWATCH dirwatch3; char fname[PATH_MAX]; tap_ev ev; plan_tests(28); sxe_register(1, 0); sxe_init(); /* We need to make a new temporary directory, because *everything* appears * to change willy-nilly during the build. The current directory has a * file that always changes. The /tmp directory always seems to have * spurious changes in it. */ SXEA1(mkdtemp(tempdir1), "Failed to create tempdir: %s", strerror(errno)); SXEA1(mkdtemp(tempdir2), "Failed to create tempdir: %s", strerror(errno)); SXEA1(mkdtemp(tempdir3), "Failed to create tempdir: %s", strerror(errno)); sxe_dirwatch_init(); sxe_dirwatch_init(); /* for coverage */ sxe_dirwatch_add(&dirwatch1, tempdir1, SXE_DIRWATCH_CREATED|SXE_DIRWATCH_MODIFIED|SXE_DIRWATCH_DELETED, test_dirwatch_event, (void *)1); sxe_dirwatch_add(&dirwatch2, tempdir2, SXE_DIRWATCH_MODIFIED, test_dirwatch_event, (void *)2); sxe_dirwatch_add(&dirwatch3, tempdir3, SXE_DIRWATCH_DELETED, test_dirwatch_event, (void *)3); sxe_dirwatch_start(); /* tempdir1: create, modify, delete */ { char rname[PATH_MAX]; int fd; snprintf(rname, sizeof rname, "%s/renamed", tempdir1); snprintf(fname, sizeof fname, "%s/created", tempdir1); fd = open(fname, O_CREAT|O_RDWR, S_IRWXU); write(fd, "Hello", 5); rename(fname, rname); unlink(rname); is_eq(test_tap_ev_identifier_wait(TEST_WAIT, &ev), "test_dirwatch_event", "Got a dirwatch event"); is_eq(tap_ev_arg(ev, "chfile"), "created", "Got filename %s", fname); is(tap_ev_arg(ev, "chflags"), SXE_DIRWATCH_CREATED, "Got flags=SXE_DIRWATCH_CREATED"); is(tap_ev_arg(ev, "user_data"), 1, "Got user_data=1 (%s)", tempdir1); is_eq(test_tap_ev_identifier_wait(TEST_WAIT, &ev), "test_dirwatch_event", "Got a dirwatch event"); is_eq(tap_ev_arg(ev, "chfile"), "created", "Got filename %s", fname); is(tap_ev_arg(ev, "chflags"), SXE_DIRWATCH_MODIFIED, "Got flags=SXE_DIRWATCH_MODIFIED"); is(tap_ev_arg(ev, "user_data"), 1, "Got user_data=1 (%s)", tempdir1); is_eq(test_tap_ev_identifier_wait(TEST_WAIT, &ev), "test_dirwatch_event", "Got a dirwatch event"); is_eq(tap_ev_arg(ev, "chfile"), "created", "Got filename %s", fname); is(tap_ev_arg(ev, "chflags"), SXE_DIRWATCH_DELETED, "Got flags=SXE_DIRWATCH_DELETED"); is(tap_ev_arg(ev, "user_data"), 1, "Got user_data=1 (%s)", tempdir1); is_eq(test_tap_ev_identifier_wait(TEST_WAIT, &ev), "test_dirwatch_event", "Got a dirwatch event"); is_eq(tap_ev_arg(ev, "chfile"), "renamed", "Got filename %s", rname); is(tap_ev_arg(ev, "chflags"), SXE_DIRWATCH_CREATED, "Got flags=SXE_DIRWATCH_CREATED"); is(tap_ev_arg(ev, "user_data"), 1, "Got user_data=1 (%s)", tempdir1); is_eq(test_tap_ev_identifier_wait(TEST_WAIT, &ev), "test_dirwatch_event", "Got a dirwatch event"); is_eq(tap_ev_arg(ev, "chfile"), "renamed", "Got filename %s", rname); is(tap_ev_arg(ev, "chflags"), SXE_DIRWATCH_DELETED, "Got flags=SXE_DIRWATCH_DELETED"); is(tap_ev_arg(ev, "user_data"), 1, "Got user_data=1 (%s)", tempdir1); } /* tempdir2: modified */ { const char *rel; int fd; snprintf(fname, sizeof fname, "%s/file.XXXXXX", tempdir2); SXEA1((rel = strchr(fname, '/')), "Didn't find '/' in %s", fname); rel++; fd = mkstemp(fname); write(fd, "Hello", 5); unlink(fname); is_eq(test_tap_ev_identifier_wait(TEST_WAIT, &ev), "test_dirwatch_event", "Got a dirwatch event"); is_eq(tap_ev_arg(ev, "chfile"), rel, "Got filename %s", fname); is(tap_ev_arg(ev, "chflags"), SXE_DIRWATCH_MODIFIED, "Got flags=SXE_DIRWATCH_MODIFIED"); is(tap_ev_arg(ev, "user_data"), 2, "Got user_data=2 (%s)", tempdir2); } /* tempdir3: deleted */ { const char *rel; int fd; snprintf(fname, sizeof fname, "%s/file.XXXXXX", tempdir3); SXEA1((rel = strchr(fname, '/')), "Didn't find '/' in %s", fname); rel++; fd = mkstemp(fname); unlink(fname); is_eq(test_tap_ev_identifier_wait(TEST_WAIT, &ev), "test_dirwatch_event", "Got a dirwatch event"); is_eq(tap_ev_arg(ev, "chfile"), rel, "Got filename %s", fname); is(tap_ev_arg(ev, "chflags"), SXE_DIRWATCH_DELETED, "Got flags=SXE_DIRWATCH_DELETED"); is(tap_ev_arg(ev, "user_data"), 3, "Got user_data=3 (%s)", tempdir3); } rmdir(tempdir1); rmdir(tempdir2); rmdir(tempdir3); sxe_dirwatch_stop(); #endif return exit_status(); }
int main(void) { SXE_HTTPD httpd; SXE * client; SXE * client2; SXE * server; SXE * server2; tap_ev event; plan_tests(14); test_sxe_register_and_init(1000); sxe_httpd_construct(&httpd, 2, 10, 512, 0); SXE_HTTPD_SET_HANDLER(&httpd, connect, h_connect); SXE_HTTPD_SET_HANDLER(&httpd, request, h_request); SXE_HTTPD_SET_HANDLER(&httpd, close, h_close); ok((listener = test_httpd_listen(&httpd, "0.0.0.0", 0)) != NULL, "HTTPD listening"); /* Starts two connections, then make a new connection, the oldest will be reaped by the server */ tap_test_case_name("reap connections"); /* 1st connection */ SXEA1((client = test_new_tcp(NULL, "0.0.0.0", 0, client_connect, client_read, client_close)) != NULL, "Failed to allocate client SXE"); SXEA1(sxe_connect(client, "127.0.0.1", SXE_LOCAL_PORT(listener)) == SXE_RETURN_OK, "Failed to connect to HTTPD"); is_eq(test_tap_ev_queue_identifier_wait(q_client, TEST_WAIT, &event), "client_connect", "Got 1st client connected event"); is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &event), "h_connect", "Got 1st server connect event"); server = SXE_CAST(SXE *, tap_ev_arg(event, "this")); /* 1st client: send a complete request line */ TEST_SXE_SEND_LITERAL(client, "GET /good HTTP/1.1\r\n", client_sent, q_client, TEST_WAIT, &event); /* Waiting for 1st client request state "stable" on "STATE_HEADER" to make * sure there is no more state updates on this request object, then the following * usleep will guarantee the 1st connection is older than the 2nd one. */ is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &event), "h_request", "Got 1st server request event"); is(tap_ev_arg(event, "this"), server, "It's the 1st server"); usleep(300000); /* 2nd connection, reaping happens, the 1st one got reaped */ SXEA1((client2 = test_new_tcp(NULL, "0.0.0.0", 0, client_connect, client_read, client_close)) != NULL, "Failed to allocate client SXE"); SXEA1(sxe_connect(client2, "127.0.0.1", SXE_LOCAL_PORT(listener)) == SXE_RETURN_OK, "Failed to connect to HTTPD"); is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &event), "h_connect", "Got 2nd server connect event"); server2 = SXE_CAST(SXE *, tap_ev_arg(event, "this")); is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &event), "h_close", "Got a server close event"); is(tap_ev_arg(event, "this"), server, "It's the 1st server"); /* Pull these two arguments off in any order */ test_process_all_libev_events(); ok((event = tap_ev_queue_shift_next(q_client, "client_connect")) != NULL, "Got 2nd client connected event"); ok((event = tap_ev_queue_shift_next(q_client, "client_close")) != NULL, "Got a client close event"); is(tap_ev_arg(event, "this"), client, "It's the 1st client"); is(tap_ev_queue_length(q_httpd), 0, "No server events lurking"); is(tap_ev_queue_length(q_client), 0, "No client events lurking"); sxe_close(listener); return exit_status(); }
int main(int argc, char *argv[]) { tap_ev ev; struct object self; struct object * this = &self; char expected[1024]; pid_t pid = getpid(); plan_tests(28); MOCK_SET_HOOK(openlog, t_openlog); MOCK_SET_HOOK(syslog, t_syslog); q_syslog = tap_ev_queue_new(); sxe_log_use_syslog("my-program", LOG_NDELAY|LOG_PID, LOG_USER); ev = tap_ev_queue_shift(q_syslog); is_eq(tap_ev_identifier(ev), "openlog", "sxe_log_use_syslog() calls openlog()"); is_eq(tap_ev_arg(ev, "ident"), "my-program", "sxe_log_use_syslog() calls openlog() with correct 'ident' parameter"); is(tap_ev_arg(ev, "option"), LOG_NDELAY|LOG_PID, "sxe_log_use_syslog() calls openlog() with correct 'option' parameter"); is(tap_ev_arg(ev, "facility"), LOG_USER, "sxe_log_use_syslog() calls openlog() with correct 'facility' parameter"); SXEL10("SXEL10"); snprintf(expected, sizeof expected, "T=%d ------ 1 - SXEL10\n", pid); ev = tap_ev_queue_shift(q_syslog); is_eq(tap_ev_identifier(ev), "syslog", "SXEL10() calls syslog()"); is(tap_ev_arg(ev, "priority"), LOG_ERR, "SXEL10() maps to LOG_ERR syslog level"); is_eq(tap_ev_arg(ev, "logline"), expected, "SXEL10() is logged correctly"); SXEL21("SXEL21(%s)", "arg1"); snprintf(expected, sizeof expected, "T=%d ------ 2 - SXEL21(arg1)\n", pid); ev = tap_ev_queue_shift(q_syslog); is_eq(tap_ev_identifier(ev), "syslog", "SXEL21() calls syslog()"); is(tap_ev_arg(ev, "priority"), LOG_WARNING, "SXEL21() maps to LOG_WARNING syslog level"); is_eq(tap_ev_arg(ev, "logline"), expected, "SXEL21() is logged correctly"); SXEL32("SXEL32(%s,%d)", "arg1", 22); snprintf(expected, sizeof expected, "T=%d ------ 3 - SXEL32(arg1,22)\n", pid); ev = tap_ev_queue_shift(q_syslog); is_eq(tap_ev_identifier(ev), "syslog", "SXEL32() calls syslog()"); is(tap_ev_arg(ev, "priority"), LOG_NOTICE, "SXEL32() maps to LOG_NOTICE syslog level"); is_eq(tap_ev_arg(ev, "logline"), expected, "SXEL32() is logged correctly"); SXEL43("SXEL43(%s,%d,%u)", "arg1", 22, 44); snprintf(expected, sizeof expected, "T=%d ------ 4 - SXEL43(arg1,22,44)\n", pid); ev = tap_ev_queue_shift(q_syslog); is_eq(tap_ev_identifier(ev), "syslog", "SXEL43() calls syslog()"); is(tap_ev_arg(ev, "priority"), LOG_INFO, "SXEL43() maps to LOG_INFO syslog level"); is_eq(tap_ev_arg(ev, "logline"), expected, "SXEL43() is logged correctly"); SXEL54("SXEL54(%s,%d,%u,%x)", "arg1", 22, 44, 64); snprintf(expected, sizeof expected, "T=%d ------ 5 - SXEL54(arg1,22,44,40)\n", pid); ev = tap_ev_queue_shift(q_syslog); is_eq(tap_ev_identifier(ev), "syslog", "SXEL54() calls syslog()"); is(tap_ev_arg(ev, "priority"), LOG_DEBUG, "SXEL54() maps to LOG_DEBUG syslog level"); is_eq(tap_ev_arg(ev, "logline"), expected, "SXEL54() is logged correctly"); SXEL65("SXEL65(%s,%d,%u,%x,%.2f)", "arg1", 22, 44, 64, 3.1415926); snprintf(expected, sizeof expected, "T=%d ------ 6 - SXEL65(arg1,22,44,40,3.14)\n", pid); ev = tap_ev_queue_shift(q_syslog); is_eq(tap_ev_identifier(ev), "syslog", "SXEL65() calls syslog()"); is(tap_ev_arg(ev, "priority"), LOG_DEBUG, "SXEL65() maps to LOG_DEBUG syslog level"); is_eq(tap_ev_arg(ev, "logline"), expected, "SXEL65() is logged correctly"); this->id = 99; SXEL10I("SXEL10I"); snprintf(expected, sizeof expected, "T=%d 99 1 - SXEL10I\n", pid); ev = tap_ev_queue_shift(q_syslog); is_eq(tap_ev_identifier(ev), "syslog", "SXEL10I() calls syslog()"); is(tap_ev_arg(ev, "priority"), LOG_ERR, "SXEL10I() maps to LOG_ERR syslog level"); is_eq(tap_ev_arg(ev, "logline"), expected, "SXEL10I() is logged correctly"); this->id = 98; SXEL65I("SXEL65I(%s,%d,%u,%x,%.2f)", "arg1", 22, 44, 64, 3.1415926); snprintf(expected, sizeof expected, "T=%d 98 6 - SXEL65I(arg1,22,44,40,3.14)\n", pid); ev = tap_ev_queue_shift(q_syslog); is_eq(tap_ev_identifier(ev), "syslog", "SXEL65I() calls syslog()"); is(tap_ev_arg(ev, "priority"), LOG_DEBUG, "SXEL65I() maps to LOG_DEBUG syslog level"); is_eq(tap_ev_arg(ev, "logline"), expected, "SXEL65I() is logged correctly"); sxe_log_hook_buffer_prefix(NULL); /* For coverage */ (void)argc; (void)argv; return exit_status(); }
int main(void) { SXE_HTTPD httpd; SXE_HTTPD_REQUEST * request; tap_ev ev; SXE * listener; SXE * c; SXE * c2; char buffer[1024]; tap_plan(24, TAP_FLAG_ON_FAILURE_EXIT, NULL); test_sxe_register_and_init(12); sxe_httpd_construct(&httpd, 3, 10, 512, 0); SXE_HTTPD_SET_HANDLER(&httpd, connect, h_connect); SXE_HTTPD_SET_HANDLER(&httpd, request, h_request); SXE_HTTPD_SET_HANDLER(&httpd, header, h_header); SXE_HTTPD_SET_HANDLER(&httpd, eoh, h_eoh); SXE_HTTPD_SET_HANDLER(&httpd, body, h_body); SXE_HTTPD_SET_HANDLER(&httpd, respond, h_respond); SXE_HTTPD_SET_HANDLER(&httpd, close, h_close); listener = test_httpd_listen(&httpd, "0.0.0.0", 0); c = test_new_tcp(NULL, "0.0.0.0", 0, client_connect, client_read, NULL); sxe_connect(c, "127.0.0.1", SXE_LOCAL_PORT(listener)); is_eq(test_tap_ev_queue_identifier_wait(q_client, TEST_WAIT, &ev), "client_connect", "1st Client connected to HTTPD"); TEST_SXE_SEND_LITERAL(c, "POST /this/is/a/URL HTTP/1.1\r\nContent-Length: 10\r\n\r\n12345678\r\n", client_sent, q_client, TEST_WAIT, &ev); is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &ev), "h_connect", "HTTPD: connected"); is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &ev), "h_request", "HTTPD: new request"); is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &ev), "h_header", "HTTPD: header event"); is_strncmp(tap_ev_arg(ev, "key"), "Content-Length", SXE_LITERAL_LENGTH("Content-Length"), "HTTPD: header was 'Connect'"); is_strncmp(tap_ev_arg(ev, "value"), "10", SXE_LITERAL_LENGTH("10"), "HTTPD: header value was 'whatever'"); is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &ev), "h_eoh", "HTTPD: eoh (end of headers) event"); test_ev_queue_wait_read(q_httpd, TEST_WAIT, &ev, NULL, "h_body", buffer, 10, "HTTPD body handler"); is_strncmp(buffer, "12345678\r\n", SXE_LITERAL_LENGTH("12345678\r\n"), "HTTPD: read correct body"); /* httpd is still in "req_response" state */ is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &ev), "h_respond", "HTTPD: respond event"); /* Extra data from client, e.g., "content-length" is wrong and shorter than real packet */ TEST_SXE_SEND_LITERAL(c, "AB", client_sent, q_client, TEST_WAIT, &ev); /* Send another valid request again, the connection is in "sink" mode now, data will get ignored */ TEST_SXE_SEND_LITERAL(c, "POST /this/is/a/URL HTTP/1.1\r\nContent-Length: 10\r\n\r\n12345678\r\n", client_sent, q_client, TEST_WAIT, &ev); test_process_all_libev_events(); /* In sink mode, no more httpd events */ is(tap_ev_queue_length(q_httpd), 0, "No lurking httpd events"); /* New client connection should not be affected */ c2 = test_new_tcp(NULL, "0.0.0.0", 0, client_connect, client_read, client_close); sxe_connect(c2, "127.0.0.1", SXE_LOCAL_PORT(listener)); is_eq(test_tap_ev_queue_identifier_wait(q_client, TEST_WAIT, &ev), "client_connect", "2nd Client connected to HTTPD"); is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &ev), "h_connect", "HTTPD: connected"); TEST_SXE_SEND_LITERAL(c2, "GET /simple HTTP/1.1\r\n\r\n", client_sent, q_client, TEST_WAIT, &ev); is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &ev), "h_request", "HTTPD: new request"); is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &ev), "h_eoh", "HTTPD: eoh (end of headers) event"); is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &ev), "h_respond", "HTTPD: respond event"); request = (SXE_HTTPD_REQUEST *)(long)tap_ev_arg(ev, "request"); sxe_httpd_response_simple(request, h_sent, NULL, 200, "OK", NULL, "Connection", "close", NULL); is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &ev), "h_sent", "HTTPD: finished responding"); sxe_close(request->sxe); #define TEST_200_CLOSE_RESPONSE "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Length: 0\r\n\r\n" test_ev_queue_wait_read(q_client, TEST_WAIT, &ev, c2, "client_read", buffer, SXE_LITERAL_LENGTH(TEST_200_CLOSE_RESPONSE), "client"); is_strncmp(buffer, TEST_200_CLOSE_RESPONSE, SXE_LITERAL_LENGTH(TEST_200_CLOSE_RESPONSE), "GET response is a 200 OK with close"); is_eq(test_tap_ev_queue_identifier_wait(q_client, TEST_WAIT, &ev), "client_close", "Got a client close event"); return exit_status(); }