diff options
author | Christian Grothoff <grothoff@gnunet.org> | 2021-07-24 22:50:22 +0200 |
---|---|---|
committer | Christian Grothoff <grothoff@gnunet.org> | 2021-07-24 22:50:22 +0200 |
commit | d63771f255057b27485c1fc96a0713d64d0ae1af (patch) | |
tree | e8b5ca287ec6283133bcb3ce49ba444253384b3a | |
parent | 31eae6bbe16302d2593b806ef3d2ac2ca9c2d8de (diff) | |
download | gnunet-d63771f255057b27485c1fc96a0713d64d0ae1af.tar.gz gnunet-d63771f255057b27485c1fc96a0713d64d0ae1af.zip |
minimal test for new pq event functionality
-rw-r--r-- | src/pq/pq_connect.c | 84 | ||||
-rw-r--r-- | src/pq/pq_event.c | 3 | ||||
-rw-r--r-- | src/pq/test_pq.c | 64 |
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 | */ | ||
88 | struct GNUNET_PQ_Context * | 67 | struct GNUNET_PQ_Context * |
89 | GNUNET_PQ_connect (const char *config_str, | 68 | GNUNET_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 | */ |
145 | static int | 129 | static enum GNUNET_GenericReturnValue |
146 | apply_patch (struct GNUNET_PQ_Context *db, | 130 | apply_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 | */ | ||
212 | enum GNUNET_GenericReturnValue | 187 | enum GNUNET_GenericReturnValue |
213 | GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db, | 188 | GNUNET_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 | */ | ||
312 | void | 282 | void |
313 | GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db) | 283 | GNUNET_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 | */ | ||
329 | void | 294 | void |
330 | GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) | 295 | GNUNET_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 | */ | ||
471 | struct GNUNET_PQ_Context * | 426 | struct GNUNET_PQ_Context * |
472 | GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, | 427 | GNUNET_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 | */ | ||
518 | void | 467 | void |
519 | GNUNET_PQ_disconnect (struct GNUNET_PQ_Context *db) | 468 | GNUNET_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 | ||
223 | static void | ||
224 | event_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 | */ | ||
244 | static int | ||
245 | test_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 | |||
223 | int | 281 | int |
224 | main (int argc, | 282 | main (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 | { |