aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <grothoff@gnunet.org>2021-07-24 22:50:22 +0200
committerChristian Grothoff <grothoff@gnunet.org>2021-07-24 22:50:22 +0200
commitd63771f255057b27485c1fc96a0713d64d0ae1af (patch)
treee8b5ca287ec6283133bcb3ce49ba444253384b3a
parent31eae6bbe16302d2593b806ef3d2ac2ca9c2d8de (diff)
downloadgnunet-d63771f255057b27485c1fc96a0713d64d0ae1af.tar.gz
gnunet-d63771f255057b27485c1fc96a0713d64d0ae1af.zip
minimal test for new pq event functionality
-rw-r--r--src/pq/pq_connect.c84
-rw-r--r--src/pq/pq_event.c3
-rw-r--r--src/pq/test_pq.c64
3 files changed, 83 insertions, 68 deletions
diff --git a/src/pq/pq_connect.c b/src/pq/pq_connect.c
index 00664dcd0..8722d2151 100644
--- a/src/pq/pq_connect.c
+++ b/src/pq/pq_connect.c
@@ -24,6 +24,7 @@
24 */ 24 */
25#include "platform.h" 25#include "platform.h"
26#include "pq.h" 26#include "pq.h"
27#include <pthread.h>
27 28
28 29
29/** 30/**
@@ -63,28 +64,6 @@ pq_notice_processor_cb (void *arg,
63} 64}
64 65
65 66
66/**
67 * Create a connection to the Postgres database using @a config_str for the
68 * configuration. Initialize logging via GNUnet's log routines and disable
69 * Postgres's logger. Also ensures that the statements in @a load_path and @a
70 * es are executed whenever we (re)connect to the database, and that the
71 * prepared statements in @a ps are "ready". If statements in @es fail that
72 * were created with #GNUNET_PQ_make_execute(), then the entire operation
73 * fails.
74 *
75 * In @a load_path, a list of "$XXXX.sql" files is expected where $XXXX
76 * must be a sequence of contiguous integer values starting at 0000.
77 * These files are then loaded in sequence using "psql $config_str" before
78 * running statements from @e es. The directory is inspected again on
79 * reconnect.
80 *
81 * @param config_str configuration to use
82 * @param load_path path to directory with SQL transactions to run, can be NULL
83 * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated
84 * array of statements to execute upon EACH connection, can be NULL
85 * @param ps array of prepared statements to prepare, can be NULL
86 * @return NULL on error
87 */
88struct GNUNET_PQ_Context * 67struct GNUNET_PQ_Context *
89GNUNET_PQ_connect (const char *config_str, 68GNUNET_PQ_connect (const char *config_str,
90 const char *load_path, 69 const char *load_path,
@@ -122,6 +101,11 @@ GNUNET_PQ_connect (const char *config_str,
122 ps, 101 ps,
123 plen * sizeof (struct GNUNET_PQ_PreparedStatement)); 102 plen * sizeof (struct GNUNET_PQ_PreparedStatement));
124 } 103 }
104 db->channel_map = GNUNET_CONTAINER_multishortmap_create (16,
105 GNUNET_YES);
106 GNUNET_assert (0 ==
107 pthread_mutex_init (&db->notify_lock,
108 NULL));
125 GNUNET_PQ_reconnect (db); 109 GNUNET_PQ_reconnect (db);
126 if (NULL == db->conn) 110 if (NULL == db->conn)
127 { 111 {
@@ -142,7 +126,7 @@ GNUNET_PQ_connect (const char *config_str,
142 * @param i patch number to append to the @a load_path 126 * @param i patch number to append to the @a load_path
143 * @return #GNUNET_OK on success, #GNUNET_NO if patch @a i does not exist, #GNUNET_SYSERR on error 127 * @return #GNUNET_OK on success, #GNUNET_NO if patch @a i does not exist, #GNUNET_SYSERR on error
144 */ 128 */
145static int 129static enum GNUNET_GenericReturnValue
146apply_patch (struct GNUNET_PQ_Context *db, 130apply_patch (struct GNUNET_PQ_Context *db,
147 const char *load_path, 131 const char *load_path,
148 unsigned int i) 132 unsigned int i)
@@ -200,15 +184,6 @@ apply_patch (struct GNUNET_PQ_Context *db,
200} 184}
201 185
202 186
203/**
204 * Within the @a db context, run all the SQL files
205 * from the @a load_path from 0000-9999.sql (as long
206 * as the files exist contiguously).
207 *
208 * @param db database context to use
209 * @param load_path where to find the XXXX.sql files
210 * @return #GNUNET_OK on success
211 */
212enum GNUNET_GenericReturnValue 187enum GNUNET_GenericReturnValue
213GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db, 188GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db,
214 const char *load_path) 189 const char *load_path)
@@ -304,11 +279,6 @@ GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db,
304} 279}
305 280
306 281
307/**
308 * Reinitialize the database @a db if the connection is down.
309 *
310 * @param db database connection to reinitialize
311 */
312void 282void
313GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db) 283GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db)
314{ 284{
@@ -321,14 +291,12 @@ GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db)
321} 291}
322 292
323 293
324/**
325 * Reinitialize the database @a db.
326 *
327 * @param db database connection to reinitialize
328 */
329void 294void
330GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) 295GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db)
331{ 296{
297 if (NULL != db->sc)
298 db->sc (db->sc_cls,
299 -1);
332 if (NULL != db->conn) 300 if (NULL != db->conn)
333 PQfinish (db->conn); 301 PQfinish (db->conn);
334 db->conn = PQconnectdb (db->config_str); 302 db->conn = PQconnectdb (db->config_str);
@@ -448,26 +416,13 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db)
448 db->conn = NULL; 416 db->conn = NULL;
449 return; 417 return;
450 } 418 }
419 if ( (NULL != db->sc) &&
420 (0 != GNUNET_CONTAINER_multishortmap_size (db->channel_map)) )
421 db->sc (db->sc_cls,
422 PQsocket (db->conn));
451} 423}
452 424
453 425
454/**
455 * Connect to a postgres database using the configuration
456 * option "CONFIG" in @a section. Also ensures that the
457 * statements in @a es are executed whenever we (re)connect to the
458 * database, and that the prepared statements in @a ps are "ready".
459 *
460 * The caller does not have to ensure that @a es and @a ps remain allocated
461 * and initialized in memory until #GNUNET_PQ_disconnect() is called, as a copy will be made.
462 *
463 * @param cfg configuration
464 * @param section configuration section to use to get Postgres configuration options
465 * @param load_path_suffix suffix to append to the SQL_DIR in the configuration
466 * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated
467 * array of statements to execute upon EACH connection, can be NULL
468 * @param ps array of prepared statements to prepare, can be NULL
469 * @return the postgres handle, NULL on error
470 */
471struct GNUNET_PQ_Context * 426struct GNUNET_PQ_Context *
472GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, 427GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg,
473 const char *section, 428 const char *section,
@@ -509,15 +464,14 @@ GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg,
509} 464}
510 465
511 466
512/**
513 * Disconnect from the database, destroying the prepared statements
514 * and releasing other associated resources.
515 *
516 * @param db database handle to disconnect (will be free'd)
517 */
518void 467void
519GNUNET_PQ_disconnect (struct GNUNET_PQ_Context *db) 468GNUNET_PQ_disconnect (struct GNUNET_PQ_Context *db)
520{ 469{
470 GNUNET_assert (0 ==
471 GNUNET_CONTAINER_multishortmap_size (db->channel_map));
472 GNUNET_CONTAINER_multishortmap_destroy (db->channel_map);
473 GNUNET_assert (0 ==
474 pthread_mutex_destroy (&db->notify_lock));
521 GNUNET_free (db->es); 475 GNUNET_free (db->es);
522 GNUNET_free (db->ps); 476 GNUNET_free (db->ps);
523 GNUNET_free (db->load_path); 477 GNUNET_free (db->load_path);
diff --git a/src/pq/pq_event.c b/src/pq/pq_event.c
index ecb942230..b87aa6c5a 100644
--- a/src/pq/pq_event.c
+++ b/src/pq/pq_event.c
@@ -346,6 +346,7 @@ GNUNET_PQ_event_listen_cancel (struct GNUNET_PQ_EventHandler *eh)
346 } 346 }
347 GNUNET_assert (0 == 347 GNUNET_assert (0 ==
348 pthread_mutex_unlock (&db->notify_lock)); 348 pthread_mutex_unlock (&db->notify_lock));
349 GNUNET_free (eh);
349} 350}
350 351
351 352
@@ -364,7 +365,7 @@ GNUNET_PQ_event_notify (struct GNUNET_PQ_Context *db,
364 end = es_to_channel (es, 365 end = es_to_channel (es,
365 end); 366 end);
366 end = stpcpy (end, 367 end = stpcpy (end,
367 "'"); 368 ", '");
368 end = GNUNET_STRINGS_data_to_string (extra, 369 end = GNUNET_STRINGS_data_to_string (extra,
369 extra_size, 370 extra_size,
370 end, 371 end,
diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c
index e588da45d..b3747dfc3 100644
--- a/src/pq/test_pq.c
+++ b/src/pq/test_pq.c
@@ -220,6 +220,64 @@ run_queries (struct GNUNET_PQ_Context *db)
220} 220}
221 221
222 222
223static void
224event_cb (void *cls,
225 const void *extra,
226 size_t extra_size)
227{
228 unsigned int *cnt = cls;
229
230 GNUNET_assert (5 == extra_size);
231 GNUNET_assert (0 == memcmp ("world",
232 extra,
233 5));
234 (*cnt)++;
235}
236
237
238/**
239 * Run subscribe/notify tests.
240 *
241 * @param db database handle
242 * @return 0 on success
243 */
244static int
245test_notify (struct GNUNET_PQ_Context *db)
246{
247 struct GNUNET_PQ_EventHeaderP e1 = {
248 .size = htons (sizeof (e1)),
249 .type = htons (1)
250 };
251 struct GNUNET_PQ_EventHeaderP e2 = {
252 .size = htons (sizeof (e2)),
253 .type = htons (2)
254 };
255 unsigned int called = 0;
256 struct GNUNET_PQ_EventHandler *eh;
257
258 eh = GNUNET_PQ_event_listen (db,
259 &e1,
260 &event_cb,
261 &called);
262 GNUNET_assert (NULL != eh);
263 GNUNET_PQ_event_notify (db,
264 &e2,
265 "hello",
266 5);
267 GNUNET_PQ_event_do_poll (db);
268 GNUNET_assert (0 == called);
269 GNUNET_PQ_event_notify (db,
270 &e1,
271 "world",
272 5);
273 GNUNET_PQ_event_do_poll (db);
274 GNUNET_assert (1 == called);
275 GNUNET_PQ_event_listen_cancel (eh);
276 return 0;
277}
278
279
280
223int 281int
224main (int argc, 282main (int argc,
225 const char *const argv[]) 283 const char *const argv[])
@@ -272,12 +330,14 @@ main (int argc,
272 return 1; 330 return 1;
273 } 331 }
274 ret = run_queries (db); 332 ret = run_queries (db);
333 ret |= test_notify (db);
334 ret |= test_notify (db);
275#if TEST_RESTART 335#if TEST_RESTART
276 fprintf (stderr, "Please restart Postgres database now!\n"); 336 fprintf (stderr, "Please restart Postgres database now!\n");
277 sleep (60); 337 sleep (60);
278 ret = run_queries (db); 338 ret |= run_queries (db);
279 fprintf (stderr, "Result: %d (expect: 1 -- if you restarted the DB)\n", ret); 339 fprintf (stderr, "Result: %d (expect: 1 -- if you restarted the DB)\n", ret);
280 ret = run_queries (db); 340 ret |= run_queries (db);
281 fprintf (stderr, "Result: %d (expect: 0)\n", ret); 341 fprintf (stderr, "Result: %d (expect: 0)\n", ret);
282#endif 342#endif
283 { 343 {