summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-04-04 16:47:11 +0200
committerChristian Grothoff <christian@grothoff.org>2016-04-04 16:47:11 +0200
commit0ff76b5abbf09aa273b7998f4d16bb0c0e4d90bb (patch)
tree285f10a9026d5af1d763ab6a28c2f1b0db734974 /src
parentbd6fb59e4ba0afd537563f356e6f1abf7b980666 (diff)
downloadexchange-0ff76b5abbf09aa273b7998f4d16bb0c0e4d90bb.tar.gz
exchange-0ff76b5abbf09aa273b7998f4d16bb0c0e4d90bb.tar.bz2
exchange-0ff76b5abbf09aa273b7998f4d16bb0c0e4d90bb.zip
fix test to ensure DB invariants are met
Diffstat (limited to 'src')
-rw-r--r--src/exchange/test_taler_exchange_aggregator.c134
-rw-r--r--src/include/taler_amount_lib.h13
-rw-r--r--src/util/amount.c24
3 files changed, 170 insertions, 1 deletions
diff --git a/src/exchange/test_taler_exchange_aggregator.c b/src/exchange/test_taler_exchange_aggregator.c
index b27c10d1f..22bc8e277 100644
--- a/src/exchange/test_taler_exchange_aggregator.c
+++ b/src/exchange/test_taler_exchange_aggregator.c
@@ -290,6 +290,16 @@ static struct Transaction *transactions_head;
*/
static struct Transaction *transactions_tail;
+/**
+ * Private key we use for fake coins.
+ */
+static struct GNUNET_CRYPTO_RsaPrivateKey *coin_pk;
+
+/**
+ * Public key we use for fake coins.
+ */
+static struct GNUNET_CRYPTO_RsaPublicKey *coin_pub;
+
/**
* Interprets the commands from the test program.
@@ -383,6 +393,47 @@ maint_child_death (void *cls,
}
+/**
+ * Setup (fake) information about a coin used in deposit.
+ *
+ * @param[out] issue information to initialize with "valid" data
+ */
+static void
+fake_issue (struct TALER_EXCHANGEDB_DenominationKeyInformationP *issue)
+{
+ memset (issue, 0, sizeof (struct TALER_EXCHANGEDB_DenominationKeyInformationP));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount_nbo ("EUR:1",
+ &issue->properties.value));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount_nbo ("EUR:0.1",
+ &issue->properties.fee_withdraw));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount_nbo ("EUR:0.1",
+ &issue->properties.fee_deposit));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount_nbo ("EUR:0.1",
+ &issue->properties.fee_refresh));
+}
+
+
+/**
+ * Setup (fake) information about a coin used in deposit.
+ *
+ * @param[out] coin information to initialize with "valid" data
+ */
+static void
+fake_coin (struct TALER_CoinPublicInfo *coin)
+{
+ struct GNUNET_HashCode hc;
+
+ coin->denom_pub.rsa_public_key = coin_pub;
+ GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
+ &hc);
+ coin->denom_sig.rsa_signature = GNUNET_CRYPTO_rsa_sign_fdh (coin_pk,
+ &hc);
+}
+
/**
* Helper function to fake a deposit operation.
@@ -423,6 +474,7 @@ do_deposit (struct Command *cmd)
GNUNET_break (0);
return GNUNET_SYSERR;
}
+ fake_coin (&deposit.coin);
/* Build JSON for wire details;
note that this simple method may fail in the future if we implement
and enforce signature checking on test-wire account details */
@@ -451,6 +503,7 @@ do_deposit (struct Command *cmd)
ret = GNUNET_SYSERR;
else
ret = GNUNET_OK;
+ GNUNET_CRYPTO_rsa_signature_free (deposit.coin.denom_sig.rsa_signature);
json_decref (deposit.wire);
return ret;
}
@@ -590,7 +643,7 @@ static void
run_test ()
{
static struct Command commands[] = {
- /* FIXME: prime DB */
+ /* test running with empty DB */
{
.opcode = OPCODE_RUN_AGGREGATOR,
.label = "run-aggregator-on-empty-db"
@@ -599,6 +652,57 @@ run_test ()
.opcode = OPCODE_EXPECT_TRANSACTIONS_EMPTY,
.label = "expect-empty-transactions-on-start"
},
+ /* test simple deposit */
+ {
+ .opcode = OPCODE_DATABASE_DEPOSIT,
+ .label = "do-deposit-",
+ .details.deposit.merchant_name = "bob",
+ .details.deposit.merchant_account = 4,
+ .details.deposit.transaction_id = 1,
+ .details.deposit.wire_deadline = { 1000LL * 1000 * 0 }, /* 5s */
+ .details.deposit.amount_with_fee = "EUR:1",
+ .details.deposit.deposit_fee = "EUR:0"
+ },
+ {
+ .opcode = OPCODE_RUN_AGGREGATOR,
+ .label = "run-aggregator-deposit-1"
+ },
+
+ /* The above step is already known to fail (with an error message)
+ right now, so we skip the rest of the test. */
+ {
+ .opcode = OPCODE_TERMINATE_SKIP,
+ .label = "testcase-incomplete-terminating-with-skip"
+ },
+
+
+ {
+ .opcode = OPCODE_EXPECT_TRANSACTION,
+ .label = "expect-deposit-1",
+ .details.expect_transaction.debit_account = 1,
+ .details.expect_transaction.credit_account = 4,
+ .details.expect_transaction.amount = "EUR:1"
+ },
+ {
+ .opcode = OPCODE_EXPECT_TRANSACTIONS_EMPTY,
+ .label = "expect-empty-transactions-on-start"
+ },
+ /* test idempotency: run again on transactions already done */
+ {
+ .opcode = OPCODE_DATABASE_DEPOSIT,
+ .label = "do-deposit-",
+ .details.deposit.merchant_name = "bob",
+ .details.deposit.merchant_account = 4,
+ .details.deposit.transaction_id = 1,
+ .details.deposit.wire_deadline = { 1000LL * 1000 * 0 }, /* 5s */
+ .details.deposit.amount_with_fee = "EUR:1",
+ .details.deposit.deposit_fee = "EUR:0"
+ },
+ {
+ .opcode = OPCODE_EXPECT_TRANSACTIONS_EMPTY,
+ .label = "expect-empty-transactions-on-start"
+ },
+
{
.opcode = OPCODE_TERMINATE_SKIP,
.label = "testcase-incomplete-terminating-with-skip"
@@ -851,19 +955,43 @@ run (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_CONFIGURATION_Handle *cfg = cls;
+ struct TALER_EXCHANGEDB_DenominationKeyInformationP issue;
+ struct TALER_DenominationPublicKey dpk;
plugin = TALER_EXCHANGEDB_plugin_load (cfg);
if (GNUNET_OK !=
plugin->create_tables (plugin->cls,
GNUNET_YES))
{
+ GNUNET_break (0);
TALER_EXCHANGEDB_plugin_unload (plugin);
+ plugin = NULL;
result = 77;
return;
}
session = plugin->get_session (plugin->cls,
GNUNET_YES);
GNUNET_assert (NULL != session);
+ fake_issue (&issue);
+ dpk.rsa_public_key = coin_pub;
+ if ( (GNUNET_OK !=
+ plugin->start (plugin->cls,
+ session)) ||
+ (GNUNET_OK !=
+ plugin->insert_denomination_info (plugin->cls,
+ session,
+ &dpk,
+ &issue)) ||
+ (GNUNET_OK !=
+ plugin->commit (plugin->cls,
+ session)) )
+ {
+ GNUNET_break (0);
+ TALER_EXCHANGEDB_plugin_unload (plugin);
+ plugin = NULL;
+ result = 77;
+ return;
+ }
child_death_task =
GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
GNUNET_DISK_pipe_handle (sigpipe,
@@ -945,7 +1073,11 @@ main (int argc,
GNUNET_assert (NULL != sigpipe);
shc_chld =
GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death);
+ coin_pk = GNUNET_CRYPTO_rsa_private_key_create (1024);
+ coin_pub = GNUNET_CRYPTO_rsa_private_key_get_public (coin_pk);
GNUNET_SCHEDULER_run (&run, cfg);
+ GNUNET_CRYPTO_rsa_private_key_free (coin_pk);
+ GNUNET_CRYPTO_rsa_public_key_free (coin_pub);
GNUNET_SIGNAL_handler_uninstall (shc_chld);
shc_chld = NULL;
GNUNET_DISK_pipe_close (sigpipe);
diff --git a/src/include/taler_amount_lib.h b/src/include/taler_amount_lib.h
index 094b96f7f..2fd547196 100644
--- a/src/include/taler_amount_lib.h
+++ b/src/include/taler_amount_lib.h
@@ -128,6 +128,19 @@ TALER_string_to_amount (const char *str,
/**
+ * Parse denomination description, in the format "T:V.F".
+ *
+ * @param str denomination description
+ * @param denom denomination to write the result to, in NBO
+ * @return #GNUNET_OK if the string is a valid denomination specification,
+ * #GNUNET_SYSERR if it is invalid.
+ */
+int
+TALER_string_to_amount_nbo (const char *str,
+ struct TALER_AmountNBO *denom);
+
+
+/**
* Get the value of "zero" in a particular currency.
*
* @param cur currency description
diff --git a/src/util/amount.c b/src/util/amount.c
index dc2d2e400..4ac7d30ab 100644
--- a/src/util/amount.c
+++ b/src/util/amount.c
@@ -151,6 +151,30 @@ TALER_string_to_amount (const char *str,
/**
+ * Parse denomination description, in the format "T:V.F".
+ *
+ * @param str denomination description
+ * @param denom denomination to write the result to, in NBO
+ * @return #GNUNET_OK if the string is a valid denomination specification,
+ * #GNUNET_SYSERR if it is invalid.
+ */
+int
+TALER_string_to_amount_nbo (const char *str,
+ struct TALER_AmountNBO *denom)
+{
+ struct TALER_Amount amount;
+
+ if (GNUNET_OK !=
+ TALER_string_to_amount (str,
+ &amount))
+ return GNUNET_SYSERR;
+ TALER_amount_hton (denom,
+ &amount);
+ return GNUNET_OK;
+}
+
+
+/**
* Convert amount from host to network representation.
*
* @param res where to store amount in network representation