LCOV - code coverage report
Current view: top level - lib - testing_api_cmd_track.c (source / functions) Hit Total Coverage
Test: rcoverage.info Lines: 74 103 71.8 %
Date: 2018-05-16 06:16:58 Functions: 8 9 88.9 %

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2014-2018 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 lib/testing_api_cmd_track.c
      22             :  * @brief command to test /track/transaction and /track/transfer.
      23             :  * @author Marcello Stanisci
      24             :  */
      25             : 
      26             : #include "platform.h"
      27             : #include <taler/taler_exchange_service.h>
      28             : #include <taler/taler_testing_lib.h>
      29             : #include "taler_merchant_service.h"
      30             : #include "taler_merchant_testing_lib.h"
      31             : 
      32             : struct TrackTransactionState
      33             : {
      34             :   struct TALER_MERCHANT_TrackTransactionHandle *tth;
      35             : 
      36             :   struct TALER_TESTING_Interpreter *is;
      37             : 
      38             :   const char *merchant_url;
      39             : 
      40             :   struct GNUNET_CURL_Context *ctx;
      41             : 
      42             :   unsigned int http_status;
      43             : 
      44             :   const char *transfer_reference;
      45             : 
      46             :   const char *pay_reference;
      47             : 
      48             :   const char *wire_fee;
      49             : 
      50             :   /* This only accounts for the *first* wire transfer that
      51             :    * payed back this transaction.  So far, this suffices to
      52             :    * make the paygen work.  */
      53             :   const char *wtid_str; 
      54             : 
      55             :   /**
      56             :    * Binary form of wtid.  Some commands expect it - via
      57             :    * appropriate traits - to be in binary form.
      58             :    */
      59             :   struct TALER_WireTransferIdentifierRawP wtid;
      60             : 
      61             : 
      62             :   const char *exchange_url;
      63             : 
      64             : };
      65             : 
      66             : struct TrackTransferState
      67             : {
      68             : 
      69             :   struct TALER_MERCHANT_TrackTransferHandle *tth;
      70             : 
      71             :   struct TALER_TESTING_Interpreter *is;
      72             : 
      73             :   const char *merchant_url;
      74             : 
      75             :   struct GNUNET_CURL_Context *ctx;
      76             : 
      77             :   unsigned int http_status;
      78             : 
      79             :   const char *check_bank_reference;
      80             : 
      81             :   /**
      82             :    * #OC_PAY command which we expect in the result.
      83             :    * Since we are tracking a bank transaction, we want to know
      84             :    * which (Taler) deposit is associated with the bank
      85             :    * transaction being tracked now.
      86             :    */
      87             :   const char *pay_reference;
      88             : };
      89             : 
      90             : /**
      91             :  * Function called with detailed wire transfer data.
      92             :  *
      93             :  * @param cls closure
      94             :  * @param http_status HTTP status code we got,
      95             :  *        0 on exchange protocol violation
      96             :  * @param ec taler-specific error code
      97             :  * @param json original json reply
      98             :  */
      99             : static void
     100           2 : track_transaction_cb (void *cls,
     101             :                       unsigned int http_status,
     102             :                       enum TALER_ErrorCode ec,
     103             :                       const json_t *json)
     104             : {
     105           2 :   struct TrackTransactionState *tts = cls;
     106             :   json_t *wtid_str;
     107             :   json_t *exchange_url;
     108             : 
     109           2 :   tts->tth = NULL;
     110           2 :   if (tts->http_status != http_status)
     111             :   {
     112           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     113             :                 "Unexpected response code %u (%d) to command %s\n",
     114             :                 http_status,
     115             :                 ec,
     116             :                 TALER_TESTING_interpreter_get_current_label
     117             :                   (tts->is));
     118           0 :     TALER_TESTING_interpreter_fail (tts->is);
     119           0 :     return;
     120             :   }
     121           2 :   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
     122             :               "/track/transaction, response code: %u\n",
     123             :               http_status);
     124             : 
     125             :   /* Only storing first element's wtid, as this works around
     126             :    * the disability of the real bank to provide a "bank check"
     127             :    * CMD as the fakebank does.  */
     128           2 :   if (NULL == (wtid_str = json_object_get
     129           2 :     (json_array_get (json, 0), "wtid")))
     130             :   {
     131           0 :     TALER_TESTING_interpreter_fail (tts->is);
     132           0 :     return; 
     133             :   }
     134             : 
     135           2 :   if (NULL == (exchange_url = json_object_get
     136           2 :     (json_array_get (json, 0), "exchange")))
     137             :   {
     138             :   
     139           0 :     TALER_TESTING_interpreter_fail (tts->is);
     140           0 :     return;
     141             :   }
     142             : 
     143           2 :   tts->exchange_url = GNUNET_strdup
     144             :     (json_string_value (exchange_url));
     145           2 :   tts->wtid_str = GNUNET_strdup
     146             :     (json_string_value (wtid_str));
     147             : 
     148           2 :   TALER_TESTING_interpreter_next (tts->is);
     149             : }
     150             : 
     151             : /**
     152             :  * Callback for a /track/transfer operation
     153             :  *
     154             :  * @param cls closure for this function
     155             :  * @param http_status HTTP response code returned by the server
     156             :  * @param ec taler-specific error code
     157             :  * @param sign_key exchange key used to sign @a json, or NULL
     158             :  * @param json original json reply (may include signatures,
     159             :  *        those have then been validated already)
     160             :  * @param h_wire hash of the wire transfer address the transfer
     161             :  *        went to, or NULL on error
     162             :  * @param total_amount total amount of the wire transfer, or NULL
     163             :  *        if the exchange could not provide any @a wtid (set only
     164             :  *        if @a http_status is #MHD_HTTP_OK)
     165             :  * @param details_length length of the @a details array
     166             :  * @param details array with details about the combined
     167             :  *        transactions
     168             :  */
     169             : static void
     170           4 : track_transfer_cb
     171             :   (void *cls,
     172             :    unsigned int http_status,
     173             :    enum TALER_ErrorCode ec,
     174             :    const struct TALER_ExchangePublicKeyP *sign_key,
     175             :    const json_t *json,
     176             :    const struct GNUNET_HashCode *h_wire,
     177             :    const struct TALER_Amount *total_amount,
     178             :    unsigned int details_length,
     179             :    const struct TALER_MERCHANT_TrackTransferDetails *details)
     180             : {
     181             :   /* FIXME, deeper checks should be implemented here. */
     182           4 :   struct TrackTransferState *tts = cls;
     183             : 
     184           4 :   tts->tth = NULL;
     185           4 :   if (tts->http_status != http_status)
     186             :   {
     187           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     188             :                 "Unexpected response code %u (%d) to command %s\n",
     189             :                 http_status,
     190             :                 ec,
     191             :                 TALER_TESTING_interpreter_get_current_label
     192             :                   (tts->is));
     193           0 :     TALER_TESTING_interpreter_fail (tts->is);
     194           0 :     return;
     195             :   }
     196           4 :   switch (http_status)
     197             :   {
     198             :     case MHD_HTTP_OK:
     199           4 :       break;
     200             :     default:
     201           0 :       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     202             :                   "Unhandled HTTP status.\n");
     203             :   }
     204           4 :   TALER_TESTING_interpreter_next (tts->is);
     205             : }
     206             : 
     207             : 
     208             : 
     209             : /**
     210             :  * Runs the command.  Note that upon return, the interpreter
     211             :  * will not automatically run the next command, as the command
     212             :  * may continue asynchronously in other scheduler tasks.  Thus,
     213             :  * the command must ensure to eventually call
     214             :  * #TALER_TESTING_interpreter_next() or
     215             :  * #TALER_TESTING_interpreter_fail().
     216             :  *
     217             :  * @param is interpreter state
     218             :  */
     219             : static void
     220           4 : track_transfer_run (void *cls,
     221             :                     const struct TALER_TESTING_Command *cmd,
     222             :                     struct TALER_TESTING_Interpreter *is)
     223             : {
     224           4 :   struct TrackTransferState *tts = cls;
     225             :   struct TALER_WireTransferIdentifierRawP *wtid;
     226             :   const struct TALER_TESTING_Command *check_bank_cmd;
     227             :   const char *exchange_url;
     228             : 
     229           4 :   tts->is = is;
     230           4 :   check_bank_cmd = TALER_TESTING_interpreter_lookup_command
     231             :     (is, tts->check_bank_reference);
     232           4 :   if (NULL == check_bank_cmd)
     233           0 :     TALER_TESTING_FAIL (is);
     234           4 :   if (GNUNET_OK != TALER_TESTING_get_trait_wtid
     235             :       (check_bank_cmd, 0, &wtid))
     236           0 :     TALER_TESTING_FAIL (is);
     237           4 :   if (GNUNET_OK != TALER_TESTING_get_trait_url
     238             :       (check_bank_cmd, 0, &exchange_url))
     239           0 :     TALER_TESTING_FAIL (is);
     240           4 :   tts->tth = TALER_MERCHANT_track_transfer (tts->ctx,
     241             :                                             tts->merchant_url,
     242             :                                             "default",
     243             :                                             "x-taler-bank",
     244             :                                             wtid,
     245             :                                             exchange_url,
     246             :                                             &track_transfer_cb,
     247             :                                             tts);
     248           4 :   GNUNET_assert (NULL != tts->tth);
     249             : }
     250             : 
     251             : /**
     252             :  * Runs the command.  Note that upon return, the interpreter
     253             :  * will not automatically run the next command, as the command
     254             :  * may continue asynchronously in other scheduler tasks.  Thus,
     255             :  * the command must ensure to eventually call
     256             :  * #TALER_TESTING_interpreter_next() or
     257             :  * #TALER_TESTING_interpreter_fail().
     258             :  *
     259             :  * @param is interpreter state
     260             :  */
     261             : static void
     262           2 : track_transaction_run (void *cls,
     263             :                        const struct TALER_TESTING_Command *cmd,
     264             :                        struct TALER_TESTING_Interpreter *is)
     265             : {
     266           2 :   struct TrackTransactionState *tts = cls;
     267             :   const char *order_id;
     268             :   const struct TALER_TESTING_Command *pay_cmd;
     269             : 
     270           2 :   tts->is = is;
     271             : 
     272           2 :   if ( NULL ==
     273           2 :      ( pay_cmd = TALER_TESTING_interpreter_lookup_command
     274             :       (is, tts->pay_reference)))
     275           0 :     TALER_TESTING_FAIL (is);
     276             : 
     277           2 :   if (GNUNET_OK != TALER_TESTING_get_trait_order_id
     278             :       (pay_cmd, 0, &order_id))
     279           0 :     TALER_TESTING_FAIL (is);
     280             : 
     281           2 :   tts->tth = TALER_MERCHANT_track_transaction
     282             :     (tts->ctx,
     283             :      tts->merchant_url,
     284             :      "default",
     285             :      order_id,
     286             :      &track_transaction_cb,
     287             :      tts);
     288             : 
     289           2 :   GNUNET_assert (NULL != tts->tth);
     290             : }
     291             : 
     292             : 
     293             : /**
     294             :  * Clean up after the command.  Run during forced termination
     295             :  * (CTRL-C) or test failure or test success.
     296             :  *
     297             :  * @param cls closure
     298             :  */
     299             : static void
     300           4 : track_transfer_cleanup (void *cls,
     301             :                         const struct TALER_TESTING_Command *cmd)
     302             : {
     303           4 :   struct TrackTransferState *tts = cls;
     304             : 
     305           4 :   if (NULL != tts->tth)
     306             :   {
     307           0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     308             :                 "/track/transfer (test) operation"
     309             :                 " did not complete\n");
     310           0 :     TALER_MERCHANT_track_transfer_cancel (tts->tth);
     311             :   }
     312           4 :   GNUNET_free (tts);
     313           4 : }
     314             : 
     315             : /**
     316             :  * Clean up after the command.  Run during forced termination
     317             :  * (CTRL-C) or test failure or test success.
     318             :  *
     319             :  * @param cls closure
     320             :  */
     321             : static void
     322           2 : track_transaction_cleanup (void *cls,
     323             :                            const struct TALER_TESTING_Command *cmd)
     324             : {
     325           2 :   struct TrackTransactionState *tts = cls;
     326             : 
     327           2 :   if (NULL != tts->tth)
     328             :   {
     329           0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     330             :                 "/track/transaction (test) operation"
     331             :                 " did not complete\n");
     332           0 :     TALER_MERCHANT_track_transaction_cancel (tts->tth);
     333             :   }
     334             : 
     335             :   /* Need to discard 'const' before freeing.  */
     336           2 :   GNUNET_free ((char *) tts->exchange_url);
     337           2 :   GNUNET_free ((char *) tts->wtid_str);
     338             : 
     339           2 :   GNUNET_free (tts);
     340           2 : }
     341             : 
     342             : 
     343             : static int
     344           0 : track_transaction_traits (void *cls,
     345             :                           void **ret,
     346             :                           const char *trait,
     347             :                           unsigned int index)
     348             : {
     349           0 :   struct TrackTransactionState *tts = cls;
     350             :   struct TALER_WireTransferIdentifierRawP *wtid_ptr;
     351             : 
     352           0 :   if (GNUNET_OK != GNUNET_STRINGS_string_to_data
     353             :       (tts->wtid_str,
     354             :        strlen (tts->wtid_str),
     355           0 :        &tts->wtid,
     356             :        sizeof (struct TALER_WireTransferIdentifierRawP)))
     357           0 :     wtid_ptr = NULL;
     358             :   else
     359           0 :     wtid_ptr = &tts->wtid;
     360             : 
     361           0 :   struct TALER_TESTING_Trait traits[] = {
     362             :     TALER_TESTING_make_trait_wtid (0, wtid_ptr),
     363           0 :     TALER_TESTING_make_trait_url (0, tts->exchange_url),
     364             :     TALER_TESTING_trait_end ()
     365             :   };
     366             : 
     367           0 :   return TALER_TESTING_get_trait (traits,
     368             :                                   ret,
     369             :                                   trait,
     370             :                                   index);
     371             :   return GNUNET_SYSERR;
     372             : }
     373             : 
     374             : /**
     375             :  * FIXME
     376             :  */
     377             : struct TALER_TESTING_Command
     378           2 : TALER_TESTING_cmd_merchant_track_transaction
     379             :   (const char *label,
     380             :    const char *merchant_url,
     381             :    struct GNUNET_CURL_Context *ctx,
     382             :    unsigned int http_status,
     383             :    const char *transfer_reference,
     384             :    const char *pay_reference,
     385             :    const char *wire_fee)
     386             : {
     387             :   struct TrackTransactionState *tts;
     388             :   struct TALER_TESTING_Command cmd;
     389             : 
     390           2 :   tts = GNUNET_new (struct TrackTransactionState);
     391           2 :   tts->merchant_url = merchant_url;
     392           2 :   tts->ctx = ctx;
     393           2 :   tts->http_status = http_status;
     394           2 :   tts->transfer_reference = transfer_reference;
     395           2 :   tts->pay_reference = pay_reference;
     396           2 :   tts->wire_fee = wire_fee;
     397             : 
     398           2 :   cmd.cls = tts;
     399           2 :   cmd.label = label;
     400           2 :   cmd.run = &track_transaction_run;
     401           2 :   cmd.cleanup = &track_transaction_cleanup;
     402           2 :   cmd.traits = &track_transaction_traits;
     403             :   // traits?
     404             : 
     405           2 :   return cmd;
     406             : }
     407             : 
     408             : 
     409             : /**
     410             :  * FIXME
     411             :  */
     412             : struct TALER_TESTING_Command
     413           4 : TALER_TESTING_cmd_merchant_track_transfer
     414             :   (const char *label,
     415             :    const char *merchant_url,
     416             :    struct GNUNET_CURL_Context *ctx,
     417             :    unsigned int http_status,
     418             :    const char *check_bank_reference,
     419             :    const char *pay_reference)
     420             : {
     421             :   struct TrackTransferState *tts;
     422             :   struct TALER_TESTING_Command cmd;
     423             : 
     424           4 :   tts = GNUNET_new (struct TrackTransferState);
     425           4 :   tts->merchant_url = merchant_url;
     426           4 :   tts->ctx = ctx;
     427           4 :   tts->http_status = http_status;
     428           4 :   tts->check_bank_reference = check_bank_reference;
     429           4 :   tts->pay_reference = pay_reference;
     430             : 
     431           4 :   cmd.cls = tts;
     432           4 :   cmd.label = label;
     433           4 :   cmd.run = &track_transfer_run;
     434           4 :   cmd.cleanup = &track_transfer_cleanup;
     435             :   // traits?
     436             : 
     437           4 :   return cmd;
     438             : }
     439             : 
     440             : /* end of testing_api_cmd_track.c */

Generated by: LCOV version 1.13