gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-merchant] branch master updated (6f5656a -> 0b14a3f)


From: gnunet
Subject: [GNUnet-SVN] [taler-merchant] branch master updated (6f5656a -> 0b14a3f)
Date: Sat, 17 Mar 2018 01:58:25 +0100

This is an automated email from the git hooks/post-receive script.

marcello pushed a change to branch master
in repository merchant.

    from 6f5656a  fix PHP prerequisites.
     new 37dbd24  re-enable twisted tests
     new c867eeb  preparing to HTTP response body modification.
     new c8e6304  comments
     new c1b34d2  check if twister is installed.
     new 502d453  fix multi-coin payment.
     new f2156b6  multicoin check paid.
     new 32b1fab  enabling twisted command.
     new 5d8989f  trigger 424
     new 0c741d5  trigger 424 confict caused by exchange.
     new 68afddc  do not treat 424 Failed Dependency as "unexpected".
     new 4699510  typo
     new b55506b  Double twister instance plus first coverage effort
     new ec3f361  malforming /history response body, and avoid extracting error 
codes from NULL responses.
     new be0f954  /proposal cb called with response code == 0.
     new 9934b64  test against invalid proposal.
     new 66a55b5  be more gentle with unexpected response codes.
     new 8f05359  trigger 404 @ /proposal
     new aa96993  proposal-lookup 404 Not Found.
     new 8284c9a  unparsable response for proposal-lookup.
     new 3d93e64  cause invalid proposal-lookup response.
     new c63fcc5  re-enabling 402 Failed Dependency from /track/transaction.
     new 0b14a3f  fulfillment URL mandatory.

The 22 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 configure.ac                                       |  21 ++
 src/backend/taler-merchant-httpd.c                 |   2 +-
 src/backend/taler-merchant-httpd_history.c         |   2 +
 src/backend/taler-merchant-httpd_parsing.c         |  42 ++-
 src/backend/taler-merchant-httpd_proposal.c        |  14 +-
 .../taler-merchant-httpd_track-transaction.c       |  51 ++-
 src/backend/taler-merchant-httpd_track-transfer.c  |  23 +-
 src/include/taler_merchant_service.h               |   8 +-
 src/include/taler_merchant_testing_lib.h           |   3 +-
 src/lib/Makefile.am                                |  45 +--
 src/lib/merchant_api_history.c                     |  13 +-
 src/lib/merchant_api_pay.c                         |   5 +-
 src/lib/merchant_api_proposal.c                    |  21 +-
 src/lib/merchant_api_track_transaction.c           |   4 +
 src/lib/test_merchant_api_new.c                    |   3 +-
 src/lib/test_merchant_api_proxy_exchange.conf      |  29 ++
 src/lib/test_merchant_api_proxy_merchant.conf      |  30 ++
 src/lib/test_merchant_api_twisted.c                | 391 ++++++++++++++++++++-
 src/lib/test_merchant_api_twisted.conf             |  31 --
 src/lib/testing_api_cmd_history.c                  |  12 +-
 src/lib/testing_api_cmd_pay.c                      |  57 +--
 src/lib/testing_api_cmd_proposal.c                 |  63 +++-
 src/lib/testing_api_cmd_track.c                    |   6 +-
 src/lib/testing_api_helpers.c                      |   4 +-
 24 files changed, 697 insertions(+), 183 deletions(-)
 create mode 100644 src/lib/test_merchant_api_proxy_exchange.conf
 create mode 100644 src/lib/test_merchant_api_proxy_merchant.conf

diff --git a/configure.ac b/configure.ac
index b13a58a..3385461 100644
--- a/configure.ac
+++ b/configure.ac
@@ -218,6 +218,27 @@ then
   fi
 fi
 
