LCOV - code coverage report
Current view: top level - testing - testing_api_cmd_transfer_get.c (source / functions) Hit Total Coverage
Test: GNU Taler exchange coverage report Lines: 52 117 44.4 %
Date: 2021-08-30 06:43:37 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2014-2020 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             : /**
      21             :  * @file testing/testing_api_cmd_transfer_get.c
      22             :  * @brief Implement the testing CMDs for the /transfer GET operation.
      23             :  * @author Marcello Stanisci
      24             :  */
      25             : #include "platform.h"
      26             : #include "taler_json_lib.h"
      27             : #include <gnunet/gnunet_curl_lib.h>
      28             : #include "taler_testing_lib.h"
      29             : 
      30             : /**
      31             :  * State for a "track transfer" CMD.
      32             :  */
      33             : struct TrackTransferState
      34             : {
      35             : 
      36             :   /**
      37             :    * Expected amount for the WTID being tracked.
      38             :    */
      39             :   const char *expected_total_amount;
      40             : 
      41             :   /**
      42             :    * Expected fee for this WTID.
      43             :    */
      44             :   const char *expected_wire_fee;
      45             : 
      46             :   /**
      47             :    * Reference to any operation that can provide a WTID.
      48             :    * Will be the WTID to track.
      49             :    */
      50             :   const char *wtid_reference;
      51             : 
      52             :   /**
      53             :    * Reference to any operation that can provide wire details.
      54             :    * Those wire details will then be matched against the credit
      55             :    * bank account of the tracked WTID.  This way we can test that
      56             :    * a wire transfer paid back one particular bank account.
      57             :    */
      58             :   const char *wire_details_reference;
      59             : 
      60             :   /**
      61             :    * Reference to any operation that can provide an amount.
      62             :    * This way we can check that the transferred amount matches
      63             :    * our expectations.
      64             :    */
      65             :   const char *total_amount_reference;
      66             : 
      67             :   /**
      68             :    * Handle to a pending "track transfer" operation.
      69             :    */
      70             :   struct TALER_EXCHANGE_TransfersGetHandle *tth;
      71             : 
      72             :   /**
      73             :    * Interpreter state.
      74             :    */
      75             :   struct TALER_TESTING_Interpreter *is;
      76             : 
      77             :   /**
      78             :    * Expected HTTP response code.
      79             :    */
      80             :   unsigned int expected_response_code;
      81             : 
      82             :   /**
      83             :    * Index to the WTID to pick, in case @a wtid_reference has
      84             :    * many on offer.
      85             :    */
      86             :   unsigned int index;
      87             : };
      88             : 
      89             : 
      90             : /**
      91             :  * Cleanup the state for a "track transfer" CMD, and possibly
      92             :  * cancel a pending operation thereof.
      93             :  *
      94             :  * @param cls closure.
      95             :  * @param cmd the command which is being cleaned up.
      96             :  */
      97             : static void
      98           3 : track_transfer_cleanup (void *cls,
      99             :                         const struct TALER_TESTING_Command *cmd)
     100             : {
     101             : 
     102           3 :   struct TrackTransferState *tts = cls;
     103             : 
     104           3 :   if (NULL != tts->tth)
     105             :   {
     106           0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     107             :                 "Command %u (%s) did not complete\n",
     108             :                 tts->is->ip,
     109             :                 cmd->label);
     110           0 :     TALER_EXCHANGE_transfers_get_cancel (tts->tth);
     111           0 :     tts->tth = NULL;
     112             :   }
     113           3 :   GNUNET_free (tts);
     114           3 : }
     115             : 
     116             : 
     117             : /**
     118             :  * Check whether the HTTP response code from a "track transfer"
     119             :  * operation is acceptable, and all other values like total amount,
     120             :  * wire fees and hashed wire details as well.
     121             :  *
     122             :  * @param cls closure.
     123             :  * @param hr HTTP response details
     124             :  * @param ta transfer data returned by the exchange
     125             :  */
     126             : static void
     127           3 : track_transfer_cb (void *cls,
     128             :                    const struct TALER_EXCHANGE_HttpResponse *hr,
     129             :                    const struct TALER_EXCHANGE_TransferData *ta)
     130             : {
     131           3 :   struct TrackTransferState *tts = cls;
     132           3 :   struct TALER_TESTING_Interpreter *is = tts->is;
     133           3 :   struct TALER_TESTING_Command *cmd = &is->commands[is->ip];
     134             :   struct TALER_Amount expected_amount;
     135             : 
     136           3 :   tts->tth = NULL;
     137           3 :   if (tts->expected_response_code != hr->http_status)
     138             :   {
     139           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     140             :                 "Unexpected response code %u/%d to command %s in %s:%u\n",
     141             :                 hr->http_status,
     142             :                 (int) hr->ec,
     143             :                 cmd->label,
     144             :                 __FILE__,
     145             :                 __LINE__);
     146           0 :     json_dumpf (hr->reply,
     147             :                 stderr,
     148             :                 0);
     149           0 :     TALER_TESTING_interpreter_fail (is);
     150           0 :     return;
     151             :   }
     152             : 
     153           3 :   switch (hr->http_status)
     154             :   {
     155           2 :   case MHD_HTTP_OK:
     156           2 :     if (NULL == tts->expected_total_amount)
     157             :     {
     158           0 :       GNUNET_break (0);
     159           0 :       TALER_TESTING_interpreter_fail (is);
     160           0 :       return;
     161             :     }
     162           2 :     if (NULL == tts->expected_wire_fee)
     163             :     {
     164           0 :       GNUNET_break (0);
     165           0 :       TALER_TESTING_interpreter_fail (is);
     166           0 :       return;
     167             :     }
     168             : 
     169           2 :     if (GNUNET_OK !=
     170           2 :         TALER_string_to_amount (tts->expected_total_amount,
     171             :                                 &expected_amount))
     172             :     {
     173           0 :       GNUNET_break (0);
     174           0 :       TALER_TESTING_interpreter_fail (is);
     175           0 :       return;
     176             :     }
     177           2 :     if (0 != TALER_amount_cmp (&ta->total_amount,
     178             :                                &expected_amount))
     179             :     {
     180           0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     181             :                   "Total amount mismatch to command %s - "
     182             :                   "%s vs %s\n",
     183             :                   cmd->label,
     184             :                   TALER_amount_to_string (&ta->total_amount),
     185             :                   TALER_amount_to_string (&expected_amount));
     186           0 :       json_dumpf (hr->reply,
     187             :                   stderr,
     188             :                   0);
     189           0 :       fprintf (stderr, "\n");
     190           0 :       TALER_TESTING_interpreter_fail (is);
     191           0 :       return;
     192             :     }
     193             : 
     194           2 :     if (GNUNET_OK !=
     195           2 :         TALER_string_to_amount (tts->expected_wire_fee,
     196             :                                 &expected_amount))
     197             :     {
     198           0 :       GNUNET_break (0);
     199           0 :       TALER_TESTING_interpreter_fail (is);
     200           0 :       return;
     201             :     }
     202             : 
     203           2 :     if (0 != TALER_amount_cmp (&ta->wire_fee,
     204             :                                &expected_amount))
     205             :     {
     206           0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     207             :                   "Wire fee mismatch to command %s\n",
     208             :                   cmd->label);
     209           0 :       json_dumpf (hr->reply,
     210             :                   stderr,
     211             :                   0);
     212           0 :       TALER_TESTING_interpreter_fail (is);
     213           0 :       return;
     214             :     }
     215             : 
     216             :     /**
     217             :      * Optionally checking: (1) wire-details for this transfer
     218             :      * match the ones from a referenced "deposit" operation -
     219             :      * or any operation that could provide wire-details.  (2)
     220             :      * Total amount for this transfer matches the one from any
     221             :      * referenced command that could provide one.
     222           2 :      */if (NULL != tts->wire_details_reference)
     223             :     {
     224             :       const struct TALER_TESTING_Command *wire_details_cmd;
     225             :       const json_t *wire_details;
     226             :       struct GNUNET_HashCode h_wire_details;
     227             : 
     228             :       wire_details_cmd
     229           0 :         = TALER_TESTING_interpreter_lookup_command (is,
     230             :                                                     tts->wire_details_reference);
     231           0 :       if (NULL == wire_details_cmd)
     232             :       {
     233           0 :         GNUNET_break (0);
     234           0 :         TALER_TESTING_interpreter_fail (is);
     235           0 :         return;
     236             :       }
     237           0 :       if (GNUNET_OK !=
     238           0 :           TALER_TESTING_get_trait_wire_details (wire_details_cmd,
     239             :                                                 0,
     240             :                                                 &wire_details))
     241             :       {
     242           0 :         GNUNET_break (0);
     243           0 :         TALER_TESTING_interpreter_fail (is);
     244           0 :         return;
     245             :       }
     246           0 :       GNUNET_assert (GNUNET_OK ==
     247             :                      TALER_JSON_merchant_wire_signature_hash (wire_details,
     248             :                                                               &h_wire_details));
     249           0 :       if (0 != GNUNET_memcmp (&h_wire_details,
     250             :                               &ta->h_wire))
     251             :       {
     252           0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     253             :                     "Wire hash missmath to command %s\n",
     254             :                     cmd->label);
     255           0 :         json_dumpf (hr->reply,
     256             :                     stderr,
     257             :                     0);
     258           0 :         TALER_TESTING_interpreter_fail (is);
     259           0 :         return;
     260             :       }
     261             :     }
     262           2 :     if (NULL != tts->total_amount_reference)
     263             :     {
     264             :       const struct TALER_TESTING_Command *total_amount_cmd;
     265             :       const struct TALER_Amount *total_amount_from_reference;
     266             : 
     267             :       total_amount_cmd
     268           0 :         = TALER_TESTING_interpreter_lookup_command (is,
     269             :                                                     tts->total_amount_reference);
     270           0 :       if (NULL == total_amount_cmd)
     271             :       {
     272           0 :         GNUNET_break (0);
     273           0 :         TALER_TESTING_interpreter_fail (is);
     274           0 :         return;
     275             :       }
     276           0 :       if (GNUNET_OK !=
     277           0 :           TALER_TESTING_get_trait_amount_obj (total_amount_cmd,
     278             :                                               0,
     279             :                                               &total_amount_from_reference))
     280             :       {
     281           0 :         GNUNET_break (0);
     282           0 :         TALER_TESTING_interpreter_fail (is);
     283           0 :         return;
     284             :       }
     285           0 :       if (0 != TALER_amount_cmp (&ta->total_amount,
     286             :                                  total_amount_from_reference))
     287             :       {
     288           0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     289             :                     "Amount missmath to command %s\n",
     290             :                     cmd->label);
     291           0 :         json_dumpf (hr->reply,
     292             :                     stderr,
     293             :                     0);
     294           0 :         TALER_TESTING_interpreter_fail (is);
     295           0 :         return;
     296             :       }
     297             :     }
     298             :   }
     299           3 :   TALER_TESTING_interpreter_next (is);
     300             : }
     301             : 
     302             : 
     303             : /**
     304             :  * Run the command.
     305             :  *
     306             :  * @param cls closure.
     307             :  * @param cmd the command under execution.
     308             :  * @param is the interpreter state.
     309             :  */
     310             : static void
     311           3 : track_transfer_run (void *cls,
     312             :                     const struct TALER_TESTING_Command *cmd,
     313             :                     struct TALER_TESTING_Interpreter *is)
     314             : {
     315             :   /* looking for a wtid to track .. */
     316           3 :   struct TrackTransferState *tts = cls;
     317             :   struct TALER_WireTransferIdentifierRawP wtid;
     318             :   const struct TALER_WireTransferIdentifierRawP *wtid_ptr;
     319             : 
     320             :   /* If no reference is given, we'll use a all-zeros
     321             :    * WTID */
     322           3 :   memset (&wtid, 0, sizeof (wtid));
     323           3 :   wtid_ptr = &wtid;
     324             : 
     325           3 :   tts->is = is;
     326           3 :   if (NULL != tts->wtid_reference)
     327             :   {
     328             :     const struct TALER_TESTING_Command *wtid_cmd;
     329             : 
     330           2 :     wtid_cmd = TALER_TESTING_interpreter_lookup_command
     331             :                  (tts->is, tts->wtid_reference);
     332             : 
     333           2 :     if (NULL == wtid_cmd)
     334             :     {
     335           0 :       GNUNET_break (0);
     336           0 :       TALER_TESTING_interpreter_fail (tts->is);
     337           0 :       return;
     338             :     }
     339             : 
     340           2 :     if (GNUNET_OK != TALER_TESTING_get_trait_wtid
     341             :           (wtid_cmd, tts->index, &wtid_ptr))
     342             :     {
     343           0 :       GNUNET_break (0);
     344           0 :       TALER_TESTING_interpreter_fail (tts->is);
     345           0 :       return;
     346             :     }
     347           2 :     GNUNET_assert (NULL != wtid_ptr);
     348             :   }
     349           3 :   tts->tth = TALER_EXCHANGE_transfers_get (is->exchange,
     350             :                                            wtid_ptr,
     351             :                                            &track_transfer_cb,
     352             :                                            tts);
     353           3 :   GNUNET_assert (NULL != tts->tth);
     354             : }
     355             : 
     356             : 
     357             : /**
     358             :  * Make a "track transfer" CMD where no "expected"-arguments,
     359             :  * except the HTTP response code, are given.  The best use case
     360             :  * is when what matters to check is the HTTP response code, e.g.
     361             :  * when a bogus WTID was passed.
     362             :  *
     363             :  * @param label the command label
     364             :  * @param wtid_reference reference to any command which can provide
     365             :  *        a wtid.  If NULL is given, then a all zeroed WTID is
     366             :  *        used that will at 99.9999% probability NOT match any
     367             :  *        existing WTID known to the exchange.
     368             :  * @param index index number of the WTID to track, in case there
     369             :  *        are multiple on offer.
     370             :  * @param expected_response_code expected HTTP response code.
     371             :  * @return the command.
     372             :  */
     373             : struct TALER_TESTING_Command
     374           1 : TALER_TESTING_cmd_track_transfer_empty (const char *label,
     375             :                                         const char *wtid_reference,
     376             :                                         unsigned int index,
     377             :                                         unsigned int expected_response_code)
     378             : {
     379             :   struct TrackTransferState *tts;
     380             : 
     381           1 :   tts = GNUNET_new (struct TrackTransferState);
     382           1 :   tts->wtid_reference = wtid_reference;
     383           1 :   tts->index = index;
     384           1 :   tts->expected_response_code = expected_response_code;
     385             :   {
     386           1 :     struct TALER_TESTING_Command cmd = {
     387             :       .cls = tts,
     388             :       .label = label,
     389             :       .run = &track_transfer_run,
     390             :       .cleanup = &track_transfer_cleanup
     391             :     };
     392             : 
     393           1 :     return cmd;
     394             :   }
     395             : }
     396             : 
     397             : 
     398             : /**
     399             :  * Make a "track transfer" command, specifying which amount and
     400             :  * wire fee are expected.
     401             :  *
     402             :  * @param label the command label.
     403             :  * @param wtid_reference reference to any command which can provide
     404             :  *        a wtid.  Will be the one tracked.
     405             :  * @param index in case there are multiple WTID offered, this
     406             :  *        parameter selects a particular one.
     407             :  * @param expected_response_code expected HTTP response code.
     408             :  * @param expected_total_amount how much money we expect being moved
     409             :  *        with this wire-transfer.
     410             :  * @param expected_wire_fee expected wire fee.
     411             :  * @return the command
     412             :  */
     413             : struct TALER_TESTING_Command
     414           2 : TALER_TESTING_cmd_track_transfer (const char *label,
     415             :                                   const char *wtid_reference,
     416             :                                   unsigned int index,
     417             :                                   unsigned int expected_response_code,
     418             :                                   const char *expected_total_amount,
     419             :                                   const char *expected_wire_fee)
     420             : {
     421             :   struct TrackTransferState *tts;
     422             : 
     423           2 :   tts = GNUNET_new (struct TrackTransferState);
     424           2 :   tts->wtid_reference = wtid_reference;
     425           2 :   tts->index = index;
     426           2 :   tts->expected_response_code = expected_response_code;
     427           2 :   tts->expected_total_amount = expected_total_amount;
     428           2 :   tts->expected_wire_fee = expected_wire_fee;
     429             :   {
     430           2 :     struct TALER_TESTING_Command cmd = {
     431             :       .cls = tts,
     432             :       .label = label,
     433             :       .run = &track_transfer_run,
     434             :       .cleanup = &track_transfer_cleanup
     435             :     };
     436             : 
     437           2 :     return cmd;
     438             :   }
     439             : }
     440             : 
     441             : 
     442             : /* end of testing_api_cmd_gransfer_get.c */

Generated by: LCOV version 1.14