aboutsummaryrefslogtreecommitdiff
path: root/src/exchange-lib/test_exchange_api.c
diff options
context:
space:
mode:
authorJeff Burdges <burdges@gnunet.org>2016-05-04 23:30:36 +0200
committerJeff Burdges <burdges@gnunet.org>2016-05-04 23:30:36 +0200
commit48863ce93578ea656fe5342f0f4da1bd2bab8139 (patch)
treeed896b67c4464d406c0bd9235123e404ae7bf8cd /src/exchange-lib/test_exchange_api.c
parent4141467d47a276365cbb9629b66c84b2c4e74dd4 (diff)
parentad6a40aaa580551b2861d51740a427af05d9f165 (diff)
Merge branch 'master' of git.taler.net:/var/git/exchange
Diffstat (limited to 'src/exchange-lib/test_exchange_api.c')
-rw-r--r--src/exchange-lib/test_exchange_api.c273
1 files changed, 226 insertions, 47 deletions
diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c
index b20f7706..49c124c8 100644
--- a/src/exchange-lib/test_exchange_api.c
+++ b/src/exchange-lib/test_exchange_api.c
@@ -139,12 +139,12 @@ enum OpCode
/**
* Check that the fakebank has received a certain transaction.
*/
- OC_CHECK_BANK_DEPOSIT,
+ OC_CHECK_BANK_TRANSFER,
/**
* Check that the fakebank has not received any other transactions.
*/
- OC_CHECK_BANK_DEPOSITS_EMPTY
+ OC_CHECK_BANK_TRANSFERS_EMPTY
};
@@ -514,8 +514,13 @@ struct Command
struct TALER_EXCHANGE_WireDepositsHandle *wdh;
/**
- * Reference to a /deposit/wtid command. If set, we use the
- * WTID from that command.
+ * Reference to a command providing a WTID. If set, we use the
+ * WTID from that command. The command can be either an
+ * #OC_DEPOSIT_WTID or an #OC_CHECK_BANK_TRANSFER. In the
+ * case of the bank transfer, we check that the total amount
+ * claimed by the exchange matches the total amount transferred
+ * by the bank. In the case of a /deposit/wtid, we check
+ * that the wire details match.
*/
const char *wtid_ref;
@@ -524,6 +529,13 @@ struct Command
*/
struct TALER_WireTransferIdentifierRawP wtid;
+ /**
+ * What is the expected total amount? Only used if
+ * @e expected_response_code was #MHD_HTTP_OK.
+ */
+ const char *total_amount_expected;
+
+
/* TODO: may want to add list of deposits we expected
to see aggregated here in the future. */
@@ -545,10 +557,9 @@ struct Command
const char *deposit_ref;
/**
- * What is the expected total amount? Only used if
- * @e expected_response_code was #MHD_HTTP_OK.
+ * Which #OC_CHECK_BANK_TRANSFER wtid should this match? NULL for none.
*/
- struct TALER_Amount total_amount_expected;
+ const char *bank_transfer_ref;
/**
* Wire transfer identifier, set if #MHD_HTTP_OK was the response code.
@@ -588,7 +599,7 @@ struct Command
*/
struct TALER_WireTransferIdentifierRawP wtid;
- } check_bank_deposit;
+ } check_bank_transfer;
} details;
@@ -625,6 +636,18 @@ struct InterpreterState
/**
+ * Pipe used to communicate child death via signal.
+ */
+static struct GNUNET_DISK_PipeHandle *sigpipe;
+
+/**
+ * ID of task called whenever we get a SIGCHILD.
+ */
+static struct GNUNET_SCHEDULER_Task *child_death_task;
+
+
+
+/**
* The testcase failed, return with an error code.
*
* @param is interpreter state to clean up
@@ -1185,6 +1208,30 @@ link_cb (void *cls,
/**
+ * Task triggered whenever we receive a SIGCHLD (child
+ * process died).
+ *
+ * @param cls closure, NULL if we need to self-restart
+ */
+static void
+maint_child_death (void *cls)
+{
+ struct InterpreterState *is = cls;
+ struct Command *cmd = &is->commands[is->ip];
+ const struct GNUNET_DISK_FileHandle *pr;
+ char c[16];
+
+ child_death_task = NULL;
+ pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ);
+ GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c)));
+ GNUNET_OS_process_wait (cmd->details.run_aggregator.aggregator_proc);
+ GNUNET_OS_process_destroy (cmd->details.run_aggregator.aggregator_proc);
+ cmd->details.run_aggregator.aggregator_proc = NULL;
+ next_command (is);
+}
+
+
+/**
* Find denomination key matching the given amount.
*
* @param keys array of keys to search
@@ -1223,9 +1270,9 @@ find_pk (const struct TALER_EXCHANGE_Keys *keys,
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Have denomination key for `%s', but with wrong expiration range %llu vs [%llu,%llu)\n",
str,
- now.abs_value_us,
- pk->valid_from.abs_value_us,
- pk->withdraw_valid_until.abs_value_us);
+ (unsigned long long) now.abs_value_us,
+ (unsigned long long) pk->valid_from.abs_value_us,
+ (unsigned long long) pk->withdraw_valid_until.abs_value_us);
GNUNET_free (str);
return NULL;
}
@@ -1321,6 +1368,7 @@ wire_deposits_cb (void *cls,
struct InterpreterState *is = cls;
struct Command *cmd = &is->commands[is->ip];
const struct Command *ref;
+ struct TALER_Amount expected_amount;
cmd->details.wire_deposits.wdh = NULL;
if (cmd->expected_response_code != http_status)
@@ -1336,42 +1384,82 @@ wire_deposits_cb (void *cls,
switch (http_status)
{
case MHD_HTTP_OK:
- ref = find_command (is,
- cmd->details.wire_deposits.wtid_ref);
- GNUNET_assert (NULL != ref);
+ if (GNUNET_OK !=
+ TALER_string_to_amount (cmd->details.wire_deposits.total_amount_expected,
+ &expected_amount))
+ {
+ GNUNET_break (0);
+ fail (is);
+ return;
+ }
if (0 != TALER_amount_cmp (total_amount,
- &ref->details.deposit_wtid.total_amount_expected))
+ &expected_amount))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Total amount missmatch to command %s\n",
- http_status,
cmd->label);
json_dumpf (json, stderr, 0);
fail (is);
return;
}
- if (NULL != ref->details.deposit_wtid.deposit_ref)
+ ref = find_command (is,
+ cmd->details.wire_deposits.wtid_ref);
+ GNUNET_assert (NULL != ref);
+ switch (ref->oc)
{
- const struct Command *dep;
- struct GNUNET_HashCode hw;
-
- dep = find_command (is,
- ref->details.deposit_wtid.deposit_ref);
- GNUNET_assert (NULL != dep);
- GNUNET_CRYPTO_hash (dep->details.deposit.wire_details,
- strlen (dep->details.deposit.wire_details),
- &hw);
- if (0 != memcmp (&hw,
- h_wire,
- sizeof (struct GNUNET_HashCode)))
+ case OC_DEPOSIT_WTID:
+ if (NULL != ref->details.deposit_wtid.deposit_ref)
+ {
+ const struct Command *dep;
+ struct GNUNET_HashCode hw;
+ json_t *wire;
+
+ dep = find_command (is,
+ ref->details.deposit_wtid.deposit_ref);
+ GNUNET_assert (NULL != dep);
+ wire = json_loads (dep->details.deposit.wire_details,
+ JSON_REJECT_DUPLICATES,
+ NULL);
+ TALER_JSON_hash (wire,
+ &hw);
+ json_decref (wire);
+ if (0 != memcmp (&hw,
+ h_wire,
+ sizeof (struct GNUNET_HashCode)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Wire hash missmatch to command %s\n",
+ cmd->label);
+ json_dumpf (json, stderr, 0);
+ fail (is);
+ return;
+ }
+ }
+ break;
+ case OC_CHECK_BANK_TRANSFER:
+ if (GNUNET_OK !=
+ TALER_string_to_amount (ref->details.check_bank_transfer.amount,
+ &expected_amount))
+ {
+ GNUNET_break (0);
+ fail (is);
+ return;
+ }
+ if (0 != TALER_amount_cmp (total_amount,
+ &expected_amount))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Wire hash missmatch to command %s\n",
+ "Total amount missmatch to command %s\n",
cmd->label);
json_dumpf (json, stderr, 0);
fail (is);
return;
}
+ break;
+ default:
+ GNUNET_break (0);
+ fail (is);
+ return;
}
break;
default:
@@ -1421,6 +1509,22 @@ deposit_wtid_cb (void *cls,
{
case MHD_HTTP_OK:
cmd->details.deposit_wtid.wtid = *wtid;
+ if (NULL != cmd->details.deposit_wtid.bank_transfer_ref)
+ {
+ const struct Command *ref;
+
+ ref = find_command (is,
+ cmd->details.deposit_wtid.bank_transfer_ref);
+ GNUNET_assert (NULL != ref);
+ if (0 != memcmp (wtid,
+ &ref->details.check_bank_transfer.wtid,
+ sizeof (struct TALER_WireTransferIdentifierRawP)))
+ {
+ GNUNET_break (0);
+ fail (is);
+ return;
+ }
+ }
break;
default:
break;
@@ -1698,7 +1802,7 @@ interpreter_run (void *cls)
GNUNET_CRYPTO_eddsa_key_get_public (&cmd->details.deposit.merchant_priv.eddsa_priv,
&merchant_pub.eddsa_pub);
- wire_deadline = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_DAYS);
+ wire_deadline = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_ZERO);
timestamp = GNUNET_TIME_absolute_get ();
GNUNET_TIME_round_abs (&timestamp);
{
@@ -1919,8 +2023,8 @@ interpreter_run (void *cls)
case OC_DEPOSIT_WTID:
cmd->details.wire_deposits.wtid = ref->details.deposit_wtid.wtid;
break;
- case OC_CHECK_BANK_DEPOSIT:
- cmd->details.wire_deposits.wtid = ref->details.check_bank_deposit.wtid;
+ case OC_CHECK_BANK_TRANSFER:
+ cmd->details.wire_deposits.wtid = ref->details.check_bank_transfer.wtid;
break;
default:
GNUNET_break (0);
@@ -1999,6 +2103,8 @@ interpreter_run (void *cls)
return;
case OC_RUN_AGGREGATOR:
{
+ const struct GNUNET_DISK_FileHandle *pr;
+
cmd->details.run_aggregator.aggregator_proc
= GNUNET_OS_start_process (GNUNET_NO,
GNUNET_OS_INHERIT_STD_ALL,
@@ -2014,16 +2120,16 @@ interpreter_run (void *cls)
fail (is);
return;
}
- GNUNET_OS_process_wait (cmd->details.run_aggregator.aggregator_proc);
- GNUNET_OS_process_destroy (cmd->details.run_aggregator.aggregator_proc);
- cmd->details.run_aggregator.aggregator_proc = NULL;
- next_command (is);
+ pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ);
+ child_death_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+ pr,
+ &maint_child_death, is);
return;
}
- case OC_CHECK_BANK_DEPOSIT:
+ case OC_CHECK_BANK_TRANSFER:
{
if (GNUNET_OK !=
- TALER_string_to_amount (cmd->details.check_bank_deposit.amount,
+ TALER_string_to_amount (cmd->details.check_bank_transfer.amount,
&amount))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -2036,9 +2142,9 @@ interpreter_run (void *cls)
if (GNUNET_OK !=
FAKEBANK_check (fakebank,
&amount,
- cmd->details.check_bank_deposit.account_debit,
- cmd->details.check_bank_deposit.account_credit,
- &cmd->details.check_bank_deposit.wtid))
+ cmd->details.check_bank_transfer.account_debit,
+ cmd->details.check_bank_transfer.account_credit,
+ &cmd->details.check_bank_transfer.wtid))
{
GNUNET_break (0);
fail (is);
@@ -2047,7 +2153,7 @@ interpreter_run (void *cls)
next_command (is);
return;
}
- case OC_CHECK_BANK_DEPOSITS_EMPTY:
+ case OC_CHECK_BANK_TRANSFERS_EMPTY:
{
if (GNUNET_OK !=
FAKEBANK_check_empty (fakebank))
@@ -2072,6 +2178,24 @@ interpreter_run (void *cls)
/**
+ * Signal handler called for SIGCHLD. Triggers the
+ * respective handler by writing to the trigger pipe.
+ */
+static void
+sighandler_child_death ()
+{
+ static char c;
+ int old_errno = errno; /* back-up errno */
+
+ GNUNET_break (1 ==
+ GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle
+ (sigpipe, GNUNET_DISK_PIPE_END_WRITE),
+ &c, sizeof (c)));
+ errno = old_errno; /* restore errno */
+}
+
+
+/**
* Function run when the test terminates (good or bad) with timeout.
*
* @param cls NULL
@@ -2251,9 +2375,9 @@ do_shutdown (void *cls)
cmd->details.run_aggregator.aggregator_proc = NULL;
}
break;
- case OC_CHECK_BANK_DEPOSIT:
+ case OC_CHECK_BANK_TRANSFER:
break;
- case OC_CHECK_BANK_DEPOSITS_EMPTY:
+ case OC_CHECK_BANK_TRANSFERS_EMPTY:
break;
default:
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -2526,7 +2650,7 @@ run (void *cls)
.details.deposit.amount = "EUR:0.1",
.details.deposit.coin_ref = "refresh-reveal-1",
.details.deposit.coin_idx = 4,
- .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":42 }",
+ .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":43 }",
.details.deposit.contract = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":3 } ] }",
.details.deposit.transaction_id = 2 },
@@ -2563,12 +2687,59 @@ run (void *cls)
.label = "wire-deposit-failing",
.expected_response_code = MHD_HTTP_NOT_FOUND },
+ /* Run transfers. Note that _actual_ aggregation will NOT
+ happen here, as each deposit operation is run with a
+ fresh merchant public key! */
{ .oc = OC_RUN_AGGREGATOR,
.label = "run-aggregator" },
- { .oc = OC_CHECK_BANK_DEPOSITS_EMPTY,
+ { .oc = OC_CHECK_BANK_TRANSFER,
+ .label = "check_bank_transfer-499c",
+ .details.check_bank_transfer.amount = "EUR:4.99",
+ .details.check_bank_transfer.account_debit = 2,
+ .details.check_bank_transfer.account_credit = 42
+ },
+ { .oc = OC_CHECK_BANK_TRANSFER,
+ .label = "check_bank_transfer-99c1",
+ .details.check_bank_transfer.amount = "EUR:0.99",
+ .details.check_bank_transfer.account_debit = 2,
+ .details.check_bank_transfer.account_credit = 42
+ },
+ { .oc = OC_CHECK_BANK_TRANSFER,
+ .label = "check_bank_transfer-99c2",
+ .details.check_bank_transfer.amount = "EUR:0.99",
+ .details.check_bank_transfer.account_debit = 2,
+ .details.check_bank_transfer.account_credit = 42
+ },
+ { .oc = OC_CHECK_BANK_TRANSFER,
+ .label = "check_bank_transfer-9c",
+ .details.check_bank_transfer.amount = "EUR:0.09",
+ .details.check_bank_transfer.account_debit = 2,
+ .details.check_bank_transfer.account_credit = 43
+ },
+
+ { .oc = OC_CHECK_BANK_TRANSFERS_EMPTY,
.label = "check_bank_empty" },
+ { .oc = OC_DEPOSIT_WTID,
+ .label = "deposit-wtid-ok",
+ .expected_response_code = MHD_HTTP_OK,
+ .details.deposit_wtid.deposit_ref = "deposit-simple",
+ .details.deposit_wtid.bank_transfer_ref = "check_bank_transfer-499c" },
+
+ { .oc = OC_WIRE_DEPOSITS,
+ .label = "wire-deposits-sucess-bank",
+ .expected_response_code = MHD_HTTP_OK,
+ .details.wire_deposits.wtid_ref = "check_bank_transfer-99c1",
+ .details.wire_deposits.total_amount_expected = "EUR:0.99" },
+
+ { .oc = OC_WIRE_DEPOSITS,
+ .label = "wire-deposits-sucess-wtid",
+ .expected_response_code = MHD_HTTP_OK,
+ .details.wire_deposits.wtid_ref = "deposit-wtid-ok",
+ .details.wire_deposits.total_amount_expected = "EUR:4.99" },
+
+
/* TODO: trigger aggregation logic and then check the
cases where tracking succeeds! */
@@ -2613,6 +2784,7 @@ main (int argc,
{
struct GNUNET_OS_Process *proc;
struct GNUNET_OS_Process *exchanged;
+ struct GNUNET_SIGNAL_Context *shc_chld;
GNUNET_log_setup ("test-exchange-api",
"WARNING",
@@ -2646,7 +2818,14 @@ main (int argc,
while (0 != system ("wget -q -t 1 -T 1 http://127.0.0.1:8081/keys -o /dev/null -O /dev/null"));
fprintf (stderr, "\n");
result = GNUNET_SYSERR;
+ sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO);
+ GNUNET_assert (NULL != sigpipe);
+ shc_chld = GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD,
+ &sighandler_child_death);
GNUNET_SCHEDULER_run (&run, NULL);
+ GNUNET_SIGNAL_handler_uninstall (shc_chld);
+ shc_chld = NULL;
+ GNUNET_DISK_pipe_close (sigpipe);
GNUNET_OS_process_kill (exchanged,
SIGTERM);
GNUNET_OS_process_wait (exchanged);