LCOV - code coverage report
Current view: top level - testing - testing_api_cmd_reserve_get.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 68.7 % 99 68
Test Date: 2025-12-26 23:00:34 Functions: 88.9 % 9 8

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2014-2022 Taler Systems SA
       4              : 
       5              :   TALER is free software; you can redistribute it and/or modify
       6              :   it under the terms of the GNU General Public License as
       7              :   published by the Free Software Foundation; either version 3, or
       8              :   (at your option) any later version.
       9              : 
      10              :   TALER is distributed in the hope that it will be useful, but
      11              :   WITHOUT ANY WARRANTY; without even the implied warranty of
      12              :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13              :   GNU General Public License for more details.
      14              : 
      15              :   You should have received a copy of the GNU General Public
      16              :   License along with TALER; see the file COPYING.  If not, see
      17              :   <http://www.gnu.org/licenses/>
      18              : */
      19              : /**
      20              :  * @file testing/testing_api_cmd_reserve_get.c
      21              :  * @brief Implement the GET /reserve/$RID test command.
      22              :  * @author Marcello Stanisci
      23              :  */
      24              : #include "taler/platform.h"
      25              : #include "taler/taler_json_lib.h"
      26              : #include <gnunet/gnunet_curl_lib.h>
      27              : #include "taler/taler_testing_lib.h"
      28              : 
      29              : 
      30              : /**
      31              :  * State for a "poll" CMD.
      32              :  */
      33              : struct PollState
      34              : {
      35              : 
      36              :   /**
      37              :    * How long do we give the exchange to respond?
      38              :    */
      39              :   struct GNUNET_TIME_Relative timeout;
      40              : 
      41              :   /**
      42              :    * Label to the command which created the reserve to check,
      43              :    * needed to resort the reserve key.
      44              :    */
      45              :   const char *poll_reference;
      46              : 
      47              :   /**
      48              :    * Timeout to wait for at most.
      49              :    */
      50              :   struct GNUNET_SCHEDULER_Task *tt;
      51              : 
      52              :   /**
      53              :    * The interpreter we are using.
      54              :    */
      55              :   struct TALER_TESTING_Interpreter *is;
      56              : };
      57              : 
      58              : 
      59              : /**
      60              :  * State for a "status" CMD.
      61              :  */
      62              : struct StatusState
      63              : {
      64              : 
      65              :   /**
      66              :    * How long do we give the exchange to respond?
      67              :    */
      68              :   struct GNUNET_TIME_Relative timeout;
      69              : 
      70              :   /**
      71              :    * Poller waiting for us.
      72              :    */
      73              :   struct PollState *ps;
      74              : 
      75              :   /**
      76              :    * Label to the command which created the reserve to check,
      77              :    * needed to resort the reserve key.
      78              :    */
      79              :   const char *reserve_reference;
      80              : 
      81              :   /**
      82              :    * Handle to the "reserve status" operation.
      83              :    */
      84              :   struct TALER_EXCHANGE_ReservesGetHandle *rsh;
      85              : 
      86              :   /**
      87              :    * Expected reserve balance.
      88              :    */
      89              :   const char *expected_balance;
      90              : 
      91              :   /**
      92              :    * Public key of the reserve being analyzed.
      93              :    */
      94              :   const struct TALER_ReservePublicKeyP *reserve_pubp;
      95              : 
      96              :   /**
      97              :    * Expected HTTP response code.
      98              :    */
      99              :   unsigned int expected_response_code;
     100              : 
     101              :   /**
     102              :    * Interpreter state.
     103              :    */
     104              :   struct TALER_TESTING_Interpreter *is;
     105              : 
     106              : };
     107              : 
     108              : 
     109              : /**
     110              :  * Check that the reserve balance and HTTP response code are
     111              :  * both acceptable.
     112              :  *
     113              :  * @param cls closure.
     114              :  * @param rs HTTP response details
     115              :  */
     116              : static void
     117           30 : reserve_status_cb (void *cls,
     118              :                    const struct TALER_EXCHANGE_ReserveSummary *rs)
     119              : {
     120           30 :   struct StatusState *ss = cls;
     121           30 :   struct TALER_TESTING_Interpreter *is = ss->is;
     122              :   struct TALER_Amount eb;
     123              : 
     124           30 :   ss->rsh = NULL;
     125           30 :   if (ss->expected_response_code != rs->hr.http_status)
     126              :   {
     127            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     128              :                 "Unexpected HTTP response code: %d in %s:%u\n",
     129              :                 rs->hr.http_status,
     130              :                 __FILE__,
     131              :                 __LINE__);
     132            0 :     json_dumpf (rs->hr.reply,
     133              :                 stderr,
     134              :                 0);
     135            0 :     TALER_TESTING_interpreter_fail (ss->is);
     136            0 :     return;
     137              :   }
     138           30 :   if (MHD_HTTP_OK == ss->expected_response_code)
     139              :   {
     140           30 :     GNUNET_assert (GNUNET_OK ==
     141              :                    TALER_string_to_amount (ss->expected_balance,
     142              :                                            &eb));
     143           30 :     if (0 != TALER_amount_cmp (&eb,
     144              :                                &rs->details.ok.balance))
     145              :     {
     146            0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     147              :                   "Unexpected amount %s in reserve, wanted %s\n",
     148              :                   TALER_amount_to_string (&rs->details.ok.balance),
     149              :                   ss->expected_balance);
     150            0 :       TALER_TESTING_interpreter_fail (ss->is);
     151            0 :       return;
     152              :     }
     153              :   }
     154           30 :   if (NULL != ss->ps)
     155              :   {
     156              :     /* force continuation on long poller */
     157            0 :     GNUNET_SCHEDULER_cancel (ss->ps->tt);
     158            0 :     ss->ps->tt = NULL;
     159            0 :     TALER_TESTING_interpreter_next (is);
     160            0 :     return;
     161              :   }
     162           30 :   if (GNUNET_TIME_relative_is_zero (ss->timeout))
     163           23 :     TALER_TESTING_interpreter_next (is);
     164              : }
     165              : 
     166              : 
     167              : /**
     168              :  * Run the command.
     169              :  *
     170              :  * @param cls closure.
     171              :  * @param cmd the command being executed.
     172              :  * @param is the interpreter state.
     173              :  */
     174              : static void
     175           30 : status_run (void *cls,
     176              :             const struct TALER_TESTING_Command *cmd,
     177              :             struct TALER_TESTING_Interpreter *is)
     178              : {
     179           30 :   struct StatusState *ss = cls;
     180              :   const struct TALER_TESTING_Command *create_reserve;
     181              :   const char *exchange_url;
     182              : 
     183           30 :   ss->is = is;
     184           30 :   exchange_url = TALER_TESTING_get_exchange_url (is);
     185           30 :   if (NULL == exchange_url)
     186              :   {
     187            0 :     GNUNET_break (0);
     188            0 :     return;
     189              :   }
     190              :   create_reserve
     191           30 :     = TALER_TESTING_interpreter_lookup_command (is,
     192              :                                                 ss->reserve_reference);
     193           30 :   GNUNET_assert (NULL != create_reserve);
     194           30 :   if (GNUNET_OK !=
     195           30 :       TALER_TESTING_get_trait_reserve_pub (create_reserve,
     196              :                                            &ss->reserve_pubp))
     197              :   {
     198            0 :     GNUNET_break (0);
     199            0 :     TALER_LOG_ERROR ("Failed to find reserve_pub for status query\n");
     200            0 :     TALER_TESTING_interpreter_fail (is);
     201            0 :     return;
     202              :   }
     203           30 :   ss->rsh = TALER_EXCHANGE_reserves_get (
     204              :     TALER_TESTING_interpreter_get_context (is),
     205              :     exchange_url,
     206              :     ss->reserve_pubp,
     207              :     ss->timeout,
     208              :     &reserve_status_cb,
     209              :     ss);
     210           30 :   if (! GNUNET_TIME_relative_is_zero (ss->timeout))
     211              :   {
     212            7 :     TALER_TESTING_interpreter_next (is);
     213            7 :     return;
     214              :   }
     215              : }
     216              : 
     217              : 
     218              : /**
     219              :  * Cleanup the state from a "reserve status" CMD, and possibly
     220              :  * cancel a pending operation thereof.
     221              :  *
     222              :  * @param cls closure.
     223              :  * @param cmd the command which is being cleaned up.
     224              :  */
     225              : static void
     226           30 : status_cleanup (void *cls,
     227              :                 const struct TALER_TESTING_Command *cmd)
     228              : {
     229           30 :   struct StatusState *ss = cls;
     230              : 
     231           30 :   if (NULL != ss->rsh)
     232              :   {
     233            0 :     TALER_TESTING_command_incomplete (ss->is,
     234              :                                       cmd->label);
     235            0 :     TALER_EXCHANGE_reserves_get_cancel (ss->rsh);
     236            0 :     ss->rsh = NULL;
     237              :   }
     238           30 :   GNUNET_free (ss);
     239           30 : }
     240              : 
     241              : 
     242              : struct TALER_TESTING_Command
     243           23 : TALER_TESTING_cmd_status (const char *label,
     244              :                           const char *reserve_reference,
     245              :                           const char *expected_balance,
     246              :                           unsigned int expected_response_code)
     247              : {
     248              :   struct StatusState *ss;
     249              : 
     250           23 :   GNUNET_assert (NULL != reserve_reference);
     251           23 :   ss = GNUNET_new (struct StatusState);
     252           23 :   ss->reserve_reference = reserve_reference;
     253           23 :   ss->expected_balance = expected_balance;
     254           23 :   ss->expected_response_code = expected_response_code;
     255              :   {
     256           23 :     struct TALER_TESTING_Command cmd = {
     257              :       .cls = ss,
     258              :       .label = label,
     259              :       .run = &status_run,
     260              :       .cleanup = &status_cleanup
     261              :     };
     262              : 
     263           23 :     return cmd;
     264              :   }
     265              : }
     266              : 
     267              : 
     268              : struct TALER_TESTING_Command
     269            7 : TALER_TESTING_cmd_reserve_poll (const char *label,
     270              :                                 const char *reserve_reference,
     271              :                                 const char *expected_balance,
     272              :                                 struct GNUNET_TIME_Relative timeout,
     273              :                                 unsigned int expected_response_code)
     274              : {
     275              :   struct StatusState *ss;
     276              : 
     277            7 :   GNUNET_assert (NULL != reserve_reference);
     278            7 :   ss = GNUNET_new (struct StatusState);
     279            7 :   ss->reserve_reference = reserve_reference;
     280            7 :   ss->expected_balance = expected_balance;
     281            7 :   ss->expected_response_code = expected_response_code;
     282            7 :   ss->timeout = timeout;
     283              :   {
     284            7 :     struct TALER_TESTING_Command cmd = {
     285              :       .cls = ss,
     286              :       .label = label,
     287              :       .run = &status_run,
     288              :       .cleanup = &status_cleanup
     289              :     };
     290              : 
     291            7 :     return cmd;
     292              :   }
     293              : }
     294              : 
     295              : 
     296              : /**
     297              :  * Long poller timed out. Fail the test.
     298              :  *
     299              :  * @param cls a `struct PollState`
     300              :  */
     301              : static void
     302            0 : finish_timeout (void *cls)
     303              : {
     304            0 :   struct PollState *ps = cls;
     305              : 
     306            0 :   ps->tt = NULL;
     307            0 :   GNUNET_break (0);
     308            0 :   TALER_TESTING_interpreter_fail (ps->is);
     309            0 : }
     310              : 
     311              : 
     312              : /**
     313              :  * Run the command.
     314              :  *
     315              :  * @param cls closure.
     316              :  * @param cmd the command being executed.
     317              :  * @param is the interpreter state.
     318              :  */
     319              : static void
     320            7 : finish_run (void *cls,
     321              :             const struct TALER_TESTING_Command *cmd,
     322              :             struct TALER_TESTING_Interpreter *is)
     323              : {
     324            7 :   struct PollState *ps = cls;
     325              :   const struct TALER_TESTING_Command *poll_reserve;
     326              :   struct StatusState *ss;
     327              : 
     328            7 :   ps->is = is;
     329              :   poll_reserve
     330            7 :     = TALER_TESTING_interpreter_lookup_command (is,
     331              :                                                 ps->poll_reference);
     332            7 :   GNUNET_assert (NULL != poll_reserve);
     333            7 :   GNUNET_assert (poll_reserve->run == &status_run);
     334            7 :   ss = poll_reserve->cls;
     335            7 :   if (NULL == ss->rsh)
     336              :   {
     337            7 :     TALER_TESTING_interpreter_next (is);
     338            7 :     return;
     339              :   }
     340            0 :   GNUNET_assert (NULL == ss->ps);
     341            0 :   ss->ps = ps;
     342            0 :   ps->tt = GNUNET_SCHEDULER_add_delayed (ps->timeout,
     343              :                                          &finish_timeout,
     344              :                                          ps);
     345              : }
     346              : 
     347              : 
     348              : /**
     349              :  * Cleanup the state from a "reserve finish" CMD.
     350              :  *
     351              :  * @param cls closure.
     352              :  * @param cmd the command which is being cleaned up.
     353              :  */
     354              : static void
     355            7 : finish_cleanup (void *cls,
     356              :                 const struct TALER_TESTING_Command *cmd)
     357              : {
     358            7 :   struct PollState *ps = cls;
     359              : 
     360            7 :   if (NULL != ps->tt)
     361              :   {
     362            0 :     GNUNET_SCHEDULER_cancel (ps->tt);
     363            0 :     ps->tt = NULL;
     364              :   }
     365            7 :   GNUNET_free (ps);
     366            7 : }
     367              : 
     368              : 
     369              : struct TALER_TESTING_Command
     370            7 : TALER_TESTING_cmd_reserve_poll_finish (const char *label,
     371              :                                        struct GNUNET_TIME_Relative timeout,
     372              :                                        const char *poll_reference)
     373              : {
     374              :   struct PollState *ps;
     375              : 
     376            7 :   GNUNET_assert (NULL != poll_reference);
     377            7 :   ps = GNUNET_new (struct PollState);
     378            7 :   ps->timeout = timeout;
     379            7 :   ps->poll_reference = poll_reference;
     380              :   {
     381            7 :     struct TALER_TESTING_Command cmd = {
     382              :       .cls = ps,
     383              :       .label = label,
     384              :       .run = &finish_run,
     385              :       .cleanup = &finish_cleanup
     386              :     };
     387              : 
     388            7 :     return cmd;
     389              :   }
     390              : }
        

Generated by: LCOV version 2.0-1