LCOV - code coverage report
Current view: top level - exchangedb - test_kyc_alerts.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 42 42
Test Date: 2026-09-11 18:55:36 Functions: 100.0 % 5 5

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2026 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 exchangedb/test_kyc_alerts.c
      18              :  * @brief tests for the exchangedb functions whose primary table is
      19              :  *        `kyc_alerts`
      20              :  * @author Christian Grothoff
      21              :  *
      22              :  * Covers #TALER_EXCHANGEDB_do_drain_kyc_alert().
      23              :  *
      24              :  * `kyc_alerts` is a work queue: the stored procedures that change the KYC
      25              :  * state of an account append a row, and taler-exchange-aggregator drains
      26              :  * it one row at a time.  Nothing exported writes to it directly, so the
      27              :  * rows here are produced through
      28              :  * #TALER_EXCHANGEDB_insert_aml_program_failure(), the cheapest of the
      29              :  * three producers.
      30              :  */
      31              : #include "test_common.h"
      32              : #include "exchange-database/do_drain_kyc_alert.h"
      33              : #include "exchange-database/insert_aml_program_failure.h"
      34              : 
      35              : 
      36              : /**
      37              :  * Trigger type the aggregator drains, and the only one any stored
      38              :  * procedure ever writes.
      39              :  */
      40              : #define AGGREGATOR_TRIGGER 1
      41              : 
      42              : 
      43              : /**
      44              :  * The two accounts we raise alerts for.
      45              :  */
      46              : static struct TDB_Account account[2];
      47              : 
      48              : 
      49              : /**
      50              :  * Nothing to drain while the queue is empty.
      51              :  *
      52              :  * @param pg the database context
      53              :  * @return 0 on success
      54              :  */
      55              : static int
      56            1 : check_empty (struct TALER_EXCHANGEDB_PostgresContext *pg)
      57              : {
      58              :   struct TALER_NormalizedPaytoHashP h_payto;
      59              : 
      60            3 :   for (unsigned int i = 0; i < 2; i++)
      61            2 :     TDB_account (pg,
      62              :                  10 + i,
      63              :                  &account[i]);
      64            1 :   memset (&h_payto,
      65              :           0,
      66              :           sizeof (h_payto));
      67            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
      68              :           TALER_EXCHANGEDB_do_drain_kyc_alert (pg,
      69              :                                                AGGREGATOR_TRIGGER,
      70              :                                                &h_payto));
      71            1 :   return 0;
      72              : }
      73              : 
      74              : 
      75              : /**
      76              :  * A KYC state change queues exactly one alert per account.
      77              :  *
      78              :  * @param pg the database context
      79              :  * @return 0 on success
      80              :  */
      81              : static int
      82            1 : check_raise (struct TALER_EXCHANGEDB_PostgresContext *pg)
      83              : {
      84            3 :   for (unsigned int i = 0; i < 2; i++)
      85            2 :     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
      86              :             TALER_EXCHANGEDB_insert_aml_program_failure (
      87              :               pg,
      88              :               0,
      89              :               &account[i].h_normalized,
      90              :               "no such AML program",
      91              :               TALER_EC_EXCHANGE_GENERIC_KYC_FAILED));
      92            1 :   FAILIF (2 != TDB_count (pg,
      93              :                           "FROM kyc_alerts"
      94              :                           " WHERE trigger_type=%d",
      95              :                           AGGREGATOR_TRIGGER));
      96              : 
      97              :   /* a second state change on an account that is already queued does not
      98              :      queue it twice */
      99            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
     100              :           TALER_EXCHANGEDB_insert_aml_program_failure (
     101              :             pg,
     102              :             0,
     103              :             &account[0].h_normalized,
     104              :             "still no such AML program",
     105              :             TALER_EC_EXCHANGE_GENERIC_KYC_FAILED));
     106            1 :   FAILIF (2 != TDB_count (pg,
     107              :                           "FROM kyc_alerts"));
     108            1 :   return 0;
     109              : }
     110              : 
     111              : 
     112              : /**
     113              :  * Draining returns the queued accounts one by one and removes them.
     114              :  *
     115              :  * @param pg the database context
     116              :  * @return 0 on success
     117              :  */
     118              : static int
     119            1 : check_drain (struct TALER_EXCHANGEDB_PostgresContext *pg)
     120              : {
     121              :   struct TALER_NormalizedPaytoHashP first;
     122              :   struct TALER_NormalizedPaytoHashP second;
     123              : 
     124              :   /* nobody listens for this trigger type, so the queue looks empty */
     125            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     126              :           TALER_EXCHANGEDB_do_drain_kyc_alert (pg,
     127              :                                                AGGREGATOR_TRIGGER + 1,
     128              :                                                &first));
     129            1 :   FAILIF (2 != TDB_count (pg,
     130              :                           "FROM kyc_alerts"));
     131              : 
     132            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
     133              :           TALER_EXCHANGEDB_do_drain_kyc_alert (pg,
     134              :                                                AGGREGATOR_TRIGGER,
     135              :                                                &first));
     136            1 :   FAILIF (1 != TDB_count (pg,
     137              :                           "FROM kyc_alerts"));
     138            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
     139              :           TALER_EXCHANGEDB_do_drain_kyc_alert (pg,
     140              :                                                AGGREGATOR_TRIGGER,
     141              :                                                &second));
     142            1 :   FAILIF (0 != TDB_count (pg,
     143              :                           "FROM kyc_alerts"));
     144              : 
     145              :   /* both of our accounts came back, each exactly once */
     146            1 :   FAILIF (0 == GNUNET_memcmp (&first,
     147              :                               &second));
     148            3 :   for (unsigned int i = 0; i < 2; i++)
     149              :   {
     150            2 :     unsigned int seen = 0;
     151              : 
     152            2 :     if (0 == GNUNET_memcmp (&first,
     153              :                             &account[i].h_normalized))
     154            1 :       seen++;
     155            2 :     if (0 == GNUNET_memcmp (&second,
     156              :                             &account[i].h_normalized))
     157            1 :       seen++;
     158            2 :     FAILIF (1 != seen);
     159              :   }
     160              : 
     161              :   /* and the queue is empty again */
     162            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     163              :           TALER_EXCHANGEDB_do_drain_kyc_alert (pg,
     164              :                                                AGGREGATOR_TRIGGER,
     165              :                                                &first));
     166            1 :   return 0;
     167              : }
     168              : 
     169              : 
     170              : /**
     171              :  * An account that was drained can be queued again.
     172              :  *
     173              :  * @param pg the database context
     174              :  * @return 0 on success
     175              :  */
     176              : static int
     177            1 : check_requeue (struct TALER_EXCHANGEDB_PostgresContext *pg)
     178              : {
     179              :   struct TALER_NormalizedPaytoHashP h_payto;
     180              : 
     181            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
     182              :           TALER_EXCHANGEDB_insert_aml_program_failure (
     183              :             pg,
     184              :             0,
     185              :             &account[1].h_normalized,
     186              :             "and again",
     187              :             TALER_EC_EXCHANGE_GENERIC_KYC_FAILED));
     188            1 :   FAILIF (1 != TDB_count (pg,
     189              :                           "FROM kyc_alerts"));
     190            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
     191              :           TALER_EXCHANGEDB_do_drain_kyc_alert (pg,
     192              :                                                AGGREGATOR_TRIGGER,
     193              :                                                &h_payto));
     194            1 :   FAILIF (0 != GNUNET_memcmp (&h_payto,
     195              :                               &account[1].h_normalized));
     196            1 :   FAILIF (0 != TDB_count (pg,
     197              :                           "FROM kyc_alerts"));
     198            1 :   return 0;
     199              : }
     200              : 
     201              : 
     202              : /**
     203              :  * The checks to run, in order.
     204              :  */
     205              : static const struct TDB_Test tests[] = {
     206              :   { "kyc-alerts-empty",
     207              :     &check_empty },
     208              :   { "kyc-alerts-raise",
     209              :     &check_raise },
     210              :   { "kyc-alerts-drain",
     211              :     &check_drain },
     212              :   { "kyc-alerts-requeue",
     213              :     &check_requeue },
     214              :   { NULL, NULL }
     215              : };
     216              : 
     217              : 
     218              : int
     219            1 : main (int argc,
     220              :       char *const *argv)
     221              : {
     222              :   int ret;
     223              : 
     224            1 :   ret = TDB_main (argc,
     225              :                   argv,
     226              :                   "test-kyc-alerts",
     227              :                   "Tests for the exchangedb `kyc_alerts' table",
     228              :                   tests);
     229            3 :   for (unsigned int i = 0; i < 2; i++)
     230            2 :     TDB_account_free (&account[i]);
     231            1 :   return ret;
     232              : }
     233              : 
     234              : 
     235              : /* end of test_kyc_alerts.c */
        

Generated by: LCOV version 2.0-1