From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: tarantool-patches@freelists.org Cc: kostja@tarantool.org Subject: [tarantool-patches] [PATCH 2/6] test: introduce breakpoints for swim's event loop Date: Wed, 20 Mar 2019 13:49:15 +0300 [thread overview] Message-ID: <fb3133cd05b2b14dd7dcb16a892cd1af417699ab.1553078631.git.v.shpilevoy@tarantool.org> (raw) In-Reply-To: <cover.1553078631.git.v.shpilevoy@tarantool.org> In-Reply-To: <cover.1553078631.git.v.shpilevoy@tarantool.org> Breakpoint as API gives a test writer more control over timing of condition checks. Breakpoint stops the swim's event loop in a certain moment of virtual time. Without breakpoints it is possible, that a condition has failed its deadline, but it can not be checked properly. For example, assume that there is a cluster of two members, and after 1 second they should become fullmesh. It means, that any checks in [0, 1) time have to fail. But without breakpoints it is not so: // event_queue: [round_step, 1 sec] // time: 0 swim_cluster_wait_fullmesh(cluster, 0.5); // Fails. // event_queue: [] // time: 1 swim_cluster_wait_fullmesh(cluster, 0.1); // Success. The second test should fail, but it does not, because global time is already 1 after the first test and the cluster is in fullmesh already. It looks weird, so such checks should be done not later than deadline. Follow-up for 03b9a6e91baf246ee2bb9841d01ba3824b6768a6 --- test/unit/swim.c | 6 ++++-- test/unit/swim.result | 5 +++-- test/unit/swim_test_ev.c | 39 +++++++++++++++++++++++++++++++++++++ test/unit/swim_test_ev.h | 8 ++++++++ test/unit/swim_test_utils.c | 26 ++++++++++++++++++------- 5 files changed, 73 insertions(+), 11 deletions(-) diff --git a/test/unit/swim.c b/test/unit/swim.c index 921fc8f07..3a97aeb18 100644 --- a/test/unit/swim.c +++ b/test/unit/swim.c @@ -50,7 +50,7 @@ static int test_result; static void swim_test_one_link(void) { - swim_start_test(1); + swim_start_test(2); /* * Run a simple cluster of two elements. One of them * learns about another explicitly. Another should add the @@ -58,7 +58,9 @@ swim_test_one_link(void) */ struct swim_cluster *cluster = swim_cluster_new(2); fail_if(swim_cluster_add_link(cluster, 0, 1) != 0); - is(swim_cluster_wait_fullmesh(cluster, 1), 0, "one link"); + is(swim_cluster_wait_fullmesh(cluster, 0.9), -1, + "no rounds - no fullmesh"); + is(swim_cluster_wait_fullmesh(cluster, 0.1), 0, "one link"); swim_cluster_delete(cluster); swim_finish_test(); diff --git a/test/unit/swim.result b/test/unit/swim.result index e8991d8d8..b58325b73 100644 --- a/test/unit/swim.result +++ b/test/unit/swim.result @@ -1,8 +1,9 @@ *** main_f *** 1..5 *** swim_test_one_link *** - 1..1 - ok 1 - one link + 1..2 + ok 1 - no rounds - no fullmesh + ok 2 - one link ok 1 - subtests *** swim_test_one_link: done *** *** swim_test_sequence *** diff --git a/test/unit/swim_test_ev.c b/test/unit/swim_test_ev.c index ee1fcdbb7..d4a0a4752 100644 --- a/test/unit/swim_test_ev.c +++ b/test/unit/swim_test_ev.c @@ -55,6 +55,7 @@ static int event_id = 0; enum swim_event_type { SWIM_EVENT_TIMER, SWIM_EVENT_FD_UNBLOCK, + SWIM_EVENT_BRK, }; struct swim_event; @@ -250,6 +251,44 @@ swim_test_ev_block_fd(int fd, double delay) e->fd = fd; } +/** + * Breakpoint event for debug. It does nothing but stops the event + * loop after a timeout to allow highlevel API to check some + * cases. + */ +struct swim_brk_event { + struct swim_event base; +}; + +/** Delete a breakpoint event. */ +static void +swim_brk_event_delete(struct swim_event *e) +{ + assert(e->type == SWIM_EVENT_BRK); + swim_event_destroy(e); + free(e); +} + +/** + * Breakpoint event processing is nothing but the event deletion. + */ +static void +swim_brk_event_process(struct swim_event *e, struct ev_loop *loop) +{ + (void) loop; + assert(e->type == SWIM_EVENT_BRK); + swim_brk_event_delete(e); +} + +void +swim_ev_set_brk(double delay) +{ + struct swim_brk_event *e = (struct swim_brk_event *) malloc(sizeof(*e)); + assert(e != NULL); + swim_event_create(&e->base, SWIM_EVENT_BRK, delay, + swim_brk_event_process, swim_brk_event_delete); +} + /** Implementation of global time visible in SWIM. */ double swim_time(void) diff --git a/test/unit/swim_test_ev.h b/test/unit/swim_test_ev.h index 808bc510e..01a1b8868 100644 --- a/test/unit/swim_test_ev.h +++ b/test/unit/swim_test_ev.h @@ -51,6 +51,14 @@ swim_test_ev_free(void); void swim_test_ev_block_fd(int fd, double delay); +/** + * Stop the event loop after @a delay fake seconds. It does not + * affect other events, so the loop can stop earlier multiple + * times. + */ +void +swim_ev_set_brk(double delay); + /** Play one step of event loop, process generated events. */ void swim_do_loop_step(struct ev_loop *loop); diff --git a/test/unit/swim_test_utils.c b/test/unit/swim_test_utils.c index a92e55233..0b301333b 100644 --- a/test/unit/swim_test_utils.c +++ b/test/unit/swim_test_utils.c @@ -129,16 +129,28 @@ swim_cluster_is_fullmesh(struct swim_cluster *cluster) return true; } +/** + * A common wrapper for some conditions checking after each event + * loop step. + */ +#define swim_wait_timeout(timeout, target_cond) ({ \ + swim_ev_set_brk(timeout); \ + double deadline = swim_time() + timeout; \ + int rc = 0; \ + while (! (target_cond)) { \ + if (swim_time() >= deadline) { \ + rc = -1; \ + break; \ + } \ + swim_do_loop_step(loop()); \ + } \ + rc; \ +}) + int swim_cluster_wait_fullmesh(struct swim_cluster *cluster, double timeout) { - double deadline = swim_time() + timeout; - while (! swim_cluster_is_fullmesh(cluster)) { - if (swim_time() >= deadline) - return -1; - swim_do_loop_step(loop()); - } - return 0; + return swim_wait_timeout(timeout, swim_cluster_is_fullmesh(cluster)); } bool -- 2.17.2 (Apple Git-113)
next prev parent reply other threads:[~2019-03-20 10:49 UTC|newest] Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-03-20 10:49 [tarantool-patches] [PATCH 0/6] SWIM failure detection draft Vladislav Shpilevoy 2019-03-20 10:49 ` [tarantool-patches] [PATCH 1/6] swim: follow-ups for SWIM anti-entropy Vladislav Shpilevoy 2019-03-29 8:27 ` [tarantool-patches] " Konstantin Osipov 2019-03-29 10:19 ` Vladislav Shpilevoy 2019-03-20 10:49 ` Vladislav Shpilevoy [this message] 2019-03-29 18:20 ` [tarantool-patches] Re: [PATCH 2/6] test: introduce breakpoints for swim's event loop Konstantin Osipov 2019-04-02 12:25 ` Vladislav Shpilevoy 2019-04-02 19:16 ` Vladislav Shpilevoy 2019-04-02 20:40 ` Konstantin Osipov 2019-04-02 21:26 ` Vladislav Shpilevoy 2019-03-20 10:49 ` [tarantool-patches] [PATCH 3/6] test: remove swim_unblock_fd event from swim test harness Vladislav Shpilevoy 2019-03-29 18:22 ` [tarantool-patches] " Konstantin Osipov 2019-04-02 21:26 ` Vladislav Shpilevoy 2019-03-20 10:49 ` [tarantool-patches] [PATCH 4/6] swim: expose enum swim_member_status to public API Vladislav Shpilevoy 2019-03-29 18:24 ` [tarantool-patches] " Konstantin Osipov 2019-04-02 12:25 ` Vladislav Shpilevoy 2019-04-02 13:17 ` Konstantin Osipov 2019-04-02 21:26 ` Vladislav Shpilevoy 2019-03-20 10:49 ` [tarantool-patches] [PATCH 5/6] test: differentiate blocked and closed swim fake fds Vladislav Shpilevoy 2019-03-29 18:25 ` [tarantool-patches] " Konstantin Osipov 2019-04-02 21:26 ` Vladislav Shpilevoy 2019-03-20 10:49 ` [tarantool-patches] [PATCH 6/6] [RAW] swim: introduce failure detection component Vladislav Shpilevoy 2019-03-29 18:59 ` [tarantool-patches] " Konstantin Osipov 2019-04-02 12:25 ` Vladislav Shpilevoy 2019-04-04 10:20 ` Vladislav Shpilevoy 2019-04-04 12:45 ` Konstantin Osipov 2019-04-04 13:57 ` Vladislav Shpilevoy 2019-04-04 16:14 ` Vladimir Davydov 2019-04-04 16:47 ` Vladislav Shpilevoy 2019-03-27 19:28 ` [tarantool-patches] [PATCH 7/6] swim: make swim_upsert_member returning two values Vladislav Shpilevoy 2019-03-28 8:52 ` [tarantool-patches] " Konstantin Osipov 2019-03-28 11:52 ` Vladislav Shpilevoy
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=fb3133cd05b2b14dd7dcb16a892cd1af417699ab.1553078631.git.v.shpilevoy@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=kostja@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [PATCH 2/6] test: introduce breakpoints for swim'\''s event loop' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox