From 3ac1088039a3c5315c4a336775b31e08671ddd81 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 25 Jul 2021 16:36:25 +0200 Subject: -extend tests, include reconnect handling for events --- src/pq/pq.h | 11 +++++ src/pq/pq_connect.c | 1 + src/pq/pq_event.c | 36 ++++++++++++++++ src/pq/test_pq.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 167 insertions(+), 2 deletions(-) diff --git a/src/pq/pq.h b/src/pq/pq.h index bad99b307..107fd116c 100644 --- a/src/pq/pq.h +++ b/src/pq/pq.h @@ -94,4 +94,15 @@ struct GNUNET_PQ_Context bool scheduler_on; }; + +/** + * Internal API. Reconnect should re-register notifications + * after a disconnect. + * + * @param db the DB handle + */ +void +GNUNET_PQ_event_reconnect_ (struct GNUNET_PQ_Context *db); + + #endif diff --git a/src/pq/pq_connect.c b/src/pq/pq_connect.c index 8722d2151..4e614526b 100644 --- a/src/pq/pq_connect.c +++ b/src/pq/pq_connect.c @@ -416,6 +416,7 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) db->conn = NULL; return; } + GNUNET_PQ_event_reconnect_ (db); if ( (NULL != db->sc) && (0 != GNUNET_CONTAINER_multishortmap_size (db->channel_map)) ) db->sc (db->sc_cls, diff --git a/src/pq/pq_event.c b/src/pq/pq_event.c index 879caf842..74b8b3653 100644 --- a/src/pq/pq_event.c +++ b/src/pq/pq_event.c @@ -365,6 +365,42 @@ manage_subscribe (struct GNUNET_PQ_Context *db, } +/** + * Re-subscribe to notifications after disconnect. + * + * @param cls the DB context + * @param sh the short hash of the channel + * @param eh the event handler + * @return #GNUNET_OK to continue to iterate + */ +static int +register_notify (void *cls, + const struct GNUNET_ShortHashCode *sh, + void *value) +{ + struct GNUNET_PQ_Context *db = cls; + struct GNUNET_PQ_EventHandler *eh = value; + + manage_subscribe (db, + "LISTEN ", + eh); + return GNUNET_OK; +} + + +void +GNUNET_PQ_event_reconnect_ (struct GNUNET_PQ_Context *db) +{ + GNUNET_assert (0 == + pthread_mutex_lock (&db->notify_lock)); + GNUNET_CONTAINER_multishortmap_iterate (db->channel_map, + ®ister_notify, + db); + GNUNET_assert (0 == + pthread_mutex_unlock (&db->notify_lock)); +} + + struct GNUNET_PQ_EventHandler * GNUNET_PQ_event_listen (struct GNUNET_PQ_Context *db, const struct GNUNET_PQ_EventHeaderP *es, diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c index b3747dfc3..1df1cd126 100644 --- a/src/pq/test_pq.c +++ b/src/pq/test_pq.c @@ -25,6 +25,26 @@ #include "platform.h" #include "pq.h" +/** + * Database handle. + */ +static struct GNUNET_PQ_Context *db; + +/** + * Global return value, 0 on success. + */ +static int ret; + +/** + * An event handler. + */ +static struct GNUNET_PQ_EventHandler *eh; + +/** + * Timeout task. + */ +static struct GNUNET_SCHEDULER_Task *tt; + /** * Setup prepared statements. @@ -277,6 +297,91 @@ test_notify (struct GNUNET_PQ_Context *db) } +/** + * Task called on shutdown. + * + * @param cls NULL + */ +static void +event_end (void *cls) +{ + GNUNET_PQ_event_scheduler_stop (db); + GNUNET_PQ_event_listen_cancel (eh); + eh = NULL; + if (NULL != tt) + { + GNUNET_SCHEDULER_cancel (tt); + tt = NULL; + } +} + + +/** + * Task called on timeout. Should not happen, means + * we did not get the expected event. + * + * @param cls NULL + */ +static void +timeout_cb (void *cls) +{ + ret = 2; + GNUNET_break (0); + tt = NULL; + GNUNET_SCHEDULER_shutdown (); +} + + +/** + * Task called on expected event + * + * @param cls NULL + */ +static void +event_sched_cb (void *cls, + const void *extra, + size_t extra_size) +{ + GNUNET_assert (5 == extra_size); + GNUNET_assert (0 == + memcmp ("hello", + extra, + 5)); + GNUNET_SCHEDULER_shutdown (); +} + + +/** + * Run tests that need a scheduler. + * + * @param cls NULL + */ +static void +sched_tests (void *cls) +{ + struct GNUNET_PQ_EventHeaderP es = { + .size = htons (sizeof (es)), + .type = htons (42) + }; + + + tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, + &timeout_cb, + NULL); + GNUNET_PQ_event_scheduler_start (db); + eh = GNUNET_PQ_event_listen (db, + &es, + &event_sched_cb, + NULL); + GNUNET_PQ_reconnect (db); + GNUNET_SCHEDULER_add_shutdown (&event_end, + NULL); + GNUNET_PQ_event_notify (db, + &es, + "hello", + 5); +} + int main (int argc, @@ -297,8 +402,6 @@ main (int argc, ")"), GNUNET_PQ_EXECUTE_STATEMENT_END }; - struct GNUNET_PQ_Context *db; - int ret; GNUNET_log_setup ("test-pq", "WARNING", @@ -332,6 +435,20 @@ main (int argc, ret = run_queries (db); ret |= test_notify (db); ret |= test_notify (db); + if (0 != ret) + { + GNUNET_break (0); + GNUNET_PQ_disconnect (db); + return ret; + } + GNUNET_SCHEDULER_run (&sched_tests, + NULL); + if (0 != ret) + { + GNUNET_break (0); + GNUNET_PQ_disconnect (db); + return ret; + } #if TEST_RESTART fprintf (stderr, "Please restart Postgres database now!\n"); sleep (60); -- cgit v1.2.3