gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] 146/277: wrote tests for deposits in the db api


From: gnunet
Subject: [taler-merchant] 146/277: wrote tests for deposits in the db api
Date: Sun, 05 Jul 2020 20:50:59 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

commit e2333817a6767933608c6d3bd3216a9fcd3033e7
Author: Jonathan Buchanan <jonathan.russ.buchanan@gmail.com>
AuthorDate: Tue May 26 18:25:52 2020 -0400

    wrote tests for deposits in the db api
---
 src/backenddb/Makefile.am       |   1 +
 src/backenddb/test_merchantdb.c | 480 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 479 insertions(+), 2 deletions(-)

diff --git a/src/backenddb/Makefile.am b/src/backenddb/Makefile.am
index 3edc450..bec76cc 100644
--- a/src/backenddb/Makefile.am
+++ b/src/backenddb/Makefile.am
@@ -54,6 +54,7 @@ libtaler_plugin_merchantdb_postgres_la_LDFLAGS = \
   -ltalerpq \
   -ltalerutil \
   -ltalerjson \
+  -ltalermhd \
   -lpq \
   -lgnunetutil $(XLIB)
 
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
index d45089a..6ed0b21 100644
--- a/src/backenddb/test_merchantdb.c
+++ b/src/backenddb/test_merchantdb.c
@@ -22,6 +22,7 @@
 #include "platform.h"
 #include <taler/taler_util.h>
 #include <taler/taler_json_lib.h>
+#include <taler/taler_signatures.h>
 #include "taler_merchantdb_lib.h"
 
 
@@ -375,7 +376,8 @@ run_test_instances (struct TestInstances_Closure *cls)
                                            instances));
 
   /* Test account creation */
-  TEST_RET_ON_FAIL (test_insert_account ("test_inst", &cls->accounts[0]));
+  TEST_RET_ON_FAIL (test_insert_account (cls->is.id,
+                                         &cls->accounts[0]));
 
   /* Test accounts from instance lookup */
   instances[0].accounts_length = 1;
@@ -399,9 +401,36 @@ run_test_instances (struct TestInstances_Closure *cls)
 
   /* Test multiple accounts */
 
+  /* Test lookup account */
+  uint64_t account_serial;
+  if (1 != plugin->lookup_account (plugin->cls,
+                                   cls->is.id,
+                                   cls->accounts[0].payto_uri,
+                                   &account_serial))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Lookup account failed\n");
+    return 1;
+  }
+  if (1 != account_serial)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Lookup account failed: incorrect serial number found\n");
+    return 1;
+  }
+  if (1 == plugin->lookup_account (plugin->cls,
+                                   cls->is.id,
+                                   "payto://other-uri",
+                                   &account_serial))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Lookup account failed: account found where there is none\n");
+    return 1;
+  }
+
   /* Test instance private key deletion */
   if (0 > plugin->delete_instance_private_key (plugin->cls,
-                                               "test_inst"))
+                                               cls->is.id))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Delete instance private key failed\n");
@@ -1161,6 +1190,452 @@ test_orders (void *cls)
 }
 
 
