exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

test_auditordb_checkpoints.c (11503B)


      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 run (void *cls)
     73 {
     74   struct GNUNET_CONFIGURATION_Handle *cfg = cls;
     75   struct TALER_Amount a1;
     76   struct TALER_Amount a2;
     77   struct TALER_Amount a3;
     78 
     79   GNUNET_assert (GNUNET_OK ==
     80                  TALER_string_to_amount (CURRENCY ":11.245678",
     81                                          &a1));
     82   GNUNET_assert (GNUNET_OK ==
     83                  TALER_string_to_amount (CURRENCY ":2",
     84                                          &a2));
     85   GNUNET_assert (GNUNET_OK ==
     86                  TALER_string_to_amount (CURRENCY ":3",
     87                                          &a3));
     88 
     89   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     90               "loading database plugin\n");
     91   if (NULL ==
     92       (plugin = TALER_AUDITORDB_plugin_load (cfg,
     93                                              true)))
     94   {
     95     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     96                 "Failed to connect to database\n");
     97     result = 77;
     98     return;
     99   }
    100 
    101   (void) plugin->drop_tables (plugin->cls,
    102                               GNUNET_YES);
    103   if (GNUNET_OK !=
    104       plugin->create_tables (plugin->cls,
    105                              false,
    106                              0))
    107   {
    108     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
    109                 "Failed to 'create_tables'\n");
    110     result = 77;
    111     goto unload;
    112   }
    113   if (GNUNET_SYSERR ==
    114       plugin->preflight (plugin->cls))
    115   {
    116     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
    117                 "Failed preflight check\n");
    118     result = 77;
    119     goto drop;
    120   }
    121 
    122   FAILIF (GNUNET_OK !=
    123           plugin->start (plugin->cls));
    124 
    125   /* Test inserting a blank value, should tell us one result */
    126   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   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   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   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   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   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     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     GNUNET_assert (value == 42);
    200     GNUNET_assert (valueNX == 0);
    201     GNUNET_assert (value3 == 245);
    202   }
    203   /* Ensure the rest are also at their expected values */
    204   {
    205     uint64_t value;
    206 
    207     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     GNUNET_assert (value == 123);
    216   }
    217   {
    218     uint64_t value;
    219 
    220     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     GNUNET_assert (value == 245);
    229   }
    230   {
    231     uint64_t value;
    232 
    233     /* Try fetching value that does not exist */
    234     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     GNUNET_assert (0 == value);
    243   }
    244 
    245   /* Test inserting a blank value, should tell us one result */
    246   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   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   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   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   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   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   GNUNET_assert (
    303     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
    304     plugin->get_balance (
    305       plugin->cls,
    306       "Test",
    307       &a1,
    308       NULL)
    309     );
    310   GNUNET_assert (0 ==
    311                  TALER_amount_cmp (&a1,
    312                                    &a2));
    313 
    314   /* Ensure the rest are also at their expected values */
    315   GNUNET_assert (
    316     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
    317     plugin->get_balance (
    318       plugin->cls,
    319       "Test2",
    320       &a1,
    321       NULL)
    322     );
    323   GNUNET_assert (0 ==
    324                  TALER_amount_cmp (&a1,
    325                                    &a2));
    326   GNUNET_assert (
    327     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
    328     plugin->get_balance (
    329       plugin->cls,
    330       "Test3",
    331       &a1,
    332       NULL)
    333     );
    334   GNUNET_assert (0 ==
    335                  TALER_amount_cmp (&a1,
    336                                    &a3));
    337 
    338   /* Try fetching value that does not exist */
    339   GNUNET_assert (
    340     GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
    341     plugin->get_balance (
    342       plugin->cls,
    343       "TestNX",
    344       &a1,
    345       NULL)
    346     );
    347   GNUNET_assert (TALER_amount_is_zero (&a1));
    348 
    349   result = 0;
    350   GNUNET_break (0 <=
    351                 plugin->commit (plugin->cls));
    352 drop:
    353   GNUNET_break (GNUNET_OK ==
    354                 plugin->drop_tables (plugin->cls,
    355                                      GNUNET_YES));
    356 unload:
    357   TALER_AUDITORDB_plugin_unload (plugin);
    358   plugin = NULL;
    359 }
    360 
    361 
    362 int
    363 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   result = -1;
    373   GNUNET_log_setup (argv[0],
    374                     "INFO",
    375                     NULL);
    376   if (NULL == (plugin_name = strrchr (argv[0],
    377                                       (int) '-')))
    378   {
    379     GNUNET_break (0);
    380     return -1;
    381   }
    382   plugin_name++;
    383   (void) GNUNET_asprintf (&testname,
    384                           "test-auditor-db-%s",
    385                           plugin_name);
    386   (void) GNUNET_asprintf (&config_filename,
    387                           "%s.conf",
    388                           testname);
    389   cfg = GNUNET_CONFIGURATION_create (TALER_AUDITOR_project_data ());
    390   if (GNUNET_OK !=
    391       GNUNET_CONFIGURATION_parse (cfg,
    392                                   config_filename))
    393   {
    394     GNUNET_break (0);
    395     GNUNET_free (config_filename);
    396     GNUNET_free (testname);
    397     return 2;
    398   }
    399   GNUNET_SCHEDULER_run (&run, cfg);
    400   GNUNET_CONFIGURATION_destroy (cfg);
    401   GNUNET_free (config_filename);
    402   GNUNET_free (testname);
    403   return result;
    404 }