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


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