+/**
+ * A container for deposit data.
+ */
+struct DepositData
+{
+  struct GNUNET_TIME_Absolute timestamp;
+
+  struct GNUNET_HashCode h_contract_terms;
+
+  struct TALER_CoinSpendPublicKeyP coin_pub;
+
+  const char *exchange_url;
+
+  struct TALER_Amount amount_with_fee;
+
+  struct TALER_Amount deposit_fee;
+
+  struct TALER_Amount refund_fee;
+
+  struct TALER_Amount wire_fee;
+
+  struct GNUNET_HashCode h_wire;
+
+  struct TALER_ExchangeSignatureP exchange_sig;
+
+};
+
+
+/**
+ * Closure for testing deposit lookup
+ */
+struct TestLookupDeposits_Closure
+{
+  /**
+   * Number of deposits to compare to
+   */
+  unsigned int deposits_to_cmp_length;
+
+  /**
+   * Pointer to array of deposit data
+   */
+  const struct DepositData *deposits_to_cmp;
+
+  /**
+   * Pointer to array of number of matches per deposit
+   */
+  unsigned int *results_matching;
+
+  /**
+   * Total number of results returned
+   */
+  unsigned int results_length;
+};
+
+
+static void
+lookup_deposits_cb (void *cls,
+                    const char *exchange_url,
+                    const struct TALER_CoinSpendPublicKeyP *coin_pub,
+                    const struct TALER_Amount *amount_with_fee,
+                    const struct TALER_Amount *deposit_fee,
+                    const struct TALER_Amount *refund_fee,
+                    const struct TALER_Amount *wire_fee)
+{
+  if (NULL == cls)
+    return;
+  struct TestLookupDeposits_Closure *cmp = cls;
+  cmp->results_length += 1;
+  for (unsigned int i = 0; cmp->deposits_to_cmp_length > i; ++i)
+  {
+    if ((GNUNET_OK == TALER_amount_cmp_currency (
+           &cmp->deposits_to_cmp[i].amount_with_fee,
+           amount_with_fee)) &&
+        (0 == TALER_amount_cmp (&cmp->deposits_to_cmp[i].amount_with_fee,
+                                amount_with_fee)) &&
+        (GNUNET_OK == TALER_amount_cmp_currency (
+           &cmp->deposits_to_cmp[i].deposit_fee,
+           deposit_fee)) &&
+        (0 == TALER_amount_cmp (&cmp->deposits_to_cmp[i].deposit_fee,
+                                deposit_fee)) &&
+        (GNUNET_OK == TALER_amount_cmp_currency (
+           &cmp->deposits_to_cmp[i].refund_fee,
+           refund_fee)) &&
+        (0 == TALER_amount_cmp (&cmp->deposits_to_cmp[i].refund_fee,
+                                refund_fee)) &&
+        (GNUNET_OK == TALER_amount_cmp_currency (
+           &cmp->deposits_to_cmp[i].wire_fee,
+           wire_fee)) &&
+        (0 == TALER_amount_cmp (&cmp->deposits_to_cmp[i].wire_fee,
+                                wire_fee)))
+    {
+      cmp->results_matching[i] += 1;
+    }
+
+  }
+}
+
+
+static int
+test_insert_deposit (const char *is,
+                     const struct TALER_ExchangePublicKeyP *exchange_pub,
+                     const struct DepositData *deposit)
+{
+  if (1 != plugin->insert_deposit (plugin->cls,
+                                   is,
+                                   deposit->timestamp,
+                                   &deposit->h_contract_terms,
+                                   &deposit->coin_pub,
+                                   deposit->exchange_url,
+                                   &deposit->amount_with_fee,
+                                   &deposit->deposit_fee,
+                                   &deposit->refund_fee,
+                                   &deposit->wire_fee,
+                                   &deposit->h_wire,
+                                   &deposit->exchange_sig,
+                                   exchange_pub))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Insert deposit failed\n");
+    return 1;
+  }
+  return 0;
+}
+
+
+static int
+test_lookup_deposits (const char *is,
+                      const struct GNUNET_HashCode *h_contract_terms,
+                      unsigned int deposits_length,
+                      const struct DepositData *deposits)
+{
+  struct TestLookupDeposits_Closure cls;
+  cls.deposits_to_cmp_length = deposits_length;
+  cls.deposits_to_cmp = deposits;
+  unsigned int results_matching[deposits_length];
+  for (unsigned int i = 0; deposits_length > i; ++i)
+    results_matching[i] = 0;
+  cls.results_matching = results_matching;
+  cls.results_length = 0;
+  if (0 > plugin->lookup_deposits (plugin->cls,
+                                   is,
+                                   h_contract_terms,
+                                   &lookup_deposits_cb,
+                                   &cls))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Lookup deposits failed\n");
+    return 1;
+  }
+  if (deposits_length != cls.results_length)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Lookup deposits failed: incorrect number of results 
returned\n");
+    return 1;
+  }
+  for (unsigned int i = 0; deposits_length > i; ++i)
+  {
+    if (cls.results_matching[i] != 1)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Lookup deposits failed: mismatched data\n");
+      return 1;
+    }
+  }
+  return 0;
+}
+
+
+/**
+ * Closure for deposit tests.
+ */
+struct TestDeposits_Closure
+{
+  /**
+   * The instance settings
+   */
+  struct TALER_MERCHANTDB_InstanceSettings is;
+
+  /**
+   * The instance public key
+   */
+  struct TALER_MerchantPublicKeyP merchant_pub;
+
+  /**
+   * The instance private key
+   */
+  struct TALER_MerchantPrivateKeyP merchant_priv;
+
+  /**
+   * The merchant account
+   */
+  struct TALER_MERCHANTDB_AccountDetails account;
+
+  /**
+   * The exchange public key
+   */
+  struct TALER_ExchangePublicKeyP exchange_pub;
+
+  /**
+   * The exchange private key
+   */
+  struct TALER_ExchangePrivateKeyP exchange_priv;
+
+  /**
+   * The master public key
+   */
+  struct TALER_MasterPublicKeyP master_pub;
+
+  /**
+   * The master private key
+   */
+  struct TALER_MasterPrivateKeyP master_priv;
+
+  /**
+   * The master signature
+   */
+  struct TALER_MasterSignatureP master_sig;
+
+  /**
+   * The exchange signkey start date
+   */
+  struct GNUNET_TIME_Absolute signkey_start;
+
+  /**
+   * The exchange signkey expire date
+   */
+  struct GNUNET_TIME_Absolute signkey_expire;
+
+  /**
+   * The exchange signkey end date
+   */
+  struct GNUNET_TIME_Absolute signkey_end;
+
+  /**
+   * The order data
+   */
+  struct OrderData order;
+
+  /**
+   * The array of deposits
+   */
+  struct DepositData deposits[2];
+};
+
+
+static void
+pre_test_deposits (struct TestDeposits_Closure *cls)
+{
+  /* Instance */
+  GNUNET_CRYPTO_eddsa_key_create (&cls->merchant_priv.eddsa_priv);
+  GNUNET_CRYPTO_eddsa_key_get_public (&cls->merchant_priv.eddsa_priv,
+                                      &cls->merchant_pub.eddsa_pub);
+  cls->is.id = "test_inst_deposits";
+  cls->is.name = "Test";
+  cls->is.address = json_array ();
+  GNUNET_assert (NULL != cls->is.address);
+  GNUNET_assert (0 == json_array_append (cls->is.address,
+                                         json_string ("123 Example St")));
+  cls->is.jurisdiction = json_array ();
+  GNUNET_assert (NULL != cls->is.jurisdiction);
+  GNUNET_assert (0 == json_array_append (cls->is.jurisdiction,
+                                         json_string ("Ohio")));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:1200.40",
+                                         &cls->is.default_max_deposit_fee));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:1200.40",
+                                         &cls->is.default_max_wire_fee));
+  cls->is.default_wire_fee_amortization = 1;
+  cls->is.default_wire_transfer_delay = GNUNET_TIME_relative_get_minute_ ();
+  cls->is.default_pay_delay = GNUNET_TIME_relative_get_second_ ();
+
+  /* Account */
+  GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG,
+                                    &cls->account.h_wire);
+  GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG,
+                                    &cls->account.salt);
+  cls->account.payto_uri = "payto://x-taler-bank/bank.demo.taler.net/4";
+  cls->account.active = true;
+
+  /* Signing key */
+  GNUNET_CRYPTO_eddsa_key_create (&cls->exchange_priv.eddsa_priv);
+  GNUNET_CRYPTO_eddsa_key_get_public (&cls->exchange_priv.eddsa_priv,
+                                      &cls->exchange_pub.eddsa_pub);
+  GNUNET_CRYPTO_eddsa_key_create (&cls->master_priv.eddsa_priv);
+  GNUNET_CRYPTO_eddsa_key_get_public (&cls->master_priv.eddsa_priv,
+                                      &cls->master_pub.eddsa_pub);
+  struct TALER_ExchangeSigningKeyValidityPS exch_sign;
+  exch_sign.purpose.size = htonl (sizeof (struct
+                                          TALER_ExchangeSigningKeyValidityPS));
+  exch_sign.purpose.purpose = htonl (
+    TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY);
+  GNUNET_CRYPTO_eddsa_sign (&cls->master_priv.eddsa_priv,
+                            &exch_sign,
+                            &cls->master_sig.eddsa_signature);
+  cls->signkey_start = GNUNET_TIME_absolute_get ();
+  cls->signkey_expire = GNUNET_TIME_absolute_get ();
+  cls->signkey_end = GNUNET_TIME_absolute_get ();
+
+  /* Order */
+  struct GNUNET_TIME_Absolute pay_deadline =
+    GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
+                              GNUNET_TIME_UNIT_DAYS);
+  struct GNUNET_TIME_Absolute refund_deadline =
+    GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
+                              GNUNET_TIME_UNIT_WEEKS);
+  GNUNET_TIME_round_abs (&pay_deadline);
+  GNUNET_TIME_round_abs (&refund_deadline);
+  cls->order.id = "test_orders_od_1";
+  cls->order.pay_deadline = pay_deadline;
+  cls->order.contract = json_object ();
+  json_object_set (cls->order.contract,
+                   "fulfillment_url",
+                   json_string ("a"));
+  json_object_set (cls->order.contract,
+                   "pay_deadline",
+                   GNUNET_JSON_from_time_abs (pay_deadline));
+  json_object_set (cls->order.contract,
+                   "refund_deadline",
+                   GNUNET_JSON_from_time_abs (refund_deadline));
+
+  /* Deposit */
+  cls->deposits[0].timestamp = GNUNET_TIME_absolute_get ();
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_JSON_hash (cls->order.contract,
+                                  &cls->deposits[0].h_contract_terms));
+  struct TALER_CoinSpendPrivateKeyP coin_priv;
+  GNUNET_CRYPTO_eddsa_key_create (&coin_priv.eddsa_priv);
+  GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv.eddsa_priv,
+                                      &cls->deposits[0].coin_pub.eddsa_pub);
+  cls->deposits[0].exchange_url = "test-exchange";
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:50.00",
+                                         &cls->deposits[0].amount_with_fee));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:1.00",
+                                         &cls->deposits[0].deposit_fee));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:1.50",
+                                         &cls->deposits[0].refund_fee));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:2.00",
+                                         &cls->deposits[0].wire_fee));
+  cls->deposits[0].h_wire = cls->account.h_wire;
+  struct TALER_DepositRequestPS deposit_sign;
+  deposit_sign.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
+  deposit_sign.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
+  deposit_sign.h_contract_terms = cls->deposits[0].h_contract_terms;
+  deposit_sign.h_wire = cls->deposits[0].h_wire;
+  deposit_sign.wallet_timestamp = GNUNET_TIME_absolute_hton (
+    GNUNET_TIME_absolute_get ());
+  deposit_sign.refund_deadline = GNUNET_TIME_absolute_hton (
+    GNUNET_TIME_absolute_get ());
+  TALER_amount_hton (&deposit_sign.amount_with_fee,
+                     &cls->deposits[0].amount_with_fee);
+  TALER_amount_hton (&deposit_sign.deposit_fee,
+                     &cls->deposits[0].deposit_fee);
+  deposit_sign.merchant = cls->merchant_pub;
+  deposit_sign.coin_pub = cls->deposits[0].coin_pub;
+  GNUNET_CRYPTO_eddsa_sign (&cls->exchange_priv.eddsa_priv,
+                            &deposit_sign,
+                            &cls->deposits[0].exchange_sig.eddsa_signature);
+}
+
+
+static void
+post_test_deposits (struct TestDeposits_Closure *cls)
+{
+  /* Instance */
+  json_decref (cls->is.address);
+  json_decref (cls->is.jurisdiction);
+
+  /* Order */
+  json_decref (cls->order.contract);
+}
+
+
+static int
+run_test_deposits (struct TestDeposits_Closure *cls)
+{
+  /* Insert the instance */
+  TEST_RET_ON_FAIL (test_insert_instance (&cls->merchant_pub,
+                                          &cls->merchant_priv,
+                                          &cls->is));
+
+  /* Insert an account */
+  TEST_RET_ON_FAIL (test_insert_account (cls->is.id,
+                                         &cls->account));
+
+  /* Insert a signing key */
+  if (1 != plugin->insert_exchange_signkey (plugin->cls,
+                                            &cls->master_pub,
+                                            &cls->exchange_pub,
+                                            cls->signkey_start,
+                                            cls->signkey_expire,
+                                            cls->signkey_end,
+                                            &cls->master_sig))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Insert signing key failed\n");
+    return 1;
+  }
+
+  /* Insert an order */
+  TEST_RET_ON_FAIL (test_insert_order (cls->is.id,
+                                       cls->order.id,
+                                       cls->order.pay_deadline,
+                                       cls->order.contract));
+
+  /* Insert contract terms */
+  if (1 != plugin->insert_contract_terms (plugin->cls,
+                                          cls->is.id,
+                                          cls->order.id,
+                                          cls->order.contract))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Insert contract terms failed\n");
+    return 1;
+  }
+
+  /* Test inserting a deposit */
+  TEST_RET_ON_FAIL (test_insert_deposit (cls->is.id,
+                                         &cls->exchange_pub,
+                                         &cls->deposits[0]));
+
+  /* Test lookup deposits */
+  TEST_RET_ON_FAIL (test_lookup_deposits (cls->is.id,
+                                          &cls->deposits[0].h_contract_terms,
+                                          1,
+                                          cls->deposits));
+
+  return 0;
+}
+
+
+static int
+test_deposits (void *cls)
+{
+  struct TestDeposits_Closure test_cls;
+  pre_test_deposits (&test_cls);
+  int test_result = run_test_deposits (&test_cls);
+  post_test_deposits (&test_cls);
+  return test_result;
+}
+
+
 /**
  * Function that runs all tests and returns 1 upon error, 0 on success.
  */
@@ -1170,6 +1645,7 @@ run_tests (void *cls)
   TEST_RET_ON_FAIL (test_instances (cls));
   TEST_RET_ON_FAIL (test_products (cls));
   TEST_RET_ON_FAIL (test_orders (cls));
+  TEST_RET_ON_FAIL (test_deposits (cls));
 
   return 0;
 }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

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