LCOV - code coverage report
Current view: top level - auditordb - test_auditordb_checkpoints.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 81.5 % 81 66
Test Date: 2025-12-28 14:06:02 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 "taler/platform.h"
      22              : #include <gnunet/gnunet_common.h>
      23              : #include <gnunet/gnunet_db_lib.h>
      24              : #include "taler/taler_auditordb_plugin.h"
      25              : 
      26              : /**
      27              :  * Currency we use, must match CURRENCY in "test-auditor-db-postgres.conf".
      28              :  */
      29              : #define CURRENCY "EUR"
      30              : 
      31              : /**
      32              :  * Report line of error if @a cond is true, and jump to label "drop".
      33              :  */
      34              : #define FAILIF(cond)                              \
      35              :         do {                                          \
      36              :           if (! (cond)) { break;}                     \
      37              :           GNUNET_break (0);                         \
      38              :           goto drop;                                \
      39              :         } while (0)
      40              : 
      41              : /**
      42              :  * Initializes @a ptr with random data.
      43              :  */
      44              : #define RND_BLK(ptr)                                                    \
      45              :         GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, \
      46              :                                     sizeof (*ptr))
      47              : 
      48              : /**
      49              :  * Initializes @a ptr with zeros.
      50              :  */
      51              : #define ZR_BLK(ptr) \
      52              :         memset (ptr, 0, sizeof (*ptr))
      53              : 
      54              : 
      55              : /**
      56              :  * Global result from the testcase.
      57              :  */
      58              : static int result = -1;
      59              : 
      60              : /**
      61              :  * Database plugin under test.
      62              :  */
      63              : static struct TALER_AUDITORDB_Plugin *plugin;
      64              : 
      65              : 
      66              : /**
      67              :  * Main function that will be run by the scheduler.
      68              :  *
      69              :  * @param cls closure with config
      70              :  */
      71              : static void
      72            1 : run (void *cls)
      73              : {
      74            1 :   struct GNUNET_CONFIGURATION_Handle *cfg = cls;
      75              :   struct TALER_Amount a1;
      76              :   struct TALER_Amount a2;
      77              :   struct TALER_Amount a3;
      78              : 
      79            1 :   GNUNET_assert (GNUNET_OK ==
      80              :                  TALER_string_to_amount (CURRENCY ":11.245678",
      81              :                                          &a1));
      82            1 :   GNUNET_assert (GNUNET_OK ==
      83              :                  TALER_string_to_amount (CURRENCY ":2",
      84              :                                          &a2));
      85            1 :   GNUNET_assert (GNUNET_OK ==
      86              :                  TALER_string_to_amount (CURRENCY ":3",
      87              :                                          &a3));
      88              : 
      89            1 :   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
      90              :               "loading database plugin\n");
      91            1 :   if (NULL ==
      92            1 :       (plugin = TALER_AUDITORDB_plugin_load (cfg,
      93              :                                              true)))
      94              :   {
      95            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
      96              :                 "Failed to connect to database\n");
      97            0 :     result = 77;
      98            0 :     return;
      99              :   }
     100              : 
     101            1 :   (void) plugin->drop_tables (plugin->cls,
     102              :                               GNUNET_YES);
     103            1 :   if (GNUNET_OK !=
     104            1 :       plugin->create_tables (plugin->cls,
     105              :                              false,
     106              :                              0))
     107              :   {
     108            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     109              :                 "Failed to 'create_tables'\n");
     110            0 :     result = 77;
     111            0 :     goto unload;
     112              :   }
     113            1 :   if (GNUNET_SYSERR ==
     114            1 :       plugin->preflight (plugin->cls))
     115              :   {
     116            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     117              :                 "Failed preflight check\n");
     118            0 :     result = 77;
     119            0 :     goto drop;
     120              :   }
     121              : 
     122            1 :   FAILIF (GNUNET_OK !=
     123              :           plugin->start (plugin->cls));
     124              : 
     125              :   /* Test inserting a blank value, should tell us one result */
     126            1 :   GNUNET_assert (
     127              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     128              :     plugin->insert_auditor_progress (plugin->cls,
     129              :                                      "Test",
     130              :                                      69,
     131              :                                      NULL)
     132              :     );
     133              :   /* Test re-inserting the same value; should yield no results */
     134            1 :   GNUNET_assert (
     135              :     GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ==
     136              :     plugin->insert_auditor_progress (plugin->cls,
     137              :                                      "Test",
     138              :                                      69,
     139              :                                      NULL)
     140              :     );
     141              :   /* Test inserting multiple values, with one already existing */
     142            1 :   GNUNET_assert (
     143              :     2 == plugin->insert_auditor_progress (plugin->cls,
     144              :                                           "Test",
     145              :                                           69,
     146              :                                           "Test2",
     147              :                                           123,
     148              :                                           "Test3",
     149              :                                           245,
     150              :                                           NULL)
     151              :     );
     152              :   /* Test re-re-inserting the same key with a different value; should also yield no results */
     153            1 :   GNUNET_assert (
     154              :     GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ==
     155              :     plugin->insert_auditor_progress (plugin->cls,
     156              :                                      "Test",
     157              :                                      42,
     158              :                                      NULL)
     159              :     );
     160              :   /* Test updating the same key (again) with a different value; should yield a result */
     161            1 :   GNUNET_assert (
     162              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     163              :     plugin->update_auditor_progress (plugin->cls,
     164              :                                      "Test",
     165              :                                      42,
     166              :                                      NULL)
     167              :     );
     168              :   /* Test updating a key that doesn't exist; should yield 0 */
     169            1 :   GNUNET_assert (
     170              :     GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ==
     171              :     plugin->update_auditor_progress (plugin->cls,
     172              :                                      "NonexistentTest",
     173              :                                      1,
     174              :                                      NULL)
     175              :     );
     176              : 
     177              :   /* Right now, the state should look like this:
     178              :    * Test  = 42
     179              :    * Test2 = 123
     180              :    * Test3 = 245
     181              :    * Let's make sure that's the case! */
     182              :   {
     183              :     uint64_t value;
     184              :     uint64_t valueNX;
     185              :     uint64_t value3;
     186              : 
     187            1 :     GNUNET_assert (
     188              :       3 ==
     189              :       plugin->get_auditor_progress (
     190              :         plugin->cls,
     191              :         "Test",
     192              :         &value,
     193              :         "TestNX",
     194              :         &valueNX,
     195              :         "Test3",
     196              :         &value3,
     197              :         NULL)
     198              :       );
     199            1 :     GNUNET_assert (value == 42);
     200            1 :     GNUNET_assert (valueNX == 0);
     201            1 :     GNUNET_assert (value3 == 245);
     202              :   }
     203              :   /* Ensure the rest are also at their expected values */
     204              :   {
     205              :     uint64_t value;
     206              : 
     207            1 :     GNUNET_assert (
     208              :       GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     209              :       plugin->get_auditor_progress (
     210              :         plugin->cls,
     211              :         "Test2",
     212              :         &value,
     213              :         NULL)
     214              :       );
     215            1 :     GNUNET_assert (value == 123);
     216              :   }
     217              :   {
     218              :     uint64_t value;
     219              : 
     220            1 :     GNUNET_assert (
     221              :       GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     222              :       plugin->get_auditor_progress (
     223              :         plugin->cls,
     224              :         "Test3",
     225              :         &value,
     226              :         NULL)
     227              :       );
     228            1 :     GNUNET_assert (value == 245);
     229              :   }
     230              :   {
     231              :     uint64_t value;
     232              : 
     233              :     /* Try fetching value that does not exist */
     234            1 :     GNUNET_assert (
     235              :       GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     236              :       plugin->get_auditor_progress (
     237              :         plugin->cls,
     238              :         "TestNX",
     239              :         &value,
     240              :         NULL)
     241              :       );
     242            1 :     GNUNET_assert (0 == value);
     243              :   }
     244              : 
     245              :   /* Test inserting a blank value, should tell us one result */
     246            1 :   GNUNET_assert (
     247              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     248              :     plugin->insert_balance (plugin->cls,
     249              :                             "Test",
     250              :                             &a1,
     251              :                             NULL)
     252              :     );
     253              :   /* Test re-inserting the same value; should yield no results */
     254            1 :   GNUNET_assert (
     255              :     GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ==
     256              :     plugin->insert_balance (plugin->cls,
     257              :                             "Test",
     258              :                             &a1,
     259              :                             NULL)
     260              :     );
     261              :   /* Test inserting multiple values, with one already existing */
     262            1 :   GNUNET_assert (
     263              :     2 == plugin->insert_balance (plugin->cls,
     264              :                                  "Test",
     265              :                                  &a1,
     266              :                                  "Test2",
     267              :                                  &a2,
     268              :                                  "Test3",
     269              :                                  &a3,
     270              :                                  NULL)
     271              :     );
     272              :   /* Test re-re-inserting the same key with a different value; should also yield no results */
     273            1 :   GNUNET_assert (
     274              :     GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ==
     275              :     plugin->insert_balance (plugin->cls,
     276              :                             "Test",
     277              :                             &a2,
     278              :                             NULL)
     279              :     );
     280              :   /* Test updating the same key (again) with a different value; should yield a result */
     281            1 :   GNUNET_assert (
     282              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     283              :     plugin->update_balance (plugin->cls,
     284              :                             "Test",
     285              :                             &a2,
     286              :                             NULL)
     287              :     );
     288              :   /* Test updating a key that doesn't exist; should yield 0 */
     289            1 :   GNUNET_assert (
     290              :     GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ==
     291              :     plugin->update_balance (plugin->cls,
     292              :                             "NonexistentTest",
     293              :                             &a2,
     294              :                             NULL)
     295              :     );
     296              : 
     297              :   /* Right now, the state should look like this:
     298              :    * Test  = a2
     299              :    * Test2 = a2
     300              :    * Test3 = a3
     301              :    * Let's make sure that's the case! */
     302            1 :   GNUNET_assert (
     303              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     304              :     plugin->get_balance (
     305              :       plugin->cls,
     306              :       "Test",
     307              :       &a1,
     308              :       NULL)
     309              :     );
     310            1 :   GNUNET_assert (0 ==
     311              :                  TALER_amount_cmp (&a1,
     312              :                                    &a2));
     313              : 
     314              :   /* Ensure the rest are also at their expected values */
     315            1 :   GNUNET_assert (
     316              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     317              :     plugin->get_balance (
     318              :       plugin->cls,
     319              :       "Test2",
     320              :       &a1,
     321              :       NULL)
     322              :     );
     323            1 :   GNUNET_assert (0 ==
     324              :                  TALER_amount_cmp (&a1,
     325              :                                    &a2));
     326            1 :   GNUNET_assert (
     327              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     328              :     plugin->get_balance (
     329              :       plugin->cls,
     330              :       "Test3",
     331              :       &a1,
     332              :       NULL)
     333              :     );
     334            1 :   GNUNET_assert (0 ==
     335              :                  TALER_amount_cmp (&a1,
     336              :                                    &a3));
     337              : 
     338              :   /* Try fetching value that does not exist */
     339            1 :   GNUNET_assert (
     340              :     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
     341              :     plugin->get_balance (
     342              :       plugin->cls,
     343              :       "TestNX",
     344              :       &a1,
     345              :       NULL)
     346              :     );
     347            1 :   GNUNET_assert (TALER_amount_is_zero (&a1));
     348              : 
     349            1 :   result = 0;
     350            1 :   GNUNET_break (0 <=
     351              :                 plugin->commit (plugin->cls));
     352            1 : drop:
     353            1 :   GNUNET_break (GNUNET_OK ==
     354              :                 plugin->drop_tables (plugin->cls,
     355              :                                      GNUNET_YES));
     356            1 : unload:
     357            1 :   TALER_AUDITORDB_plugin_unload (plugin);
     358            1 :   plugin = NULL;
     359              : }
     360              : 
     361              : 
     362              : int
     363            1 : main (int argc,
     364              :       char *const argv[])
     365              : {
     366              :   const char *plugin_name;
     367              :   char *config_filename;
     368              :   char *testname;
     369              :   struct GNUNET_CONFIGURATION_Handle *cfg;
     370              : 
     371              :   (void) argc;
     372            1 :   result = -1;
     373            1 :   GNUNET_log_setup (argv[0],
     374              :                     "INFO",
     375              :                     NULL);
     376            1 :   if (NULL == (plugin_name = strrchr (argv[0],
     377              :                                       (int) '-')))
     378              :   {
     379            0 :     GNUNET_break (0);
     380            0 :     return -1;
     381              :   }
     382            1 :   plugin_name++;
     383            1 :   (void) GNUNET_asprintf (&testname,
     384              :                           "test-auditor-db-%s",
     385              :                           plugin_name);
     386            1 :   (void) GNUNET_asprintf (&config_filename,
     387              :                           "%s.conf",
     388              :                           testname);
     389            1 :   cfg = GNUNET_CONFIGURATION_create (TALER_AUDITOR_project_data ());
     390            1 :   if (GNUNET_OK !=
     391            1 :       GNUNET_CONFIGURATION_parse (cfg,
     392              :                                   config_filename))
     393              :   {
     394            0 :     GNUNET_break (0);
     395            0 :     GNUNET_free (config_filename);
     396            0 :     GNUNET_free (testname);
     397            0 :     return 2;
     398              :   }
     399            1 :   GNUNET_SCHEDULER_run (&run, cfg);
     400            1 :   GNUNET_CONFIGURATION_destroy (cfg);
     401            1 :   GNUNET_free (config_filename);
     402            1 :   GNUNET_free (testname);
     403            1 :   return result;
     404              : }
        

Generated by: LCOV version 2.0-1