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 (11675B)


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