LCOV - code coverage report
Current view: top level - auditordb - test_auditordb_checkpoints.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.7 % 72 61
Test Date: 2026-09-09 15:11:34 Functions: 100.0 % 2 2

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2016--2024 Taler Systems SA
       4              : 
       5              :   TALER is free software; you can redistribute it and/or modify it under the
       6              :   terms of the GNU General Public License as published by the Free Software
       7              :   Foundation; either version 3, or (at your option) any later version.
       8              : 
       9              :   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
      10              :   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      11              :   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
      12              : 
      13              :   You should have received a copy of the GNU General Public License along with
      14              :   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
      15              : */
      16              : /**
      17              :  * @file auditordb/test_auditordb_checkpoints.c
      18              :  * @brief test cases for DB interaction functions
      19              :  * @author Christian Grothoff
      20              :  */
      21              : #include <gnunet/gnunet_common.h>
      22              : #include <gnunet/gnunet_db_lib.h>
      23              : #include "auditordb_lib.h"
      24              : #include "auditor-database/create_tables.h"
      25              : #include "auditor-database/drop_tables.h"
      26              : #include "auditor-database/get_auditor_progress.h"
      27              : #include "auditor-database/get_balance.h"
      28              : #include "auditor-database/insert_auditor_progress.h"
      29              : #include "auditor-database/insert_balance.h"
      30              : #include "auditor-database/preflight.h"
      31              : #include "auditor-database/start.h"
      32              : 
      33              : 
      34              : /**
      35              :  * Currency we use, must match CURRENCY in "test-auditor-db-postgres.conf".
      36              :  */
      37              : #define CURRENCY "EUR"
      38              : 
      39              : /**
      40              :  * Report line of error if @a cond is true, and jump to label "drop".
      41              :  */
      42              : #define FAILIF(cond)                              \
      43              :         do {                                          \
      44              :           if (! (cond)) { break;}                     \
      45              :           GNUNET_break (0);                         \
      46              :           goto drop;                                \
      47              :         } while (0)
      48              : 
      49              : /**
      50              :  * Initializes @a ptr with random data.
      51              :  */
      52              : #define RND_BLK(ptr)                                                    \
      53              :         GNUNET_CRYPTO_random_block (ptr, \
      54              :                                     sizeof (*ptr))
      55              : 
      56              : /**
      57              :  * Initializes @a ptr with zeros.
      58              :  */
      59              : #define ZR_BLK(ptr) \
      60              :         memset (ptr, 0, sizeof (*ptr))
      61              : 
      62              : 
      63              : /**
      64              :  * Global result from the testcase.
      65              :  */
      66              : static int result = -1;
      67              : 
      68              : /**
      69              :  * Database connection under test.
      70              :  */
      71              : static struct TALER_AUDITORDB_PostgresContext *pg;
      72              : 
      73              : 
      74              : /**
      75              :  * Main function that will be run by the scheduler.
      76              :  *
      77              :  * @param cls closure with config
      78              :  */
      79              : static void
      80            1 : run (void *cls)
      81              : {
      82            1 :   struct GNUNET_CONFIGURATION_Handle *cfg = cls;
      83              :   struct TALER_Amount a1;
      84              :   struct TALER_Amount a2;
      85              :   struct TALER_Amount a3;
      86              : 
      87            1 :   GNUNET_assert (GNUNET_OK ==
      88              :                  TALER_string_to_amount (CURRENCY ":11.245678",
      89              :                                          &a1));
      90            1 :   GNUNET_assert (GNUNET_OK ==
      91              :                  TALER_string_to_amount (CURRENCY ":2",
      92              :                                          &a2));
      93            1 :   GNUNET_assert (GNUNET_OK ==
      94              :                  TALER_string_to_amount (CURRENCY ":3",
      95              :                                          &a3));
      96              : 
      97            1 :   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
      98              :               "Connecting to database\n");
      99            1 :   if (NULL ==
     100            1 :       (pg = TALER_AUDITORDB_connect (cfg)))
     101              :   {
     102            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     103              :                 "Failed to connect to database\n");
     104            0 :     result = 77;
     105            0 :     return;
     106              :   }
     107            1 :   GNUNET_assert (GNUNET_OK ==
     108              :                  TALER_AUDITORDB_preflight (pg));
     109            1 :   (void) TALER_AUDITORDB_drop_tables (pg,
     110              :                                       GNUNET_YES);
     111            1 :   if (GNUNET_OK !=
     112            1 :       TALER_AUDITORDB_create_tables (pg,
     113              :                                      false,
     114              :                                      0))
     115              :   {
     116            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     117              :                 "Failed to 'create_tables'\n");
     118            0 :     result = 77;
     119            0 :     goto unload;
     120              :   }
     121            1 :   if (GNUNET_SYSERR ==
     122            1 :       TALER_AUDITORDB_preflight (pg))
     123              :   {
     124            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     125              :                 "Failed preflight check\n");
     126            0 :     result = 77;
     127            0 :     goto drop;
     128              :   }
     129              : 
     130            1 :   FAILIF (GNUNET_OK !=
     131              :           TALER_AUDITORDB_start (pg,
     132              :                                  "test-auditordb-checkpoints"));
     133              : 
     134              :   /* Test inserting a blank value, should tell us one result */
     135            1 :   GNUNET_assert (
     136              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     137              :     TALER_AUDITORDB_insert_auditor_progress (pg,
     138              :                                              "Test",
     139              :                                              69,
     140              :                                              NULL)
     141              :     );
     142              :   /* Test re-inserting the same value; insert is an upsert, so this
     143              :      still touches the row */
     144            1 :   GNUNET_assert (
     145              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     146              :     TALER_AUDITORDB_insert_auditor_progress (pg,
     147              :                                              "Test",
     148              :                                              69,
     149              :                                              NULL)
     150              :     );
     151              :   /* Test inserting multiple values, with one already existing */
     152            1 :   GNUNET_assert (
     153              :     3 == TALER_AUDITORDB_insert_auditor_progress (pg,
     154              :                                                   "Test",
     155              :                                                   69,
     156              :                                                   "Test2",
     157              :                                                   123,
     158              :                                                   "Test3",
     159              :                                                   245,
     160              :                                                   NULL)
     161              :     );
     162              :   /* Test re-re-inserting the same key with a different value; the
     163              :      upsert must store the new value */
     164            1 :   GNUNET_assert (
     165              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     166              :     TALER_AUDITORDB_insert_auditor_progress (pg,
     167              :                                              "Test",
     168              :                                              42,
     169              :                                              NULL)
     170              :     );
     171              :   /* Test updating the same key (again) with a different value; should yield a result */
     172            1 :   GNUNET_assert (
     173              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     174              :     TALER_AUDITORDB_insert_auditor_progress (pg,
     175              :                                              "Test",
     176              :                                              42,
     177              :                                              NULL)
     178              :     );
     179              :   /* Test updating a key that does not exist yet; update is an upsert,
     180              :      so the row must be created */
     181            1 :   GNUNET_assert (
     182              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     183              :     TALER_AUDITORDB_insert_auditor_progress (pg,
     184              :                                              "NonexistentTest",
     185              :                                              1,
     186              :                                              NULL)
     187              :     );
     188              : 
     189              :   /* Right now, the state should look like this:
     190              :    * Test  = 42
     191              :    * Test2 = 123
     192              :    * Test3 = 245
     193              :    * Let's make sure that's the case! */
     194              :   {
     195              :     uint64_t value;
     196              :     uint64_t valueNX;
     197              :     uint64_t value3;
     198              : 
     199            1 :     GNUNET_assert (
     200              :       3 ==
     201              :       TALER_AUDITORDB_get_auditor_progress (
     202              :         pg,
     203              :         "Test",
     204              :         &value,
     205              :         "TestNX",
     206              :         &valueNX,
     207              :         "Test3",
     208              :         &value3,
     209              :         NULL)
     210              :       );
     211            1 :     GNUNET_assert (value == 42);
     212            1 :     GNUNET_assert (valueNX == 0);
     213            1 :     GNUNET_assert (value3 == 245);
     214              :   }
     215              :   /* Ensure the rest are also at their expected values */
     216              :   {
     217              :     uint64_t value;
     218              : 
     219            1 :     GNUNET_assert (
     220              :       GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     221              :       TALER_AUDITORDB_get_auditor_progress (
     222              :         pg,
     223              :         "Test2",
     224              :         &value,
     225              :         NULL)
     226              :       );
     227            1 :     GNUNET_assert (value == 123);
     228              :   }
     229              :   {
     230              :     uint64_t value;
     231              : 
     232            1 :     GNUNET_assert (
     233              :       GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     234              :       TALER_AUDITORDB_get_auditor_progress (
     235              :         pg,
     236              :         "Test3",
     237              :         &value,
     238              :         NULL)
     239              :       );
     240            1 :     GNUNET_assert (value == 245);
     241              :   }
     242              :   {
     243              :     uint64_t value;
     244              : 
     245              :     /* Try fetching value that does not exist */
     246            1 :     GNUNET_assert (
     247              :       GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     248              :       TALER_AUDITORDB_get_auditor_progress (
     249              :         pg,
     250              :         "TestNX",
     251              :         &value,
     252              :         NULL)
     253              :       );
     254            1 :     GNUNET_assert (0 == value);
     255              :   }
     256              : 
     257              :   /* Test inserting a blank value, should tell us one result */
     258            1 :   GNUNET_assert (
     259              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     260              :     TALER_AUDITORDB_insert_balance (pg,
     261              :                                     "Test",
     262              :                                     &a1,
     263              :                                     NULL)
     264              :     );
     265              :   /* Test re-inserting the same value; insert is an upsert, so this
     266              :      still touches the row */
     267            1 :   GNUNET_assert (
     268              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     269              :     TALER_AUDITORDB_insert_balance (pg,
     270              :                                     "Test",
     271              :                                     &a1,
     272              :                                     NULL)
     273              :     );
     274              :   /* Test inserting multiple values, with one already existing */
     275            1 :   GNUNET_assert (
     276              :     3 == TALER_AUDITORDB_insert_balance (pg,
     277              :                                          "Test",
     278              :                                          &a1,
     279              :                                          "Test2",
     280              :                                          &a2,
     281              :                                          "Test3",
     282              :                                          &a3,
     283              :                                          NULL)
     284              :     );
     285              :   /* Test re-re-inserting the same key with a different value; the
     286              :      upsert must store the new value */
     287            1 :   GNUNET_assert (
     288              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     289              :     TALER_AUDITORDB_insert_balance (pg,
     290              :                                     "Test",
     291              :                                     &a2,
     292              :                                     NULL)
     293              :     );
     294              :   /* Test updating the same key (again) with a different value; should yield a result */
     295            1 :   GNUNET_assert (
     296              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     297              :     TALER_AUDITORDB_insert_balance (pg,
     298              :                                     "Test",
     299              :                                     &a2,
     300              :                                     NULL)
     301              :     );
     302              :   /* Test updating a key that does not exist yet; update is an upsert,
     303              :      so the row must be created */
     304            1 :   GNUNET_assert (
     305              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     306              :     TALER_AUDITORDB_insert_balance (pg,
     307              :                                     "NonexistentTest",
     308              :                                     &a2,
     309              :                                     NULL)
     310              :     );
     311              : 
     312              :   /* Right now, the state should look like this:
     313              :    * Test  = a2
     314              :    * Test2 = a2
     315              :    * Test3 = a3
     316              :    * Let's make sure that's the case! */
     317            1 :   GNUNET_assert (
     318              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     319              :     TALER_AUDITORDB_get_balance (
     320              :       pg,
     321              :       "Test",
     322              :       &a1,
     323              :       NULL)
     324              :     );
     325            1 :   GNUNET_assert (0 ==
     326              :                  TALER_amount_cmp (&a1,
     327              :                                    &a2));
     328              : 
     329              :   /* Ensure the rest are also at their expected values */
     330            1 :   GNUNET_assert (
     331              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     332              :     TALER_AUDITORDB_get_balance (
     333              :       pg,
     334              :       "Test2",
     335              :       &a1,
     336              :       NULL)
     337              :     );
     338            1 :   GNUNET_assert (0 ==
     339              :                  TALER_amount_cmp (&a1,
     340              :                                    &a2));
     341            1 :   GNUNET_assert (
     342              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     343              :     TALER_AUDITORDB_get_balance (
     344              :       pg,
     345              :       "Test3",
     346              :       &a1,
     347              :       NULL)
     348              :     );
     349            1 :   GNUNET_assert (0 ==
     350              :                  TALER_amount_cmp (&a1,
     351              :                                    &a3));
     352              : 
     353              :   /* Try fetching value that does not exist */
     354            1 :   GNUNET_assert (
     355              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     356              :     TALER_AUDITORDB_get_balance (
     357              :       pg,
     358              :       "TestNX",
     359              :       &a1,
     360              :       NULL)
     361              :     );
     362            1 :   GNUNET_assert (TALER_amount_is_zero (&a1));
     363              : 
     364            1 :   result = 0;
     365            1 :   GNUNET_break (0 <=
     366              :                 TALER_AUDITORDB_commit (pg));
     367            1 : drop:
     368            1 :   GNUNET_break (GNUNET_OK ==
     369              :                 TALER_AUDITORDB_drop_tables (pg,
     370              :                                              GNUNET_YES));
     371            1 : unload:
     372            1 :   TALER_AUDITORDB_disconnect (pg);
     373            1 :   pg = NULL;
     374              : }
     375              : 
     376              : 
     377              : int
     378            1 : main (int argc,
     379              :       char *const argv[])
     380              : {
     381              :   struct GNUNET_CONFIGURATION_Handle *cfg;
     382              : 
     383              :   (void) argc;
     384            1 :   result = -1;
     385            1 :   GNUNET_log_setup (argv[0],
     386              :                     "INFO",
     387              :                     NULL);
     388            1 :   cfg = GNUNET_CONFIGURATION_create (TALER_AUDITOR_project_data ());
     389            1 :   if (GNUNET_OK !=
     390            1 :       GNUNET_CONFIGURATION_parse (cfg,
     391              :                                   "test-auditor-db-postgres.conf"))
     392              :   {
     393            0 :     GNUNET_break (0);
     394            0 :     return 2;
     395              :   }
     396            1 :   GNUNET_SCHEDULER_run (&run, cfg);
     397            1 :   GNUNET_CONFIGURATION_destroy (cfg);
     398            1 :   return result;
     399              : }
        

Generated by: LCOV version 2.0-1