LCOV - code coverage report
Current view: top level - auditordb - test_auditordb_checkpoints.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 66 81 81.5 %
Date: 2025-06-05 21:03:14 Functions: 2 2 100.0 %

          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 "platform.h"
      22             : #include <gnunet/gnunet_common.h>
      23             : #include <gnunet/gnunet_db_lib.h>
      24             : #include "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 1.16