+# check for libtalertwistertesting
+twistertesting=0
+AC_MSG_CHECKING([for talerwtistertesting])
+AC_ARG_WITH([twister],
+            [AS_HELP_STRING([--with-twister=PFX], [base of 
libtalertwistertesting])],
+            [AC_MSG_RESULT([given as $with_twister])],
+            [AC_MSG_RESULT([not given])
+             with_twister=yes])
+AS_CASE([$with_twister],
+        [yes], [],
+        [no], [AC_MSG_WARN([no twister-testing will be compiled])],
+        [LDFLAGS="-L$with_twister/lib $LDFLAGS"
+         CPPFLAGS="-I$with_twister/include $CPPFLAGS"])
+AC_CHECK_LIB(talertwistertesting,TALER_TESTING_run_twister,
+  [AC_CHECK_HEADER([taler/taler_twister_testing_lib.h],[twistertesting=1],,
+                   [#ifdef HAVE_GNUNET_PLATFORM_H
+                      #include <gnunet/platform.h>
+                    #endif])]
+  ,,[-ltalerexchange -ltalerbank])
+AM_CONDITIONAL(HAVE_TWISTER, test x$twistertesting = x1)
+
 # gcov compilation
 AC_MSG_CHECKING(whether to compile with support for code coverage analysis)
 AC_ARG_ENABLE([coverage],
diff --git a/src/backend/taler-merchant-httpd.c 
b/src/backend/taler-merchant-httpd.c
index 174be2d..017d6a1 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -408,7 +408,7 @@ handle_mhd_completion_callback (void *cls,
 
   if (NULL == hc)
     return;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Finished handling request for `%s' with status %d\n",
               hc->rh->url,
               (int) toe);
diff --git a/src/backend/taler-merchant-httpd_history.c 
b/src/backend/taler-merchant-httpd_history.c
index 207ddca..ef0d3e6 100644
--- a/src/backend/taler-merchant-httpd_history.c
+++ b/src/backend/taler-merchant-httpd_history.c
@@ -132,6 +132,7 @@ MH_handler_history (struct TMH_RequestHandler *rh,
   enum GNUNET_DB_QueryStatus qs;
   struct ProcessContractClosure pcc;
 
+  LOG_INFO ("Serving /history\n");
   response = json_array ();
   str = MHD_lookup_connection_value (connection,
                                      MHD_GET_ARGUMENT_KIND,
@@ -280,6 +281,7 @@ MH_handler_history (struct TMH_RequestHandler *rh,
   ret = TMH_RESPONSE_reply_json (connection,
                                  response,
                                  MHD_HTTP_OK);
+  LOG_INFO ("/history, http code: %d\n", MHD_HTTP_OK);
   json_decref (response);
   return ret;
 }
diff --git a/src/backend/taler-merchant-httpd_parsing.c 
b/src/backend/taler-merchant-httpd_parsing.c
index f04313a..333637c 100644
--- a/src/backend/taler-merchant-httpd_parsing.c
+++ b/src/backend/taler-merchant-httpd_parsing.c
@@ -64,7 +64,7 @@ struct Buffer
 
 
 /**
- * Initialize a buffer.
+ * Initialize a buffer and copy first chunk of data in it.
  *
  * @param buf the buffer to initialize
  * @param data the initial data
@@ -189,7 +189,7 @@ TMH_PARSE_post_cleanup_callback (void *con_cls)
  *               may be parsed in the future (call again);
  *               `*json` will be NULL if we need to be called again,
  *                and non-NULL if we are done.
- *    #GNUNET_NO is request incomplete or invalid
+ *    #GNUNET_NO if request is incomplete or invalid
  *               (error message was generated)
  *    #GNUNET_SYSERR on internal error
  *               (we could not even queue an error message,
@@ -203,7 +203,10 @@ TMH_PARSE_post_json (struct MHD_Connection *connection,
                      json_t **json)
 {
   struct Buffer *r = *con_cls;
-
+  
+  TALER_LOG_DEBUG ("Will parse: %.*s\n",
+                   (int) *upload_data_size,
+                   upload_data);
   *json = NULL;
   if (NULL == *con_cls)
   {
@@ -219,21 +222,27 @@ TMH_PARSE_post_json (struct MHD_Connection *connection,
       *con_cls = NULL;
       buffer_deinit (r);
       GNUNET_free (r);
-      return (MHD_NO ==
-              TMH_RESPONSE_reply_internal_error (connection,
-                                                TALER_EC_PARSER_OUT_OF_MEMORY,
-                                                 "out of memory"))
-        ? GNUNET_SYSERR : GNUNET_NO;
+      /* return GNUNET_SYSERR if this isn't even
+       * able to generate proper error response.  */
+      return (MHD_NO == TMH_RESPONSE_reply_internal_error
+        (connection,
+         TALER_EC_PARSER_OUT_OF_MEMORY,
+         "out of memory")) ? GNUNET_SYSERR : GNUNET_NO;
     }
     /* everything OK, wait for more POST data */
     *upload_data_size = 0;
     *con_cls = r;
     return GNUNET_YES;
   }
+
+  /* When zero, upload is over.  */
   if (0 != *upload_data_size)
   {
-    /* We are seeing an old request with more data available. */
+    TALER_LOG_INFO ("Parser asking for more data"
+                    ", current data size is %lu\n",
+                    *upload_data_size);
 
+    /* We are seeing an old request with more data available. */
     if (GNUNET_OK !=
         buffer_append (r,
                        upload_data,
@@ -244,17 +253,19 @@ TMH_PARSE_post_json (struct MHD_Connection *connection,
       *con_cls = NULL;
       buffer_deinit (r);
       GNUNET_free (r);
-      return (MHD_NO ==
-              TMH_RESPONSE_reply_request_too_large (connection))
-        ? GNUNET_SYSERR : GNUNET_NO;
+      return (MHD_NO == TMH_RESPONSE_reply_request_too_large
+        (connection)) ? GNUNET_SYSERR : GNUNET_NO;
     }
+
     /* everything OK, wait for more POST data */
     *upload_data_size = 0;
     return GNUNET_YES;
   }
 
+  TALER_LOG_DEBUG ("About to parse: %.*s\n",
+                   (int) r->fill,
+                   r->data);
   /* We have seen the whole request. */
-
   *json = json_loadb (r->data,
                       r->fill,
                       0,
@@ -263,9 +274,8 @@ TMH_PARSE_post_json (struct MHD_Connection *connection,
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Failed to parse JSON request body\n");
-    return (MHD_YES ==
-            TMH_RESPONSE_reply_invalid_json (connection))
-      ? GNUNET_NO : GNUNET_SYSERR;
+    return (MHD_YES == TMH_RESPONSE_reply_invalid_json
+      (connection)) ? GNUNET_NO : GNUNET_SYSERR;
   }
   buffer_deinit (r);
   GNUNET_free (r);
diff --git a/src/backend/taler-merchant-httpd_proposal.c 
b/src/backend/taler-merchant-httpd_proposal.c
index 64517b3..1cdea4a 100644
--- a/src/backend/taler-merchant-httpd_proposal.c
+++ b/src/backend/taler-merchant-httpd_proposal.c
@@ -281,6 +281,7 @@ proposal_put (struct MHD_Connection *connection,
 
   if (NULL == instance)
   {
+    TALER_LOG_DEBUG ("Giving 'default' instance\n");
     instance = "default";
   }
 
@@ -296,9 +297,10 @@ proposal_put (struct MHD_Connection *connection,
 
     if (NULL == mi)
     {
-      return TMH_RESPONSE_reply_internal_error (connection,
-                                                
TALER_EC_PROPOSAL_ORDER_PARSE_ERROR,
-                                                "merchant instance not found");
+      TALER_LOG_WARNING ("Does 'default' instance exist?\n");
+      return TMH_RESPONSE_reply_not_found (connection,
+                                           TALER_EC_CONTRACT_INSTANCE_UNKNOWN,
+                                           "merchant instance (order:instance) 
not found");
     }
     if (NULL == json_object_get (order, "merchant"))
     {
@@ -385,7 +387,7 @@ proposal_put (struct MHD_Connection *connection,
     GNUNET_JSON_parse_free (spec);
     return TMH_RESPONSE_reply_not_found (connection,
                                         TALER_EC_CONTRACT_INSTANCE_UNKNOWN,
-                                        "Unknown instance given");
+                                        "Unknown instance 
(order:merchant:instance) given");
   }
   /* add fields to the contract that the backend should provide */
   json_object_set (order,
@@ -520,8 +522,10 @@ MH_handler_proposal_put (struct TMH_RequestHandler *rh,
                              &root);
   if (GNUNET_SYSERR == res)
     return MHD_NO;
-  /* the POST's body has to be further fetched */
+
+  /* A error response was already generated */
   if ( (GNUNET_NO == res) ||
+  /* or, need more data to accomplish parsing */
        (NULL == root) )
     return MHD_YES;
 
diff --git a/src/backend/taler-merchant-httpd_track-transaction.c 
b/src/backend/taler-merchant-httpd_track-transaction.c
index b5e76ee..4446691 100644
--- a/src/backend/taler-merchant-httpd_track-transaction.c
+++ b/src/backend/taler-merchant-httpd_track-transaction.c
@@ -571,11 +571,11 @@ proof_cb (void *cls,
 
 
 /**
- * Function called with detailed wire transfer data.
- * We were trying to find out in which wire transfer one of the
- * coins was involved in. Now we know. What we do now is first
- * obtain the inverse: all other coins of that wire transfer,
- * which is what we prefer to store.
+ * This function takes the wtid from the coin being tracked
+ * and _track_ it against the exchange.  This way, we know
+ * all the other coins which were aggregated together with
+ * this one.  This way we save further HTTP requests to track
+ * the other coins.
  *
  * @param cls closure with a `struct TrackCoinContext`
  * @param http_status HTTP status code we got, 0 on exchange protocol violation
@@ -624,8 +624,10 @@ wtid_cb (void *cls,
   }
   tctx->current_wtid = *wtid;
   tctx->current_execution_time = execution_time;
+
   pcc.p_ret = NULL;
-  /* FIXME: change to avoid using callback! */
+  /* attempt to find this wtid's track from our database,
+     Will make pcc.p_ret point to a "proof", if one exists. */
   qs = db->find_proof_by_wtid (db->cls,
                               tctx->current_exchange,
                               wtid,
@@ -644,11 +646,13 @@ wtid_cb (void *cls,
                                "Fail to query database about proofs"));
     return;
   }
-  /* WARNING: if two transactions got aggregated under the same
-     WTID, then this branch is always taken (when attempting to
-     track the second transaction). */
+
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
   {
+    /* How come this wtid was already stored into the
+       database and _not all_ of its coins were already
+       tracked? Inconsistent state (! At least regarding
+       what the exchange tells us) */
     GNUNET_break_op (0);
     resume_track_transaction_with_response
       (tcc->tctx,
@@ -661,6 +665,7 @@ wtid_cb (void *cls,
                                     "coin_pub", GNUNET_JSON_from_data_auto 
(&tcc->coin_pub)));
     return;
   }
+
   tctx->wdh = TALER_EXCHANGE_track_transfer (tctx->eh,
                                              wtid,
                                              &wire_deposits_cb,
@@ -792,9 +797,9 @@ find_exchange (struct TrackTransactionContext *tctx);
 
 
 /**
- * This function is called to trace the wire transfers for
- * all of the coins of the transaction of the @a tctx.  Once
- * we have traced all coins, we build the response.
+ * This function is called to 'trace the wire transfers'
+ * (true?) for all of the coins of the transaction of the @a tctx.
+ * Once we have traced all coins, we build the response.
  *
  * @param tctx track context with established connection to exchange
  */
@@ -803,10 +808,15 @@ trace_coins (struct TrackTransactionContext *tctx)
 {
   struct TrackCoinContext *tcc;
 
+  /* Make sure we are connected to the exchange. */
   GNUNET_assert (NULL != tctx->eh);
+
   for (tcc = tctx->tcc_head; NULL != tcc; tcc = tcc->next)
+
+    /* How come one does't have wtid? */
     if (GNUNET_YES != tcc->have_wtid)
       break;
+
   if (NULL != tcc)
   {
     if (0 != strcmp (tcc->exchange_url,
@@ -837,6 +847,8 @@ trace_coins (struct TrackTransactionContext *tctx)
 
 /**
  * Function called with the result of our exchange lookup.
+ * Merely provide the execution context to the routine actually
+ * tracking the coin.
  *
  * @param cls the `struct TrackTransactionContext`
  * @param eh NULL if exchange was not found to be acceptable
@@ -921,7 +933,7 @@ transfer_cb (void *cls,
 
 
 /**
- * Function called with information about a coin that was deposited.
+ * Responsible to get the current coin wtid and store it into its state.
  *
  * @param cls closure
  * @param transaction_id of the contract
@@ -957,6 +969,11 @@ coin_cb (void *cls,
   GNUNET_CONTAINER_DLL_insert (tctx->tcc_head,
                                tctx->tcc_tail,
                                tcc);
+
+  /* find all those <coin, wtid> pairs associated to
+     this contract term's hash code.  The callback
+     will then set the wtid for the "current coin"
+     context. */
   qs = db->find_transfers_by_hash (db->cls,
                                   h_contract_terms,
                                   &transfer_cb,
@@ -1094,7 +1111,10 @@ MH_handler_track_transaction (struct TMH_RequestHandler 
*rh,
     return TMH_RESPONSE_reply_not_found (connection,
                                         
TALER_EC_TRACK_TRANSACTION_INSTANCE_UNKNOWN,
                                         "unknown instance");
-
+  
+  /* Map order id to contract terms; the objective is to get
+     the contract term's hashcode so as to retrieve all the
+     coins which have been deposited for it. */
   qs = db->find_contract_terms (db->cls,
                                &contract_terms,
                                 &last_session_id,
@@ -1154,6 +1174,9 @@ MH_handler_track_transaction (struct TMH_RequestHandler 
*rh,
 
   tctx->qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
   db->preflight (db->cls);
+
+  /* Find coins which have been deposited for this contract,
+     and retrieve the wtid for each one. */
   qs = db->find_payments (db->cls,
                          &tctx->h_contract_terms,
                          &tctx->mi->pubkey,
diff --git a/src/backend/taler-merchant-httpd_track-transfer.c 
b/src/backend/taler-merchant-httpd_track-transfer.c
index e22b51e..4ce2e59 100644
--- a/src/backend/taler-merchant-httpd_track-transfer.c
+++ b/src/backend/taler-merchant-httpd_track-transfer.c
@@ -426,9 +426,9 @@ track_transfer_cleanup (struct TM_HandlerContext *hc)
 
 
 /**
- * Function called with information about a coin that was transfered.
- * Verify that it matches the information claimed by the exchange.
- * Update the `check_transfer_result` field accordingly.
+ * This function checks that the information about the coin which
+ * was paid back by _this_ wire transfer matches what _we_ (the merchant)
+ * knew about this coin.
  *
  * @param cls closure with our `struct TrackTransferContext *`
  * @param transaction_id of the contract
@@ -651,10 +651,19 @@ wire_transfer_cb (void *cls,
                      wire_fee))
     return;
 
+  /* Now we want to double-check that any (Taler coin) deposit
+   * which is accounted into _this_ wire transfer, does exist
+   * into _our_ database.  This is the rationale: if the
+   * exchange paid us for it, we must have received it _beforehands_!
+   *
+   * details_length is how many (Taler coin) deposits have been
+   * aggregated into _this_ wire transfer.
+   */
   for (unsigned int i=0;i<details_length;i++)
   {
     rctx->current_offset = i;
     rctx->current_detail = &details[i];
+    /* Set the coin as "never seen" before. */
     rctx->check_transfer_result = GNUNET_NO;
     qs = db->find_payments_by_hash_and_coin (db->cls,
                                             &details[i].h_contract_terms,
@@ -680,8 +689,8 @@ wire_transfer_cb (void *cls,
     if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
     {
       /* The exchange says we made this deposit, but WE do not
-         recall making it! Well, let's say thanks and accept the
-         money! */
+         recall making it (corrupted / unreliable database?)!
+         Well, let's say thanks and accept the money! */
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                   "Failed to find payment data in DB\n");
       rctx->check_transfer_result = GNUNET_OK;
@@ -713,8 +722,8 @@ wire_transfer_cb (void *cls,
       rctx->response = NULL;
       return;
     }
-    /* Response is consistent with the /deposit we made, remember
-       it for future reference */
+    /* Response is consistent with the /deposit we made,
+       remember it for future reference */
     for (unsigned int i=0;i<MAX_RETRIES;i++)
     {
       qs = db->store_coin_to_transfer (db->cls,
diff --git a/src/include/taler_merchant_service.h 
b/src/include/taler_merchant_service.h
index 2dd0b20..6c0339f 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -303,12 +303,12 @@ struct TALER_MERCHANT_PayCoin
   struct TALER_CoinSpendPrivateKeyP coin_priv;
 
   /**
-   * Amount this coin is to contribute (including fee).
+   * Amount this coin contributes to (including fee).
    */
   struct TALER_Amount amount_with_fee;
 
   /**
-   * Amount this coin is to contribute (without fee).
+   * Amount this coin contributes to (without fee).
    */
   struct TALER_Amount amount_without_fee;
 
@@ -493,12 +493,12 @@ struct TALER_MERCHANT_PaidCoin
   struct TALER_CoinSpendSignatureP coin_sig;
 
   /**
-   * Amount this coin is to contribute (including fee).
+   * Amount this coin contributes to (including fee).
    */
   struct TALER_Amount amount_with_fee;
 
   /**
-   * Amount this coin is to contribute (without fee).
+   * Amount this coin contributes to (without fee).
    */
   struct TALER_Amount amount_without_fee;
 
diff --git a/src/include/taler_merchant_testing_lib.h 
b/src/include/taler_merchant_testing_lib.h
index c155eb1..c487edb 100644
--- a/src/include/taler_merchant_testing_lib.h
+++ b/src/include/taler_merchant_testing_lib.h
@@ -103,7 +103,8 @@ TALER_TESTING_cmd_proposal_lookup
    struct GNUNET_CURL_Context *ctx,
    const char *merchant_url,
    unsigned int http_status,
-   const char *proposal_reference);
+   const char *proposal_reference,
+   const char *order_id);
 
 /**
  * Make a "check payment" test command.
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 4419e67..9235863 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -77,32 +77,35 @@ if HAVE_TALERFAKEBANK
 check_PROGRAMS = \
   test_merchant_api_new \
   test_merchant_api
-  # test_merchant_api_twisted
+
+if HAVE_TWISTER
+  check_PROGRAMS += test_merchant_api_twisted
+endif
+
 endif
 
 TESTS = \
   $(check_PROGRAMS)
 
-# To be uncommented once the twister is deployed.
-#test_merchant_api_twisted_SOURCES = \
-#  test_merchant_api_twisted.c
-#test_merchant_api_twisted_LDADD = \
-#  $(top_srcdir)/src/backenddb/libtalermerchantdb.la \
-#  libtalermerchant.la \
-#  $(LIBGCRYPT_LIBS) \
-#  -ltalertesting \
-#  -ltalermerchanttesting \
-#  -ltalertwistertesting \
-#  -ltalerfakebank \
-#  -ltalerbank \
-#  -ltalerexchange \
-#  -ltalerjson \
-#  -ltalerutil \
-#  -lgnunetjson \
-#  -lgnunetcurl \
-#  -lgnunetutil \
-#  -ljansson \
-#  -ltalertwister
+test_merchant_api_twisted_SOURCES = \
+  test_merchant_api_twisted.c
+test_merchant_api_twisted_LDADD = \
+  $(top_srcdir)/src/backenddb/libtalermerchantdb.la \
+  libtalermerchant.la \
+  $(LIBGCRYPT_LIBS) \
+  -ltalertesting \
+  -ltalermerchanttesting \
+  -ltalertwistertesting \
+  -ltalerfakebank \
+  -ltalerbank \
+  -ltalerexchange \
+  -ltalerjson \
+  -ltalerutil \
+  -lgnunetjson \
+  -lgnunetcurl \
+  -lgnunetutil \
+  -ljansson \
+  -ltalertwister
 
 test_merchant_api_new_SOURCES = \
   test_merchant_api_new.c
diff --git a/src/lib/merchant_api_history.c b/src/lib/merchant_api_history.c
index 0a3e01a..3ca8a12 100644
--- a/src/lib/merchant_api_history.c
+++ b/src/lib/merchant_api_history.c
@@ -99,7 +99,17 @@ history_raw_cb (void *cls,
   switch (response_code)
   {
   case 0:
-    break;
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "/history returned response code 0\n");
+    /**
+     * The response was malformed or didn't have the
+     * application/json header.
+     */
+    ho->cb (ho->cb_cls,
+            response_code,
+            TALER_EC_INVALID_RESPONSE,
+            json);
+    return;
   case MHD_HTTP_OK:
     ho->cb (ho->cb_cls,
             MHD_HTTP_OK,
@@ -124,6 +134,7 @@ history_raw_cb (void *cls,
     response_code = 0;
     break;
   }
+
   ho->cb (ho->cb_cls,
           response_code,
          TALER_JSON_get_error_code (json),
diff --git a/src/lib/merchant_api_pay.c b/src/lib/merchant_api_pay.c
index 849b22b..75c2384 100644
--- a/src/lib/merchant_api_pay.c
+++ b/src/lib/merchant_api_pay.c
@@ -666,10 +666,11 @@ prepare_pay_generic (struct GNUNET_CURL_Context *ctx,
   dr.timestamp = GNUNET_TIME_absolute_hton (timestamp);
   dr.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline);
   dr.merchant = *merchant_pub;
+
   for (unsigned int i=0;i<num_coins;i++)
   {
-    const struct TALER_MERCHANT_PayCoin *coin = &coins[i];
-    struct TALER_MERCHANT_PaidCoin *p = &pc[i];
+    const struct TALER_MERCHANT_PayCoin *coin = &coins[i]; // coin priv.
+    struct TALER_MERCHANT_PaidCoin *p = &pc[i]; // coin pub.
     struct TALER_Amount fee;
 
     /* prepare 'dr' for this coin to generate coin signature */
diff --git a/src/lib/merchant_api_proposal.c b/src/lib/merchant_api_proposal.c
index 8f4f67f..a670f8b 100644
--- a/src/lib/merchant_api_proposal.c
+++ b/src/lib/merchant_api_proposal.c
@@ -136,7 +136,12 @@ handle_proposal_finished (void *cls,
   switch (response_code)
   {
   case 0:
-    break;
+    po->cb (po->cb_cls,
+            response_code,
+            TALER_EC_INVALID_RESPONSE,
+            json,
+            order_id);
+    return;
   case MHD_HTTP_OK:
     {
       if (GNUNET_OK !=
@@ -274,17 +279,11 @@ handle_proposal_lookup_finished (void *cls,
 
   if (MHD_HTTP_OK != response_code)
   {
-    char *s;
-
-    s = json_dumps (json,
-                    JSON_COMPACT);
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Proposal lookup failed with HTTP status code %u on input 
`%s'\n",
-                (unsigned int) response_code,
-                s);
-    if (NULL != s)
-      free (s);
-    GNUNET_break_op (0);
+                "Proposal lookup failed with HTTP status code %u\n",
+                (unsigned int) response_code);
+    GNUNET_break (0);
+
     plo->cb (plo->cb_cls,
              response_code,
              json,
diff --git a/src/lib/merchant_api_track_transaction.c 
b/src/lib/merchant_api_track_transaction.c
index e38660c..ae5d903 100644
--- a/src/lib/merchant_api_track_transaction.c
+++ b/src/lib/merchant_api_track_transaction.c
@@ -97,6 +97,10 @@ handle_track_transaction_finished (void *cls,
       /* Expect time stamp of when the transfer is supposed to happen */
     }
     break;
+  case MHD_HTTP_FAILED_DEPENDENCY:
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Exchange gave inconsistent response\n");
+    break;
   case MHD_HTTP_NOT_FOUND:
     /* Nothing really to verify, this should never
        happen, we should pass the JSON reply to the application */
diff --git a/src/lib/test_merchant_api_new.c b/src/lib/test_merchant_api_new.c
index b2979fa..444636d 100644
--- a/src/lib/test_merchant_api_new.c
+++ b/src/lib/test_merchant_api_new.c
@@ -337,7 +337,8 @@ run (void *cls,
                                        is->ctx,
                                        merchant_url,
                                        MHD_HTTP_OK,
-                                       "create-proposal-2"),
+                                       "create-proposal-2",
+                                       NULL),
 
     TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-1"),
 
diff --git a/src/lib/test_merchant_api_proxy_exchange.conf 
b/src/lib/test_merchant_api_proxy_exchange.conf
new file mode 100644
index 0000000..6e311cb
--- /dev/null
+++ b/src/lib/test_merchant_api_proxy_exchange.conf
@@ -0,0 +1,29 @@
+# This file is in the public domain.
+
+# Config to set up the twister between the
+# merchant and the exchange.
+
+[twister]
+# HTTP listen port for twister (the merchant
+# will transparently use this URL as the "exchange")
+HTTP_PORT = 8888
+
+# HTTP Destination for twister, so the real exchange
+# URL.  Note: no trailing '/'!
+DESTINATION_BASE_URL = "http://localhost:8081";
+
+# Control port for TCP
+# PORT = 8889
+HOSTNAME = localhost
+ACCEPT_FROM = 127.0.0.1;
+ACCEPT_FROM6 = ::1;
+
+# Control port for UNIX
+UNIXPATH = /tmp/taler-service-twister-exchange.sock
+UNIX_MATCH_UID = NO
+UNIX_MATCH_GID = YES
+
+# Launching of twister by ARM
+# BINARY = taler-service-twister
+# AUTOSTART = NO
+# FORCESTART = NO
diff --git a/src/lib/test_merchant_api_proxy_merchant.conf 
b/src/lib/test_merchant_api_proxy_merchant.conf
new file mode 100644
index 0000000..706ac29
--- /dev/null
+++ b/src/lib/test_merchant_api_proxy_merchant.conf
@@ -0,0 +1,30 @@
+# This file is in the public domain.
+
+# Config to set up the twister between the
+# HTTP client (= the "lib" code) and the
+# merchant service.
+
+[twister]
+# HTTP listen port for twister ("lib" code will
+# transparently use this URL as the "merchant")
+HTTP_PORT = 8889
+
+# HTTP Destination for twister, so the real
+# merchant URL.  Note: no trailing '/'!
+DESTINATION_BASE_URL = "http://localhost:8082";
+
+# Control port for TCP
+# PORT = 8889
+HOSTNAME = localhost
+ACCEPT_FROM = 127.0.0.1;
+ACCEPT_FROM6 = ::1;
+
+# Control port for UNIX
+UNIXPATH = /tmp/taler-service-twister-merchant.sock
+UNIX_MATCH_UID = NO
+UNIX_MATCH_GID = YES
+
+# Launching of twister by ARM
+# BINARY = taler-service-twister
+# AUTOSTART = NO
+# FORCESTART = NO
diff --git a/src/lib/test_merchant_api_twisted.c 
b/src/lib/test_merchant_api_twisted.c
index 8ffbd2b..963bbfd 100644
--- a/src/lib/test_merchant_api_twisted.c
+++ b/src/lib/test_merchant_api_twisted.c
@@ -46,14 +46,33 @@
 #define CONFIG_FILE "test_merchant_api_twisted.conf"
 
 /**
+ * Configuration file for the proxy between merchant and
+ * exchange.  Not used directly here in the code (instead
+ * used in the merchant config), but kept around for consistency.
+ */
+#define PROXY_EXCHANGE_CONFIG_FILE \
+  "test_merchant_api_proxy_exchange.conf"
+
+/**
+ * Configuration file for the proxy between "lib" and merchant.
+ */
+#define PROXY_MERCHANT_CONFIG_FILE \
+  "test_merchant_api_proxy_merchant.conf"
+
+/**
  * Exchange base URL.  Could also be taken from config.
  */
 #define EXCHANGE_URL "http://localhost:8081/";
 
 /**
- * (real) Twister URL.  Used at startup time to check if it runs.
+ * Twister URL that proxies the exchange.
  */
-static char *twister_url;
+static char *twister_exchange_url;
+
+/**
+ * Twister URL that proxies the merchant.
+ */
+static char *twister_merchant_url;
 
 /**
  * URL of the fakebank.  Obtained from CONFIG_FILE's
@@ -77,9 +96,14 @@ static char *exchange_url;
 static struct GNUNET_OS_Process *merchantd;
 
 /**
- * Twister process.
+ * Twister process that proxies the exchange.
  */
-static struct GNUNET_OS_Process *twisterd;
+static struct GNUNET_OS_Process *twisterexchanged;
+
+/**
+ * Twister process that proxies the merchant.
+ */
+static struct GNUNET_OS_Process *twistermerchantd;
 
 /**
  * Account number of the exchange at the bank.
@@ -157,9 +181,334 @@ run (void *cls,
 {
 
   struct TALER_TESTING_Command commands[] = {
-    TALER_TESTING_cmd_hack_response_code ("hack-1",
-                                          CONFIG_FILE,
-                                          MHD_HTTP_FORBIDDEN),
+
+
+  /**** Covering /proposal lib ****/
+
+  /**
+   * Make the merchant return a 400 Bad Request response
+   * due to uploaded body malformation.
+   */
+  TALER_TESTING_cmd_malform_request
+    ("malform-order",
+     PROXY_MERCHANT_CONFIG_FILE),
+
+  TALER_TESTING_cmd_proposal
+    ("create-proposal-0",
+     twister_merchant_url,
+     is->ctx,
+     MHD_HTTP_BAD_REQUEST,
+     /* giving a valid JSON to not make it fail before
+      * data reaches the merchant.  */
+     "{\"not\": \"used\"}",
+     NULL),
+
+    TALER_TESTING_cmd_hack_response_code
+      ("proposal-500",
+       PROXY_MERCHANT_CONFIG_FILE,
+       MHD_HTTP_INTERNAL_SERVER_ERROR),
+
+  TALER_TESTING_cmd_proposal
+    ("create-proposal-1",
+     twister_merchant_url,
+     is->ctx,
+     /* This status code == 0 is gotten via a 500 Internal Server
+      * Error handed to the library.  */
+     MHD_HTTP_INTERNAL_SERVER_ERROR,
+     /* giving a valid JSON to not make it fail before
+      * data reaches the merchant.  */
+     "{\"not\": \"used\"}",
+     NULL),
+
+  /**
+   * Cause the PUT /proposal callback to be called
+   * with a response code == 0.  We achieve this by malforming
+   * the response body.
+   */
+
+    TALER_TESTING_cmd_malform_response
+      ("malform-proposal",
+       PROXY_MERCHANT_CONFIG_FILE),
+
+    TALER_TESTING_cmd_proposal
+      ("create-proposal-2",
+       twister_merchant_url,
+       is->ctx,
+       0,
+       "{\"max_fee\":\
+          {\"currency\":\"EUR\",\
+           \"value\":0,\
+           \"fraction\":50000000},\
+        \"order_id\":\"1\",\
+        \"refund_deadline\":\"\\/Date(0)\\/\",\
+        \"pay_deadline\":\"\\/Date(99999999999)\\/\",\
+        \"amount\":\
+          {\"currency\":\"EUR\",\
+           \"value\":5,\
+           \"fraction\":0},\
+        \"summary\": \"merchant-lib testcase\",\
+        \"products\": [ {\"description\":\"ice cream\",\
+                         \"value\":\"{EUR:5}\"} ] }",
+        NULL),
+
+
+    /**
+     * Cause proposal to be invalid: this is achieved
+     * by deleting the "order_id" field of it.
+     */
+    TALER_TESTING_cmd_delete_object ("remove-order-id",
+                                     PROXY_MERCHANT_CONFIG_FILE,
+                                     "order_id"),
+    TALER_TESTING_cmd_proposal
+      ("create-proposal-3",
+       twister_merchant_url,
+       is->ctx,
+       0,
+       "{\"max_fee\":\
+          {\"currency\":\"EUR\",\
+           \"value\":0,\
+           \"fraction\":50000000},\
+         \"fulfillment_url\": \"https://example.com/\",\
+         \"order_id\":\"2\",\
+         \"refund_deadline\":\"\\/Date(0)\\/\",\
+         \"pay_deadline\":\"\\/Date(99999999999)\\/\",\
+         \"amount\":\
+           {\"currency\":\"EUR\",\
+            \"value\":5,\
+            \"fraction\":0},\
+         \"summary\": \"merchant-lib testcase\",\
+         \"products\": [ {\"description\":\"ice cream\",\
+                          \"value\":\"{EUR:5}\"} ] }",
+         NULL),
+    /**
+     * Cause a 404 Not Found response code,
+     * due to a non existing merchant instance.
+     */
+    TALER_TESTING_cmd_proposal
+      ("create-proposal-4",
+       twister_merchant_url,
+       is->ctx,
+       MHD_HTTP_NOT_FOUND,
+       "{\"amount\":\"EUR:5\",\
+         \"fulfillment_url\": \"https://example.com/\",\
+         \"summary\": \"merchant-lib testcase\"}",
+       "non-existent-instance"),
+
+    /* Cause a 404 Not Found from /proposal/lookup,
+     * due to a non existing order id being queried.  */
+    TALER_TESTING_cmd_proposal_lookup ("lookup-0",
+                                       is->ctx,
+                                       twister_merchant_url,
+                                       MHD_HTTP_NOT_FOUND,
+                                       NULL,
+                                       "does-not-exist"),
+    /* Cause a unparsable response to be returned.  */
+    TALER_TESTING_cmd_malform_response
+      ("malform-proposal-lookup",
+       PROXY_MERCHANT_CONFIG_FILE),
+    /* To be short, we'll make a _error_ response to be
+     * unparsable.  */
+    TALER_TESTING_cmd_proposal_lookup ("lookup-1",
+                                       is->ctx,
+                                       twister_merchant_url,
+                                       0, // response code.
+                                       NULL,
+                                       "does-not-exist"),
+
+    /* Generating a proposal-lookup response which doesn't pass
+     * validation, by removing a field that is expected by the
+     * library.  The library will call the callback with a status
+     * code of 0.  */
+
+    /* First step is to create a _valid_ proposal, so that
+     * we can lookup for it later.  */
+    TALER_TESTING_cmd_proposal
+      ("create-proposal-5",
+       twister_merchant_url,
+       is->ctx,
+       MHD_HTTP_OK,
+       "{\"max_fee\":\
+          {\"currency\":\"EUR\",\
+           \"value\":0,\
+           \"fraction\":50000000},\
+        \"order_id\":\"5\",\
+        \"refund_deadline\":\"\\/Date(0)\\/\",\
+        \"pay_deadline\":\"\\/Date(99999999999)\\/\",\
+        \"amount\":\
+          {\"currency\":\"EUR\",\
+           \"value\":5,\
+           \"fraction\":0},\
+        \"fulfillment_url\": \"https://example.com/\",\
+        \"summary\": \"merchant-lib testcase\",\
+        \"products\": [ {\"description\":\"ice cream\",\
+                         \"value\":\"{EUR:5}\"} ] }",
+        NULL),
+
+    /* Remove expected field.  */
+    TALER_TESTING_cmd_delete_object ("remove-contract-terms",
+                                     PROXY_MERCHANT_CONFIG_FILE,
+                                     "contract_terms"),
+
+    /* lookup!  */
+    TALER_TESTING_cmd_proposal_lookup ("lookup-5",
+                                       is->ctx,
+                                       twister_merchant_url,
+                                       // expected response code.
+                                       0,
+                                       "create-proposal-5",
+                                       NULL),
+    /**** Covering /history lib ****/
+
+    /**
+     * Changing the response code to a unexpected
+     * one.  NOTE: this is unexpected to the *lib*
+     * code, that is then expected to trigger some
+     * emergency behaviour, like setting the response
+     * code to zero before calling the callback.
+     */
+    TALER_TESTING_cmd_hack_response_code
+      ("twist-history",
+       PROXY_MERCHANT_CONFIG_FILE,
+       MHD_HTTP_GONE),
+
+    TALER_TESTING_cmd_history ("history-0",
+                               twister_merchant_url,
+                               is->ctx,
+                               0,
+                               GNUNET_TIME_UNIT_ZERO_ABS,
+                               1, // nresult
+                               10, // start
+                               10), // nrows
+    /**
+     * Making the returned response malformed, in order
+     * to make the JSON downloader+parser fail and call
+     * the lib passing a response code as zero.
+     */
+    TALER_TESTING_cmd_malform_response
+      ("malform-history",
+       PROXY_MERCHANT_CONFIG_FILE),
+
+    TALER_TESTING_cmd_history ("history-1",
+                               twister_merchant_url,
+                               is->ctx,
+                               0, // also works with MHD_HTTP_GONE
+                               GNUNET_TIME_UNIT_ZERO_ABS,
+                               1, // nresult
+                               10, // start
+                               10), // nrows
+
+
+    /**
+     * Move money to the exchange's bank account.
+     */
+    CMD_TRANSFER_TO_EXCHANGE ("create-reserve-1",
+                              "EUR:2.02"),
+
+    /**
+     * Make a reserve exist, according to the previous
+     * transfer.
+     */
+    CMD_EXEC_WIREWATCH ("wirewatch-1"),
+
+    TALER_TESTING_cmd_check_bank_transfer
+      ("check_bank_transfer-2",
+       "http://localhost:8081/";,
+       "EUR:2.02", USER_ACCOUNT_NO, EXCHANGE_ACCOUNT_NO),
+
+    TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1",
+                                       is->exchange,
+                                       "create-reserve-1",
+                                       "EUR:1",
+                                       MHD_HTTP_OK),
+    TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2",
+                                       is->exchange,
+                                       "create-reserve-1",
+                                       "EUR:1",
+                                       MHD_HTTP_OK),
+    TALER_TESTING_cmd_status ("withdraw-status",
+                              is->exchange,
+                              "create-reserve-1",
+                              "EUR:0",
+                              MHD_HTTP_OK),
+
+    TALER_TESTING_cmd_proposal
+      ("create-proposal-6",
+       twister_merchant_url,
+       is->ctx,
+       MHD_HTTP_OK,
+       "{\"max_fee\":\
+          {\"currency\":\"EUR\",\
+           \"value\":0,\
+           \"fraction\":50000000},\
+        \"order_id\":\"11\",\
+        \"refund_deadline\":\"\\/Date(0)\\/\",\
+        \"pay_deadline\":\"\\/Date(99999999999)\\/\",\
+        \"fulfillment_url\": \"https://example.com/\",\
+        \"amount\":\
+          {\"currency\":\"EUR\",\
+           \"value\":2,\
+           \"fraction\":0},\
+        \"summary\": \"merchant-lib testcase\",\
+        \"products\": [ {\"description\":\"ice cream\",\
+                         \"value\":\"{EUR:3}\"} ] }",
+        NULL),
+
+    TALER_TESTING_cmd_check_payment ("check-payment-1",
+                                     twister_merchant_url,
+                                     is->ctx,
+                                     MHD_HTTP_OK,
+                                     "create-proposal-6",
+                                     GNUNET_NO),
+
+    TALER_TESTING_cmd_pay ("deposit-simple",
+                           twister_merchant_url,
+                           is->ctx,
+                           MHD_HTTP_OK,
+                           "create-proposal-6",
+                           "withdraw-coin-1;" \
+                           "withdraw-coin-2",
+                           "EUR:2",
+                           "EUR:1.99", // no sense now
+                           "EUR:0.01"), // no sense now
+
+    TALER_TESTING_cmd_check_payment ("check-payment-2",
+                                     twister_merchant_url,
+                                     is->ctx,
+                                     MHD_HTTP_OK,
+                                     "create-proposal-6",
+                                     GNUNET_YES),
+
+    CMD_EXEC_AGGREGATOR ("run-aggregator"),
+
+    TALER_TESTING_cmd_check_bank_transfer
+      ("check_bank_transfer-1",
+       twister_exchange_url,
+       /* paid,         1.97 =
+          brutto        2.00 -
+          deposit fee   0.01 * 2 -
+          wire fee      0.01
+       */
+       "EUR:1.97", 2, 62),
+
+    /* Should instead change the response body somehow! */
+    TALER_TESTING_cmd_modify_object ("hack-0",
+                                     PROXY_EXCHANGE_CONFIG_FILE,
+                                     "total",
+                                     "EUR:0.98"),
+
+    TALER_TESTING_cmd_delete_object ("hack-1",
+                                     PROXY_EXCHANGE_CONFIG_FILE,
+                                     "deposits.0"),
+
+    TALER_TESTING_cmd_merchant_track_transaction
+      ("track-transaction-1",
+       twister_merchant_url,
+       is->ctx,
+       MHD_HTTP_FAILED_DEPENDENCY,
+       "check_bank_transfer-1",
+       "deposit-simple",
+       "EUR:0.01"), // ignored
+
     /**
      * End the suite.  Fixme: better to have a label for this
      * too, as it shows a "(null)" token on logs.
@@ -167,6 +516,7 @@ run (void *cls,
     TALER_TESTING_cmd_end ()
   };
 
+
   TALER_TESTING_run_with_fakebank (is,
                                    commands,
                                    fakebank_url);
@@ -204,8 +554,12 @@ main (int argc,
       (CONFIG_FILE)))
     return 77;
 
-  if (NULL == (twister_url = TALER_TESTING_prepare_twister
-      (CONFIG_FILE)))
+  if (NULL == (twister_exchange_url = TALER_TESTING_prepare_twister
+      (PROXY_EXCHANGE_CONFIG_FILE)))
+    return 77;
+
+  if (NULL == (twister_merchant_url = TALER_TESTING_prepare_twister
+      (PROXY_MERCHANT_CONFIG_FILE)))
     return 77;
 
   TALER_TESTING_cleanup_files (CONFIG_FILE);
@@ -223,21 +577,22 @@ main (int argc,
 
     if (NULL == (merchantd = TALER_TESTING_run_merchant
         (CONFIG_FILE)))
-    {
-      purge_process (twisterd);
-      return 1; // 1 is fine; after all is merchant test cases.
-    }
+      // 1 is fine; after all this is merchant test cases.
+      return 1;
 
-    if (NULL == (twisterd = TALER_TESTING_run_twister
-        (CONFIG_FILE)))
+    if (NULL == (twisterexchanged = TALER_TESTING_run_twister
+        (PROXY_EXCHANGE_CONFIG_FILE)))
+      return 77;
+
+    if (NULL == (twistermerchantd = TALER_TESTING_run_twister
+        (PROXY_MERCHANT_CONFIG_FILE)))
       return 77;
 
     ret = TALER_TESTING_setup_with_exchange (&run, NULL,
                                              CONFIG_FILE);
     purge_process (merchantd);
-    purge_process (twisterd);
-    GNUNET_free (merchant_url);
-    GNUNET_free (twister_url);
+    purge_process (twisterexchanged);
+    purge_process (twistermerchantd);
 
     if (GNUNET_OK != ret)
       return 1;
diff --git a/src/lib/test_merchant_api_twisted.conf 
b/src/lib/test_merchant_api_twisted.conf
index ea298df..3bd9cea 100644
--- a/src/lib/test_merchant_api_twisted.conf
+++ b/src/lib/test_merchant_api_twisted.conf
@@ -1,34 +1,5 @@
 # This file is in the public domain.
 
-#########################
-# Twister configuration #
-#########################
-
-[twister]
-# HTTP listen port for twister
-HTTP_PORT = 8888
-
-# HTTP Destination for twister.  The test-Webserver needs
-# to listen on the port used here.  Note: no trailing '/'!
-DESTINATION_BASE_URL = "http://localhost:8081";
-
-# Control port for TCP
-# PORT = 8889
-HOSTNAME = localhost
-ACCEPT_FROM = 127.0.0.1;
-ACCEPT_FROM6 = ::1;
-
-# Control port for UNIX
-UNIXPATH = /tmp/taler-service-twister.sock
-UNIX_MATCH_UID = NO
-UNIX_MATCH_GID = YES
-
-# Launching of twister by ARM
-# BINARY = taler-service-twister
-# AUTOSTART = NO
-# FORCESTART = NO
-
-#
 [PATHS]
 # Persistant data storage for the testcase
 TALER_TEST_HOME = test_merchant_api_home/
@@ -127,7 +98,6 @@ TIP_EXCHANGE = http://localhost:8088/
 TIP_RESERVE_PRIV_FILENAME = reserve_dkey.priv
 NAME = Test Tipping Merchant 2
 
-
 [merchant-instance-wireformat-tor]
 TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/merchant/wire/test.json
 
@@ -163,7 +133,6 @@ BIC = GENODEF1SRL
 SALT = 17919252168512238964
 ADDRESS = "Garching"
 
-
 ##########################
 # Exchange configuration #
 ##########################
diff --git a/src/lib/testing_api_cmd_history.c 
b/src/lib/testing_api_cmd_history.c
index 3667d34..8cad77a 100644
--- a/src/lib/testing_api_cmd_history.c
+++ b/src/lib/testing_api_cmd_history.c
@@ -157,8 +157,18 @@ history_cb (void *cls,
   struct GNUNET_TIME_Absolute entry_timestamp;
 
   hs->ho = NULL;
+
+
   if (hs->http_status != http_status)
-    TALER_TESTING_FAIL (hs->is);
+      TALER_TESTING_FAIL (hs->is);
+
+  if (0 == hs->http_status)
+  {
+    /* 0 was caused intentionally by the tests,
+     * move on without further checking. */
+    TALER_TESTING_interpreter_next (hs->is); 
+    return;
+  }
 
   nresult = json_array_size (json);
   if (hs->nresult != nresult)
