exchange

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

test_auditordb.c (19915B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2016--2022 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.c
     18  * @brief test cases for DB interaction functions
     19  * @author Gabor X Toth
     20  * @author Christian Grothoff
     21  */
     22 #include <gnunet/gnunet_db_lib.h>
     23 #include "auditordb_lib.h"
     24 #include "auditor-database/create_tables.h"
     25 #include "auditor-database/del_reserve_info.h"
     26 #include "auditor-database/delete_auditor_closure_lag.h"
     27 #include "auditor-database/drop_tables.h"
     28 #include "auditor-database/gc.h"
     29 #include "auditor-database/get_denomination_balance.h"
     30 #include "auditor-database/get_reserve_info.h"
     31 #include "auditor-database/insert_auditor_closure_lags.h"
     32 #include "auditor-database/insert_denomination_balance.h"
     33 #include "auditor-database/insert_historic_denom_revenue.h"
     34 #include "auditor-database/insert_historic_reserve_revenue.h"
     35 #include "auditor-database/insert_reserve_info.h"
     36 #include "auditor-database/preflight.h"
     37 #include "auditor-database/select_historic_denom_revenue.h"
     38 #include "auditor-database/select_historic_reserve_revenue.h"
     39 #include "auditor-database/start.h"
     40 #include "auditor-database/update_denomination_balance.h"
     41 #include "auditor-database/update_reserve_info.h"
     42 
     43 /**
     44  * Currency we use, must match CURRENCY in "test-auditor-db-postgres.conf".
     45  */
     46 #define CURRENCY "EUR"
     47 
     48 /**
     49  * Report line of error if @a cond is true, and jump to label "drop".
     50  */
     51 #define FAILIF(cond)                              \
     52         do {                                          \
     53           if (! (cond)) { break;}                     \
     54           GNUNET_break (0);                         \
     55           goto drop;                                \
     56         } while (0)
     57 
     58 /**
     59  * Initializes @a ptr with random data.
     60  */
     61 #define RND_BLK(ptr)                                                    \
     62         GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (* \
     63                                                                              ptr))
     64 
     65 /**
     66  * Initializes @a ptr with zeros.
     67  */
     68 #define ZR_BLK(ptr) \
     69         memset (ptr, 0, sizeof (*ptr))
     70 
     71 
     72 /**
     73  * Global result from the testcase.
     74  */
     75 static int result = -1;
     76 
     77 /**
     78  * Hash of denomination public key.
     79  */
     80 static struct TALER_DenominationHashP denom_pub_hash;
     81 
     82 /**
     83  * Another hash of a denomination public key.
     84  */
     85 static struct TALER_DenominationHashP rnd_hash;
     86 
     87 /**
     88  * Current time.
     89  */
     90 static struct GNUNET_TIME_Timestamp now;
     91 
     92 /**
     93  * Timestamp in the past.
     94  */
     95 static struct GNUNET_TIME_Timestamp past;
     96 
     97 /**
     98  * Timestamp in the future.
     99  */
    100 static struct GNUNET_TIME_Timestamp future;
    101 
    102 /**
    103  * Database under test.
    104  */
    105 static struct TALER_AUDITORDB_PostgresContext *pg;
    106 
    107 /**
    108  * Historic denomination revenue value.
    109  */
    110 static struct TALER_Amount rbalance;
    111 
    112 /**
    113  * Historic denomination loss value.
    114  */
    115 static struct TALER_Amount rloss;
    116 
    117 /**
    118  * Reserve profit value we are using.
    119  */
    120 static struct TALER_Amount reserve_profits;
    121 
    122 
    123 static enum GNUNET_GenericReturnValue
    124 select_historic_denom_revenue_result (
    125   void *cls,
    126   uint64_t rowid,
    127   const struct TALER_DenominationHashP *denom_pub_hash2,
    128   struct GNUNET_TIME_Timestamp revenue_timestamp2,
    129   const struct TALER_Amount *revenue_balance2,
    130   const struct TALER_Amount *loss2)
    131 {
    132   static int n = 0;
    133 
    134   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    135               "select_historic_denom_revenue_result: row %u\n", n);
    136 
    137   if ( (2 <= n++)
    138        || (cls != NULL)
    139        || ((0 != GNUNET_memcmp (&revenue_timestamp2,
    140                                 &past))
    141            && (0 != GNUNET_memcmp (&revenue_timestamp2,
    142                                    &now)))
    143        || ((0 != GNUNET_memcmp (denom_pub_hash2,
    144                                 &denom_pub_hash))
    145            && (0 != GNUNET_memcmp (denom_pub_hash2,
    146                                    &rnd_hash)))
    147        || (0 != TALER_amount_cmp (revenue_balance2,
    148                                   &rbalance))
    149        || (0 != TALER_amount_cmp (loss2,
    150                                   &rloss)))
    151   {
    152     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    153                 "select_historic_denom_revenue_result: result does not match\n")
    154     ;
    155     GNUNET_break (0);
    156     return GNUNET_SYSERR;
    157   }
    158   return GNUNET_OK;
    159 }
    160 
    161 
    162 static enum GNUNET_GenericReturnValue
    163 select_historic_reserve_revenue_result (
    164   void *cls,
    165   uint64_t rowid,
    166   struct GNUNET_TIME_Timestamp start_time2,
    167   struct GNUNET_TIME_Timestamp end_time2,
    168   const struct TALER_Amount *reserve_profits2)
    169 {
    170   static int n = 0;
    171 
    172   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    173               "select_historic_reserve_revenue_result: row %u\n", n);
    174 
    175   if ((2 <= n++)
    176       || (cls != NULL)
    177       || ((0 != GNUNET_memcmp (&start_time2,
    178                                &past))
    179           && (0 != GNUNET_memcmp (&start_time2,
    180                                   &now)))
    181       || (0 != GNUNET_memcmp (&end_time2,
    182                               &future))
    183       || (0 != TALER_amount_cmp (reserve_profits2,
    184                                  &reserve_profits)))
    185   {
    186     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    187                 "select_historic_reserve_revenue_result: result does not match\n");
    188     GNUNET_break (0);
    189     return GNUNET_SYSERR;
    190   }
    191   return GNUNET_OK;
    192 }
    193 
    194 
    195 /**
    196  * Main function that will be run by the scheduler.
    197  *
    198  * @param cls closure with config
    199  */
    200 static void
    201 run (void *cls)
    202 {
    203   struct GNUNET_CONFIGURATION_Handle *cfg = cls;
    204   uint64_t rowid;
    205   struct TALER_Amount value;
    206   struct TALER_Amount fee_withdraw;
    207   struct TALER_Amount fee_deposit;
    208   struct TALER_Amount fee_refresh;
    209   struct TALER_Amount fee_refund;
    210   struct TALER_ReservePublicKeyP reserve_pub;
    211   struct TALER_DenominationPrivateKey denom_priv;
    212   struct TALER_DenominationPublicKey denom_pub;
    213   struct GNUNET_TIME_Timestamp date;
    214 
    215   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    216               "connecting to database\n");
    217 
    218   if (NULL ==
    219       (pg = TALER_AUDITORDB_connect (cfg,
    220                                      true)))
    221   {
    222     result = 77;
    223     return;
    224   }
    225 
    226   (void) TALER_AUDITORDB_drop_tables (pg,
    227                                       GNUNET_YES);
    228   if (GNUNET_OK !=
    229       TALER_AUDITORDB_create_tables (cfg,
    230                                      false,
    231                                      0))
    232   {
    233     result = 77;
    234     goto unload;
    235   }
    236   if (GNUNET_SYSERR ==
    237       TALER_AUDITORDB_preflight (pg))
    238   {
    239     result = 77;
    240     goto drop;
    241   }
    242 
    243   FAILIF (GNUNET_OK !=
    244           TALER_AUDITORDB_start (pg));
    245 
    246   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    247               "initializing\n");
    248 
    249   GNUNET_assert (GNUNET_OK ==
    250                  TALER_string_to_amount (CURRENCY ":1.000010",
    251                                          &value));
    252   GNUNET_assert (GNUNET_OK ==
    253                  TALER_string_to_amount (CURRENCY ":0.000011",
    254                                          &fee_withdraw));
    255   GNUNET_assert (GNUNET_OK ==
    256                  TALER_string_to_amount (CURRENCY ":0.000012",
    257                                          &fee_deposit));
    258   GNUNET_assert (GNUNET_OK ==
    259                  TALER_string_to_amount (CURRENCY ":0.000013",
    260                                          &fee_refresh));
    261   GNUNET_assert (GNUNET_OK ==
    262                  TALER_string_to_amount (CURRENCY ":0.000014",
    263                                          &fee_refund));
    264   RND_BLK (&reserve_pub);
    265   RND_BLK (&rnd_hash);
    266   GNUNET_assert (GNUNET_OK ==
    267                  TALER_denom_priv_create (&denom_priv,
    268                                           &denom_pub,
    269                                           GNUNET_CRYPTO_BSA_RSA,
    270                                           1024));
    271   TALER_denom_pub_hash (&denom_pub,
    272                         &denom_pub_hash);
    273   TALER_denom_priv_free (&denom_priv);
    274   TALER_denom_pub_free (&denom_pub);
    275 
    276   now = GNUNET_TIME_timestamp_get ();
    277   past = GNUNET_TIME_absolute_to_timestamp (
    278     GNUNET_TIME_absolute_subtract (now.abs_time,
    279                                    GNUNET_TIME_relative_multiply (
    280                                      GNUNET_TIME_UNIT_HOURS,
    281                                      4)));
    282   future = GNUNET_TIME_absolute_to_timestamp (
    283     GNUNET_TIME_absolute_add (now.abs_time,
    284                               GNUNET_TIME_relative_multiply (
    285                                 GNUNET_TIME_UNIT_HOURS,
    286                                 4)));
    287 
    288   {
    289     struct TALER_AUDITORDB_ReserveFeeBalance rfb;
    290     struct TALER_AUDITORDB_ReserveFeeBalance rfb2;
    291 
    292     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    293                 "Test: insert_reserve_info\n");
    294     GNUNET_assert (GNUNET_OK ==
    295                    TALER_string_to_amount (CURRENCY ":12.345678",
    296                                            &rfb.reserve_balance));
    297     GNUNET_assert (GNUNET_OK ==
    298                    TALER_string_to_amount (CURRENCY ":11.245678",
    299                                            &rfb.reserve_loss));
    300     GNUNET_assert (GNUNET_OK ==
    301                    TALER_string_to_amount (CURRENCY ":23.456789",
    302                                            &rfb.withdraw_fee_balance));
    303     GNUNET_assert (GNUNET_OK ==
    304                    TALER_string_to_amount (CURRENCY ":23.456719",
    305                                            &rfb.close_fee_balance));
    306     GNUNET_assert (GNUNET_OK ==
    307                    TALER_string_to_amount (CURRENCY ":33.456789",
    308                                            &rfb.purse_fee_balance));
    309     GNUNET_assert (GNUNET_OK ==
    310                    TALER_string_to_amount (CURRENCY ":43.456789",
    311                                            &rfb.open_fee_balance));
    312     GNUNET_assert (GNUNET_OK ==
    313                    TALER_string_to_amount (CURRENCY ":53.456789",
    314                                            &rfb.history_fee_balance));
    315     {
    316       struct TALER_FullPayto pt = {
    317         .full_payto = (char *) "payto://bla/blub?receiver-name=blub"
    318       };
    319 
    320       FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    321               TALER_AUDITORDB_insert_reserve_info (pg,
    322                                                    &reserve_pub,
    323                                                    &rfb,
    324                                                    past,
    325                                                    pt));
    326     }
    327     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    328                 "Test: update_reserve_info\n");
    329     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    330             TALER_AUDITORDB_update_reserve_info (pg,
    331                                                  &reserve_pub,
    332                                                  &rfb,
    333                                                  future));
    334     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    335                 "Test: get_reserve_info\n");
    336     {
    337       struct TALER_FullPayto payto;
    338 
    339       FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    340               TALER_AUDITORDB_get_reserve_info (pg,
    341                                                 &reserve_pub,
    342                                                 &rowid,
    343                                                 &rfb2,
    344                                                 &date,
    345                                                 &payto));
    346       FAILIF (0 != strcmp (payto.full_payto,
    347                            "payto://bla/blub?receiver-name=blub"));
    348       GNUNET_free (payto.full_payto);
    349     }
    350     FAILIF ( (0 != GNUNET_memcmp (&date,
    351                                   &future))
    352              || (0 != TALER_amount_cmp (&rfb2.reserve_balance,
    353                                         &rfb.reserve_balance))
    354              || (0 != TALER_amount_cmp (&rfb2.withdraw_fee_balance,
    355                                         &rfb.withdraw_fee_balance))
    356              || (0 != TALER_amount_cmp (&rfb2.close_fee_balance,
    357                                         &rfb.close_fee_balance))
    358              || (0 != TALER_amount_cmp (&rfb2.purse_fee_balance,
    359                                         &rfb.purse_fee_balance))
    360              || (0 != TALER_amount_cmp (&rfb2.open_fee_balance,
    361                                         &rfb.open_fee_balance))
    362              || (0 != TALER_amount_cmp (&rfb2.history_fee_balance,
    363                                         &rfb.history_fee_balance))
    364              );
    365   }
    366 
    367   {
    368     struct TALER_AUDITORDB_ClosureLags cl = {
    369       .problem_row_id = 42
    370     };
    371 
    372     GNUNET_assert (GNUNET_OK ==
    373                    TALER_string_to_amount (CURRENCY ":12.345678",
    374                                            &cl.amount));
    375     cl.account.full_payto
    376       = (char *) "payto://unspec/foo?receiver-name=bar";
    377     memset (&cl.wtid,
    378             42,
    379             sizeof (cl.wtid));
    380     cl.deadline = GNUNET_TIME_absolute_get ();
    381     FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
    382             TALER_AUDITORDB_delete_auditor_closure_lag (pg,
    383                                                         &cl.amount,
    384                                                         &cl.wtid,
    385                                                         cl.account));
    386     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    387             TALER_AUDITORDB_insert_auditor_closure_lags (pg,
    388                                                          &cl));
    389     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    390             TALER_AUDITORDB_delete_auditor_closure_lag (pg,
    391                                                         &cl.amount,
    392                                                         &cl.wtid,
    393                                                         cl.account));
    394   }
    395 
    396   {
    397     struct TALER_AUDITORDB_DenominationCirculationData dcd;
    398     struct TALER_AUDITORDB_DenominationCirculationData dcd2;
    399 
    400     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    401                 "Test: insert_denomination_balance\n");
    402     GNUNET_assert (GNUNET_OK ==
    403                    TALER_string_to_amount (CURRENCY ":12.345678",
    404                                            &dcd.denom_balance));
    405     GNUNET_assert (GNUNET_OK ==
    406                    TALER_string_to_amount (CURRENCY ":0.1",
    407                                            &dcd.denom_loss));
    408     GNUNET_assert (GNUNET_OK ==
    409                    TALER_string_to_amount (CURRENCY ":13.57986",
    410                                            &dcd.denom_risk));
    411     GNUNET_assert (GNUNET_OK ==
    412                    TALER_string_to_amount (CURRENCY ":12.57986",
    413                                            &dcd.recoup_loss));
    414     dcd.num_issued = 62;
    415     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    416             TALER_AUDITORDB_insert_denomination_balance (pg,
    417                                                          &denom_pub_hash,
    418                                                          &dcd));
    419     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    420                 "Test: update_denomination_balance\n");
    421     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    422             TALER_AUDITORDB_update_denomination_balance (pg,
    423                                                          &denom_pub_hash,
    424                                                          &dcd));
    425     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    426                 "Test: get_denomination_balance\n");
    427 
    428     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    429             TALER_AUDITORDB_get_denomination_balance (pg,
    430                                                       &denom_pub_hash,
    431                                                       &dcd2));
    432     FAILIF (0 != TALER_amount_cmp (&dcd2.denom_balance,
    433                                    &dcd.denom_balance));
    434     FAILIF (0 != TALER_amount_cmp (&dcd2.denom_loss,
    435                                    &dcd.denom_loss));
    436     FAILIF (0 != TALER_amount_cmp (&dcd2.denom_risk,
    437                                    &dcd.denom_risk));
    438     FAILIF (0 != TALER_amount_cmp (&dcd2.recoup_loss,
    439                                    &dcd.recoup_loss));
    440     FAILIF (dcd2.num_issued != dcd.num_issued);
    441   }
    442 
    443   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    444               "Test: insert_historic_denom_revenue\n");
    445   GNUNET_assert (GNUNET_OK ==
    446                  TALER_string_to_amount (CURRENCY ":12.345678",
    447                                          &rbalance));
    448   GNUNET_assert (GNUNET_OK ==
    449                  TALER_string_to_amount (CURRENCY ":23.456789",
    450                                          &rloss));
    451   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    452           TALER_AUDITORDB_insert_historic_denom_revenue (pg,
    453                                                          &denom_pub_hash,
    454                                                          past,
    455                                                          &rbalance,
    456                                                          &rloss));
    457   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    458           TALER_AUDITORDB_insert_historic_denom_revenue (pg,
    459                                                          &rnd_hash,
    460                                                          now,
    461                                                          &rbalance,
    462                                                          &rloss));
    463   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    464               "Test: select_historic_denom_revenue\n");
    465   FAILIF (0 >=
    466           TALER_AUDITORDB_select_historic_denom_revenue (
    467             pg,
    468             1024, /* limit */
    469             0, /* offset */
    470             &select_historic_denom_revenue_result,
    471             NULL));
    472   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    473               "Test: insert_historic_reserve_revenue\n");
    474   GNUNET_assert (GNUNET_OK ==
    475                  TALER_string_to_amount (CURRENCY ":56.789012",
    476                                          &reserve_profits));
    477   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    478           TALER_AUDITORDB_insert_historic_reserve_revenue (pg,
    479                                                            past,
    480                                                            future,
    481                                                            &reserve_profits));
    482   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    483           TALER_AUDITORDB_insert_historic_reserve_revenue (pg,
    484                                                            now,
    485                                                            future,
    486                                                            &reserve_profits));
    487   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    488               "Test: select_historic_reserve_revenue\n");
    489   FAILIF (0 >=
    490           TALER_AUDITORDB_select_historic_reserve_revenue (
    491             pg,
    492             1024, /* limit */
    493             0,    /* offset */
    494             &select_historic_reserve_revenue_result,
    495             NULL));
    496 
    497   FAILIF (0 >
    498           TALER_AUDITORDB_commit (pg));
    499 
    500   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    501           TALER_AUDITORDB_del_reserve_info (pg,
    502                                             &reserve_pub));
    503 
    504 #if GC_IMPLEMENTED
    505   FAILIF (GNUNET_OK !=
    506           TALER_AUDITORDB_gc (pg));
    507 #endif
    508 
    509   result = 0;
    510 
    511 drop:
    512   TALER_AUDITORDB_rollback (pg);
    513   GNUNET_break (GNUNET_OK ==
    514                 TALER_AUDITORDB_drop_tables (pg,
    515                                              GNUNET_YES));
    516 unload:
    517   TALER_AUDITORDB_disconnect (pg);
    518   pg = NULL;
    519 }
    520 
    521 
    522 int
    523 main (int argc,
    524       char *const argv[])
    525 {
    526   struct GNUNET_CONFIGURATION_Handle *cfg;
    527 
    528   (void) argc;
    529   result = -1;
    530   GNUNET_log_setup (argv[0],
    531                     "WARNING",
    532                     NULL);
    533   cfg = GNUNET_CONFIGURATION_create (TALER_AUDITOR_project_data ());
    534   if (GNUNET_OK !=
    535       GNUNET_CONFIGURATION_parse (cfg,
    536                                   "test-auditor-db-postgres.conf"))
    537   {
    538     GNUNET_break (0);
    539     return 2;
    540   }
    541   GNUNET_SCHEDULER_run (&run,
    542                         cfg);
    543   GNUNET_CONFIGURATION_destroy (cfg);
    544   return result;
    545 }