From 810651e04c53d2c030afb91a6cc63299b9aa5891 Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Tue, 17 May 2011 01:17:48 +0200 Subject: [PATCH] Update tests & benchmarks to use the new timer api --- msvs/libuv-test.vcxproj | 2 +- test/benchmark-pump.c | 29 ++++---- test/test-callback-stack.c | 32 +++++---- test/test-delayed-accept.c | 31 +++++---- test/test-list.h | 4 +- test/test-loop-handles.c | 31 +++++---- test/test-timeout.c | 105 ---------------------------- test/test-timer.c | 139 +++++++++++++++++++++++++++++++++++++ 8 files changed, 210 insertions(+), 163 deletions(-) delete mode 100644 test/test-timeout.c create mode 100644 test/test-timer.c diff --git a/msvs/libuv-test.vcxproj b/msvs/libuv-test.vcxproj index 0a8ff79d..14f25c07 100644 --- a/msvs/libuv-test.vcxproj +++ b/msvs/libuv-test.vcxproj @@ -155,7 +155,7 @@ - + diff --git a/test/benchmark-pump.c b/test/benchmark-pump.c index 7ac19f26..d5a7ffc9 100644 --- a/test/benchmark-pump.c +++ b/test/benchmark-pump.c @@ -65,6 +65,8 @@ static char write_buffer[WRITE_BUFFER_SIZE]; static uv_handle_t read_handles[TARGET_CONNECTIONS]; static uv_handle_t write_handles[TARGET_CONNECTIONS]; +static uv_handle_t timer_handle; + static double gbit(int64_t bytes, int64_t passed_ms) { double gbits = ((double)bytes / (1024 * 1024 * 1024)) * 8; @@ -72,14 +74,12 @@ static double gbit(int64_t bytes, int64_t passed_ms) { } -static void show_stats(uv_req_t *req, int64_t skew, int status) { - int64_t msec = STATS_INTERVAL + skew; - +static void show_stats(uv_handle_t *handle, int status) { #if PRINT_STATS LOGF("connections: %d, read: %.1f gbit/s, write: %.1f gbit/s\n", read_sockets, - gbit(nrecv, msec), - gbit(nsent, msec)); + gbit(nrecv, STATS_INTERVAL), + gbit(nsent, STATS_INTERVAL)); #endif /* Exit if the show is over */ @@ -97,10 +97,11 @@ static void show_stats(uv_req_t *req, int64_t skew, int status) { /* Reset read and write counters */ nrecv = 0; nsent = 0; +} - uv_timeout(req, (STATS_INTERVAL - skew > 0) - ? STATS_INTERVAL - skew - : 0); + +void close_cb(uv_handle_t* handle, int status) { + ASSERT(status == 0); } @@ -108,16 +109,12 @@ static void start_stats_collection() { uv_req_t* req = req_alloc(); int r; - /* Show-stats timeout */ + /* Show-stats timer */ stats_left = STATS_COUNT; - uv_req_init(req, NULL, (void*)show_stats); - r = uv_timeout(req, STATS_INTERVAL); + r = uv_timer_init(&timer_handle, close_cb, NULL); + ASSERT(r == 0); + r = uv_timer_start(&timer_handle, show_stats, STATS_INTERVAL, STATS_INTERVAL); ASSERT(r == 0); -} - - -void close_cb(uv_handle_t* handle, int status) { - ASSERT(status == 0); } diff --git a/test/test-callback-stack.c b/test/test-callback-stack.c index 5d843b4d..d136c9a7 100644 --- a/test/test-callback-stack.c +++ b/test/test-callback-stack.c @@ -30,14 +30,14 @@ static const char MESSAGE[] = "Failure is for the weak. Everyone dies alone."; -static uv_handle_t client; -static uv_req_t connect_req, write_req, timeout_req, shutdown_req; +static uv_handle_t client, timer; +static uv_req_t connect_req, write_req, shutdown_req; static int nested = 0; static int close_cb_called = 0; static int connect_cb_called = 0; static int write_cb_called = 0; -static int timeout_cb_called = 0; +static int timer_cb_called = 0; static int bytes_received = 0; static int shutdown_cb_called = 0; @@ -100,9 +100,12 @@ static void read_cb(uv_handle_t* handle, int nread, uv_buf_t buf) { } -static void timeout_cb(uv_req_t* req, int64_t skew, int status) { +static void timer_cb(uv_handle_t* handle, int status) { + int r; + + ASSERT(handle == &timer); ASSERT(status == 0); - ASSERT(nested == 0 && "timeout_cb must be called from a fresh stack"); + ASSERT(nested == 0 && "timer_cb must be called from a fresh stack"); puts("Timeout complete. Now read data..."); @@ -112,11 +115,16 @@ static void timeout_cb(uv_req_t* req, int64_t skew, int status) { } nested--; - timeout_cb_called++; + timer_cb_called++; + + r = uv_close(handle); + ASSERT(r == 0); } static void write_cb(uv_req_t* req, int status) { + int r; + ASSERT(status == 0); ASSERT(nested == 0 && "write_cb must be called from a fresh stack"); @@ -127,10 +135,10 @@ static void write_cb(uv_req_t* req, int status) { /* back to our receive buffer when we start reading. This maximizes the */ /* tempation for the backend to use dirty stack for calling read_cb. */ nested++; - uv_req_init(&timeout_req, NULL, timeout_cb); - if (uv_timeout(&timeout_req, 500)) { - FATAL("uv_timeout failed"); - } + r = uv_timer_init(&timer, close_cb, NULL); + ASSERT(r == 0); + r = uv_timer_start(&timer, timer_cb, 500, 0); + ASSERT(r == 0); nested--; write_cb_called++; @@ -194,10 +202,10 @@ TEST_IMPL(callback_stack) { ASSERT(nested == 0); ASSERT(connect_cb_called == 1 && "connect_cb must be called exactly once"); ASSERT(write_cb_called == 1 && "write_cb must be called exactly once"); - ASSERT(timeout_cb_called == 1 && "timeout_cb must be called exactly once"); + ASSERT(timer_cb_called == 1 && "timer_cb must be called exactly once"); ASSERT(bytes_received == sizeof MESSAGE); ASSERT(shutdown_cb_called == 1 && "shutdown_cb must be called exactly once"); - ASSERT(close_cb_called == 1 && "close_cb must be called exactly once"); + ASSERT(close_cb_called == 2 && "close_cb must be called exactly twice"); return 0; } diff --git a/test/test-delayed-accept.c b/test/test-delayed-accept.c index 796ee19e..e372b955 100644 --- a/test/test-delayed-accept.c +++ b/test/test-delayed-accept.c @@ -43,42 +43,49 @@ static void close_cb(uv_handle_t* handle, int status) { } -static void do_accept(uv_req_t* req, int64_t skew, int status) { +static void do_accept(uv_handle_t* timer_handle, int status) { uv_handle_t* server; uv_handle_t* accepted_handle = (uv_handle_t*)malloc(sizeof *accepted_handle); int r; - ASSERT(req != NULL); + ASSERT(timer_handle != NULL); ASSERT(status == 0); ASSERT(accepted_handle != NULL); - server = (uv_handle_t*)req->data; + server = (uv_handle_t*)timer_handle->data; r = uv_accept(server, accepted_handle, close_cb, NULL); ASSERT(r == 0); do_accept_called++; /* Immediately close the accepted handle. */ - uv_close(accepted_handle); + r = uv_close(accepted_handle); + ASSERT(r == 0); /* After accepting the two clients close the server handle */ if (do_accept_called == 2) { - uv_close(server); + r = uv_close(server); + ASSERT(r == 0); } - free(req); + /* Dispose the timer. */ + r = uv_close(timer_handle); + ASSERT(r == 0); } static void accept_cb(uv_handle_t* handle) { - uv_req_t* timeout_req = (uv_req_t*)malloc(sizeof *timeout_req); + int r; + uv_handle_t* timer_handle; - ASSERT(timeout_req != NULL); + timer_handle = (uv_handle_t*)malloc(sizeof *timer_handle); + ASSERT(timer_handle != NULL); /* Accept the client after 1 second */ - uv_req_init(timeout_req, NULL, &do_accept); - timeout_req->data = (void*)handle; - uv_timeout(timeout_req, 1000); + r = uv_timer_init(timer_handle, close_cb, (void*)handle); + ASSERT(r == 0); + r = uv_timer_start(timer_handle, do_accept, 1000, 0); + ASSERT(r == 0); accept_cb_called++; } @@ -173,7 +180,7 @@ TEST_IMPL(delayed_accept) { ASSERT(accept_cb_called == 2); ASSERT(do_accept_called == 2); ASSERT(connect_cb_called == 2); - ASSERT(close_cb_called == 5); + ASSERT(close_cb_called == 7); return 0; } diff --git a/test/test-list.h b/test/test-list.h index 0cf3518b..e6db49a5 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -29,7 +29,7 @@ TEST_DECLARE (bind_error_fault) TEST_DECLARE (bind_error_inval) TEST_DECLARE (connection_fail) TEST_DECLARE (callback_stack) -TEST_DECLARE (timeout) +TEST_DECLARE (timer) TEST_DECLARE (loop_handles) TEST_DECLARE (async) TEST_DECLARE (fail_always) @@ -60,7 +60,7 @@ TASK_LIST_START TEST_ENTRY (callback_stack) TEST_HELPER (callback_stack, echo_server) - TEST_ENTRY (timeout) + TEST_ENTRY (timer) TEST_ENTRY (loop_handles) diff --git a/test/test-loop-handles.c b/test/test-loop-handles.c index ae95c036..7b2c27c7 100644 --- a/test/test-loop-handles.c +++ b/test/test-loop-handles.c @@ -58,9 +58,9 @@ * being started by a check_1 watcher. It verifies that a watcher is * implicitly stopped when closed, and that a watcher can close itself * safely. - * - There is a timeout request that reposts itself after every timeout. It - * does not keep te event loop alive (ev_unref) but makes sure that the loop - * keeps polling the system for events. + * - There is a repeating timer. It does not keep te event loop alive + * (ev_unref) but makes sure that the loop keeps polling the system for + * events. */ @@ -83,7 +83,7 @@ static uv_handle_t check_handle; static uv_handle_t idle_1_handles[IDLE_COUNT]; static uv_handle_t idle_2_handle; -static uv_req_t timeout_req; +static uv_handle_t timer_handle; static int loop_iteration = 0; @@ -106,19 +106,19 @@ static int idle_2_close_cb_called = 0; static int idle_2_cb_started = 0; static int idle_2_is_active = 0; -static int timeout_cb_called = 0; +static int timer_cb_called = 0; -static void timeout_cb(uv_req_t *req, int64_t skew, int status) { - int r; - - ASSERT(req == &timeout_req); +static void timer_cb(uv_handle_t* handle, int status) { + ASSERT(handle == &timer_handle); ASSERT(status == 0); - timeout_cb_called++; + timer_cb_called++; +} - r = uv_timeout(req, TIMEOUT); - ASSERT(r == 0); + +static void timer_close_cb(uv_handle_t* handle, int status) { + FATAL("timer_close_cb should not be called"); } @@ -350,8 +350,9 @@ TEST_IMPL(loop_handles) { /* the timer callback is there to keep the event loop polling */ /* unref it as it is not supposed to keep the loop alive */ - uv_req_init(&timeout_req, NULL, timeout_cb); - r = uv_timeout(&timeout_req, TIMEOUT); + r = uv_timer_init(&timer_handle, timer_close_cb, NULL); + ASSERT(r == 0); + r = uv_timer_start(&timer_handle, timer_cb, TIMEOUT, TIMEOUT); ASSERT(r == 0); uv_unref(); @@ -379,7 +380,7 @@ TEST_IMPL(loop_handles) { ASSERT(idle_2_close_cb_called == idle_2_cb_started); ASSERT(idle_2_is_active == 0); - ASSERT(timeout_cb_called > 0); + ASSERT(timer_cb_called > 0); return 0; } diff --git a/test/test-timeout.c b/test/test-timeout.c deleted file mode 100644 index 07c8f0fb..00000000 --- a/test/test-timeout.c +++ /dev/null @@ -1,105 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "../uv.h" -#include "task.h" - - -static int expected = 0; -static int timeouts = 0; - -static int64_t start_time; - -static void timeout_cb(uv_req_t *req, int64_t skew, int status) { - ASSERT(req != NULL); - ASSERT(status == 0); - - free(req); - timeouts++; - - /* Just call this randomly for the code coverage. */ - uv_update_time(); -} - -static void exit_timeout_cb(uv_req_t *req, int64_t skew, int status) { - int64_t now = uv_now(); - ASSERT(req != NULL); - ASSERT(status == 0); - ASSERT(timeouts == expected); - ASSERT(start_time < now); - exit(0); -} - -static void dummy_timeout_cb(uv_req_t *req, int64_t skew, int status) { - /* Should never be called */ - FATAL("dummy_timer_cb should never be called"); -} - - -static uv_buf_t alloc_cb(uv_handle_t* handle, size_t size) { - uv_buf_t buf = {0, 0}; - FATAL("alloc should not be called"); - return buf; -} - - -TEST_IMPL(timeout) { - uv_req_t *req; - uv_req_t exit_req; - uv_req_t dummy_req; - int i; - - uv_init(alloc_cb); - - start_time = uv_now(); - ASSERT(0 < start_time); - - /* Let 10 timers time out in 500 ms total. */ - for (i = 0; i < 10; i++) { - req = (uv_req_t*)malloc(sizeof(*req)); - ASSERT(req != NULL); - - uv_req_init(req, NULL, timeout_cb); - - if (uv_timeout(req, i * 50) < 0) { - FATAL("uv_timeout failed"); - } - - expected++; - } - - /* The 11th timer exits the test and runs after 1 s. */ - uv_req_init(&exit_req, NULL, exit_timeout_cb); - if (uv_timeout(&exit_req, 1000) < 0) { - FATAL("uv_timeout failed"); - } - - /* The 12th timer should never run. */ - uv_req_init(&dummy_req, NULL, dummy_timeout_cb); - if (uv_timeout(&dummy_req, 2000)) { - FATAL("uv_timeout failed"); - } - - uv_run(); - - FATAL("should never get here"); - return 2; -} diff --git a/test/test-timer.c b/test/test-timer.c new file mode 100644 index 00000000..f4bd65a9 --- /dev/null +++ b/test/test-timer.c @@ -0,0 +1,139 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "../uv.h" +#include "task.h" + + +static int once_cb_called = 0; +static int once_close_cb_called = 0; +static int repeat_cb_called = 0; +static int repeat_close_cb_called = 0; + +static int64_t start_time; + + +static void once_close_cb(uv_handle_t* handle, int status) { + ASSERT(handle != NULL); + ASSERT(status == 0); + + once_close_cb_called++; + + free(handle); +} + + +static void once_cb(uv_handle_t* handle, int status) { + ASSERT(handle != NULL); + ASSERT(status == 0); + + once_cb_called++; + + uv_close(handle); + + /* Just call this randomly for the code coverage. */ + uv_update_time(); +} + + +static void repeat_close_cb(uv_handle_t* handle, int status) { + ASSERT(handle != NULL); + ASSERT(status == 0); + + repeat_close_cb_called++; +} + + +static void repeat_cb(uv_handle_t* handle, int status) { + ASSERT(handle != NULL); + ASSERT(status == 0); + + repeat_cb_called++; + + if (repeat_cb_called == 5) { + uv_close(handle); + } +} + + +static void never_close_cb(uv_handle_t* handle, int status) { + FATAL("never_close_cb should never be called"); +} + + +static void never_cb(uv_handle_t* handle, int status) { + FATAL("never_cb should never be called"); +} + + +static uv_buf_t alloc_cb(uv_handle_t* handle, size_t size) { + uv_buf_t buf = {0, 0}; + FATAL("alloc should not be called"); + return buf; +} + + +TEST_IMPL(timer) { + uv_handle_t *once; + uv_handle_t repeat, never; + int i, r; + + uv_init(alloc_cb); + + start_time = uv_now(); + ASSERT(0 < start_time); + + /* Let 10 timers time out in 500 ms total. */ + for (i = 0; i < 10; i++) { + once = (uv_handle_t*)malloc(sizeof(*once)); + ASSERT(once != NULL); + r = uv_timer_init(once, once_close_cb, NULL); + ASSERT(r == 0); + r = uv_timer_start(once, once_cb, i * 50, 0); + ASSERT(r == 0); + } + + /* The 11th timer is a repeating timer that runs 5 times */ + r = uv_timer_init(&repeat, repeat_close_cb, NULL); + ASSERT(r == 0); + r = uv_timer_start(&repeat, repeat_cb, 100, 100); + ASSERT(r == 0); + + /* The 12th timer should not do anything. */ + r = uv_timer_init(&never, never_close_cb, NULL); + ASSERT(r == 0); + r = uv_timer_start(&never, never_cb, 100, 100); + ASSERT(r == 0); + r = uv_timer_stop(&never); + ASSERT(r == 0); + uv_unref(); + + uv_run(); + + ASSERT(once_cb_called == 10); + ASSERT(once_close_cb_called == 10); + ASSERT(repeat_cb_called == 5); + ASSERT(repeat_close_cb_called == 1); + + ASSERT(500 <= uv_now() - start_time); + + return 0; +}