diff --git a/src/lib/testing_api_cmd_pay.c b/src/lib/testing_api_cmd_pay.c
index e628de9..6e8229a 100644
--- a/src/lib/testing_api_cmd_pay.c
+++ b/src/lib/testing_api_cmd_pay.c
@@ -394,13 +394,12 @@ check_payment_run (void *cls,
  * @return the command
  */
 struct TALER_TESTING_Command
-TALER_TESTING_cmd_check_payment (
-  const char *label,
-  const char *merchant_url,
-  struct GNUNET_CURL_Context *ctx,
-  unsigned int http_status,
-  const char *proposal_reference,
-  unsigned int expect_paid)
+TALER_TESTING_cmd_check_payment (const char *label,
+                                 const char *merchant_url,
+                                 struct GNUNET_CURL_Context *ctx,
+                                 unsigned int http_status,
+                                 const char *proposal_reference,
+                                 unsigned int expect_paid)
 {
   struct CheckPaymentState *cps;
   struct TALER_TESTING_Command cmd;
@@ -430,9 +429,10 @@ TALER_TESTING_cmd_check_payment (
  * @param[in] coins string specifying coins to add to @a pc,
  *            clobbered in the process
  * @param is interpreter state
- * @param amount_with_fee
- * @param amount_without_fee
- * @param refund_fee
+ * @param amount_with_fee total amount to be paid for a contract.
+ * @param amount_without_fee to be removed, there is no
+ *        per-contract fee, only per-coin exists.
+ * @param refund_fee per-contract? per-coin?
  * @return #GNUNET_OK on success
  */
 static int
@@ -454,6 +454,7 @@ build_coins (struct TALER_MERCHANT_PayCoin **pc,
     char *ctok;
     unsigned int ci;
     struct TALER_MERCHANT_PayCoin *icoin;
+    const struct TALER_EXCHANGE_DenomPublicKey *dpk;
 
     /* Token syntax is "LABEL[/NUMBER]" */
     ctok = strchr (token, '/');
@@ -512,6 +513,15 @@ build_coins (struct TALER_MERCHANT_PayCoin **pc,
     icoin->denom_pub = denom_pub->key;
     icoin->denom_sig = *denom_sig;
     icoin->denom_value = *denom_value;
+    icoin->amount_with_fee = *denom_value;
+    
+    GNUNET_assert (NULL != (dpk = TALER_TESTING_find_pk
+      (is->keys, &icoin->denom_value)));
+
+    GNUNET_assert (GNUNET_SYSERR != TALER_amount_subtract
+      (&icoin->amount_without_fee,
+       &icoin->denom_value,
+       &dpk->fee_deposit));
 
     GNUNET_assert
       (GNUNET_OK == TALER_TESTING_get_trait_url
@@ -519,14 +529,6 @@ build_coins (struct TALER_MERCHANT_PayCoin **pc,
 
     GNUNET_assert
       (GNUNET_OK == TALER_string_to_amount
-        (amount_with_fee, &icoin->amount_with_fee));
-
-    GNUNET_assert
-      (GNUNET_OK == TALER_string_to_amount
-        (amount_without_fee, &icoin->amount_without_fee));
-
-    GNUNET_assert
-      (GNUNET_OK == TALER_string_to_amount
         (refund_fee, &icoin->refund_fee));
   }
 
@@ -980,16 +982,15 @@ pay_traits (void *cls,
  * @return the command
  */
 struct TALER_TESTING_Command
-TALER_TESTING_cmd_pay (
-  const char *label,
-  const char *merchant_url,
-  struct GNUNET_CURL_Context *ctx,
-  unsigned int http_status,
-  const char *proposal_reference,
-  const char *coin_reference,
-  const char *amount_with_fee,
-  const char *amount_without_fee,
-  const char *refund_fee)
+TALER_TESTING_cmd_pay (const char *label,
+                       const char *merchant_url,
+                       struct GNUNET_CURL_Context *ctx,
+                       unsigned int http_status,
+                       const char *proposal_reference,
+                       const char *coin_reference,
+                       const char *amount_with_fee,
+                       const char *amount_without_fee,
+                       const char *refund_fee)
 {
   struct PayState *ps;
   struct TALER_TESTING_Command cmd;
diff --git a/src/lib/testing_api_cmd_proposal.c 
b/src/lib/testing_api_cmd_proposal.c
index 3c6c439..4529e40 100644
--- a/src/lib/testing_api_cmd_proposal.c
+++ b/src/lib/testing_api_cmd_proposal.c
@@ -135,6 +135,8 @@ struct ProposalLookupState
    * Reference to a proposal operation.
    */
   const char *proposal_reference;
+
+  const char *order_id;
 };
 
 /**
@@ -262,6 +264,17 @@ proposal_cb (void *cls,
   struct ProposalState *ps = cls;
 
   ps->po = NULL;
+
+  if (ps->http_status != http_status)
+    TALER_TESTING_FAIL (ps->is);
+
+  if (0 == ps->http_status)
+  {
+    TALER_LOG_DEBUG ("/proposal, expected 0 status code\n");
+    TALER_TESTING_interpreter_next (ps->is);
+    return;
+  }
+
   switch (http_status)
   {
   case MHD_HTTP_OK:
@@ -279,12 +292,15 @@ proposal_cb (void *cls,
                   ps->is),
                 s);
     GNUNET_free_non_null (s);
-    TALER_TESTING_interpreter_fail (ps->is);
+    /**
+     * Not failing, as test cases are _supposed_
+     * to create non 200 OK situations.
+     */
+    TALER_TESTING_interpreter_next (ps->is);
   }
   return;
   }
 
-
   if (NULL ==
      (ps->plo = TALER_MERCHANT_proposal_lookup
        (ps->ctx,
@@ -386,8 +402,8 @@ proposal_cleanup (void *cls,
     ps->plo = NULL;
   }
 
-  GNUNET_free ((void *) ps->order_id);
-  GNUNET_free ((void *) ps->contract_terms);
+  GNUNET_free_non_null ((void *) ps->order_id);
+  GNUNET_free_non_null ((void *) ps->contract_terms);
   GNUNET_free (ps);
 }
 
@@ -444,6 +460,7 @@ TALER_TESTING_cmd_proposal (const char *label,
   ps->http_status = http_status;
   ps->ctx = ctx;
   ps->merchant_url = merchant_url;
+  ps->instance = instance;
 
   cmd.cls = ps;
   cmd.label = label;
@@ -498,24 +515,37 @@ proposal_lookup_run (void *cls,
   const struct TALER_TESTING_Command *proposal_cmd;
   const char *order_id;
   const struct GNUNET_CRYPTO_EddsaPublicKey *nonce;
+  /* Only used if we do NOT use the nonce from traits.  */
+  struct GNUNET_CRYPTO_EddsaPublicKey dummy_nonce;
   #define GET_TRAIT_NONCE(cmd,ptr) \
     TALER_TESTING_get_trait_peer_key_pub (cmd, 1, ptr)
 
   pls->is = is;
-  proposal_cmd = TALER_TESTING_interpreter_lookup_command
-    (is, pls->proposal_reference);
 
-  if (NULL == proposal_cmd)
-    TALER_TESTING_FAIL (is);
+  if (NULL != pls->order_id)
+  {
+    order_id = pls->order_id;
+    GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+                                &dummy_nonce,
+                                sizeof (dummy_nonce));
+    nonce = &dummy_nonce;
+  }
+  else
+  {
+    proposal_cmd = TALER_TESTING_interpreter_lookup_command
+      (is, pls->proposal_reference);
 
-  if (GNUNET_OK != GET_TRAIT_NONCE (proposal_cmd,
-                                    &nonce))
-    TALER_TESTING_FAIL (is); 
+    if (NULL == proposal_cmd)
+      TALER_TESTING_FAIL (is);
 
-  if (GNUNET_OK != TALER_TESTING_get_trait_order_id
-      (proposal_cmd, 0, &order_id))
-    TALER_TESTING_FAIL (is);
+    if (GNUNET_OK != GET_TRAIT_NONCE (proposal_cmd,
+                                      &nonce))
+      TALER_TESTING_FAIL (is); 
 
+    if (GNUNET_OK != TALER_TESTING_get_trait_order_id
+        (proposal_cmd, 0, &order_id))
+      TALER_TESTING_FAIL (is);
+  }
   pls->plo = TALER_MERCHANT_proposal_lookup (pls->ctx,
                                              pls->merchant_url,
                                              order_id,
@@ -527,7 +557,6 @@ proposal_lookup_run (void *cls,
 }
 
 
-
 /**
  * Make a "proposal lookup" command.
  *
@@ -540,7 +569,8 @@ TALER_TESTING_cmd_proposal_lookup
    struct GNUNET_CURL_Context *ctx,
    const char *merchant_url,
    unsigned int http_status,
-   const char *proposal_reference)
+   const char *proposal_reference,
+   const char *order_id)
 {
   struct ProposalLookupState *pls;
   struct TALER_TESTING_Command cmd;
@@ -550,6 +580,7 @@ TALER_TESTING_cmd_proposal_lookup
   pls->proposal_reference = proposal_reference;
   pls->merchant_url = merchant_url;
   pls->ctx = ctx;
+  pls->order_id = order_id;
 
   cmd.cls = pls;
   cmd.label = label;
diff --git a/src/lib/testing_api_cmd_track.c b/src/lib/testing_api_cmd_track.c
index e665373..f3d6338 100644
--- a/src/lib/testing_api_cmd_track.c
+++ b/src/lib/testing_api_cmd_track.c
@@ -101,9 +101,9 @@ track_transaction_cb (void *cls,
     TALER_TESTING_interpreter_fail (tts->is);
     return;
   }
-  if (MHD_HTTP_OK != http_status)
-    TALER_TESTING_FAIL (tts->is);
-
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "/track/transaction, response code: %u\n",
+              http_status);
   TALER_TESTING_interpreter_next (tts->is);
 }
 
diff --git a/src/lib/testing_api_helpers.c b/src/lib/testing_api_helpers.c
index e445856..bca193c 100644
--- a/src/lib/testing_api_helpers.c
+++ b/src/lib/testing_api_helpers.c
@@ -59,7 +59,7 @@ TALER_TESTING_run_merchant (const char *config_filename)
 
   /* give child time to start and bind against the socket */
   fprintf (stderr,
-           "Waiting for `taler-merchant-httpd' to be ready");
+           "Waiting for `taler-merchant-httpd' to be ready\n");
   iter = 0;
   do
     {
@@ -74,7 +74,7 @@ TALER_TESTING_run_merchant (const char *config_filename)
        GNUNET_OS_process_destroy (merchant_proc);
        MERCHANT_FAIL ();
       }
-      fprintf (stderr, ".");
+      fprintf (stderr, ".\n");
       sleep (1);
       iter++;
     }

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]