extending test driver interpreter with commands to exercise aggregation API (not yet actually executed)

This commit is contained in:
Christian Grothoff 2016-01-22 15:29:31 +01:00
parent 46a10b12b8
commit dbfb2f7163

View File

@ -111,7 +111,17 @@ enum OpCode
/**
* Verify the mint's /wire-method.
*/
OC_WIRE
OC_WIRE,
/**
* Verify mint's /wire/deposits method.
*/
OC_WIRE_DEPOSITS,
/**
* Verify mint's /deposit/wtid method.
*/
OC_DEPOSIT_WTID
};
@ -470,6 +480,60 @@ struct Command
} wire;
/**
* Information for the /wire/deposits's command.
*/
struct {
/**
* Handle to the wire deposits request.
*/
struct TALER_MINT_WireDepositsHandle *wdh;
/**
* Reference to a /deposit/wtid command. If set, we use the
* WTID from that command.
*/
const char *wtid_ref;
/**
* WTID to use (used if @e wtid_ref is NULL).
*/
struct TALER_WireTransferIdentifierRawP wtid;
/* TODO: may want to add list of deposits we expected
to see aggregated here in the future. */
} wire_deposits;
/**
* Information for the /deposit/wtid command.
*/
struct {
/**
* Handle to the deposit wtid request.
*/
struct TALER_MINT_DepositWtidHandle *dwh;
/**
* Which /deposit operation should we obtain WTID data for?
*/
const char *deposit_ref;
/**
* What is the expected total amount? Only used if
* @e expected_response_code was #MHD_HTTP_OK.
*/
struct TALER_Amount total_amount_expected;
/**
* Wire transfer identifier, set if #MHD_HTTP_OK was the response code.
*/
struct TALER_WireTransferIdentifierRawP wtid;
} deposit_wtid;
} details;
};
@ -1219,6 +1283,156 @@ wire_cb (void *cls,
}
/**
* Function called with detailed wire transfer data, including all
* of the coin transactions that were combined into the wire transfer.
*
* @param cls closure
* @param http_status HTTP status code we got, 0 on mint protocol violation
* @param json original json reply (may include signatures, those have then been
* validated already)
* @param wtid extracted wire transfer identifier, or NULL if the mint could
* not provide any (set only if @a http_status is #MHD_HTTP_OK)
* @param total_amount total amount of the wire transfer, or NULL if the mint could
* not provide any @a wtid (set only if @a http_status is #MHD_HTTP_OK)
* @param details_length length of the @a details array
* @param details array with details about the combined transactions
*/
static void
wire_deposits_cb (void *cls,
unsigned int http_status,
json_t *json,
const struct GNUNET_HashCode *h_wire,
const struct TALER_Amount *total_amount,
unsigned int details_length,
const struct TALER_WireDepositDetails *details)
{
struct InterpreterState *is = cls;
struct Command *cmd = &is->commands[is->ip];
const struct Command *ref;
ref = find_command (is,
cmd->details.wire_deposits.wtid_ref);
if (cmd->expected_response_code != http_status)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u to command %s\n",
http_status,
cmd->label);
json_dumpf (json, stderr, 0);
fail (is);
return;
}
switch (http_status)
{
case MHD_HTTP_OK:
if (0 != TALER_amount_cmp (total_amount,
&ref->details.deposit_wtid.total_amount_expected))
{
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)
{
const struct Command *dep;
struct GNUNET_HashCode hw;
dep = find_command (is,
ref->details.deposit_wtid.deposit_ref);
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)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Wire hash missmatch to command %s\n",
cmd->label);
json_dumpf (json, stderr, 0);
fail (is);
return;
}
}
break;
default:
break;
}
/* move to next command */
is->ip++;
is->task = GNUNET_SCHEDULER_add_now (&interpreter_run,
is);
}
/**
* Function called with detailed wire transfer data.
*
* @param cls closure
* @param http_status HTTP status code we got, 0 on mint protocol violation
* @param json original json reply (may include signatures, those have then been
* validated already)
* @param wtid wire transfer identifier used by the mint, NULL if mint did not
* yet execute the transaction
* @param execution_time actual or planned execution time for the wire transfer
* @param coin_contribution contribution to the @a total_amount of the deposited coin (may be NULL)
* @param total_amount total amount of the wire transfer, or NULL if the mint could
* not provide any @a wtid (set only if @a http_status is #MHD_HTTP_OK)
*/
static void
deposit_wtid_cb (void *cls,
unsigned int http_status,
json_t *json,
const struct TALER_WireTransferIdentifierRawP *wtid,
struct GNUNET_TIME_Absolute execution_time,
const struct TALER_Amount *coin_contribution,
const struct TALER_Amount *total_amount)
{
struct InterpreterState *is = cls;
struct Command *cmd = &is->commands[is->ip];
if (cmd->expected_response_code != http_status)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u to command %s\n",
http_status,
cmd->label);
json_dumpf (json, stderr, 0);
fail (is);
return;
}
switch (http_status)
{
case MHD_HTTP_OK:
cmd->details.deposit_wtid.wtid = *wtid;
if (0 != TALER_amount_cmp (total_amount,
&cmd->details.deposit_wtid.total_amount_expected))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Total amount missmatch to command %s\n",
cmd->label);
json_dumpf (json, stderr, 0);
fail (is);
return;
}
break;
default:
break;
}
/* move to next command */
is->ip++;
is->task = GNUNET_SCHEDULER_add_now (&interpreter_run,
is);
}
/**
* Run the main interpreter loop that performs mint operations.
*
@ -1686,6 +1900,85 @@ interpreter_run (void *cls,
is);
trigger_context_task ();
return;
case OC_WIRE_DEPOSITS:
if (NULL != cmd->details.wire_deposits.wtid_ref)
{
ref = find_command (is,
cmd->details.wire_deposits.wtid_ref);
GNUNET_assert (NULL != ref);
cmd->details.wire_deposits.wtid = ref->details.deposit_wtid.wtid;
}
cmd->details.wire_deposits.wdh
= TALER_MINT_wire_deposits (mint,
&cmd->details.wire_deposits.wtid,
&wire_deposits_cb,
is);
trigger_context_task ();
return;
case OC_DEPOSIT_WTID:
{
struct GNUNET_HashCode h_wire;
struct GNUNET_HashCode h_contract;
json_t *wire;
json_t *contract;
const struct Command *coin;
struct TALER_CoinSpendPublicKeyP coin_pub;
ref = find_command (is,
cmd->details.deposit_wtid.deposit_ref);
GNUNET_assert (NULL != ref);
coin = find_command (is,
ref->details.deposit.coin_ref);
GNUNET_assert (NULL != coin);
switch (coin->oc)
{
case OC_WITHDRAW_SIGN:
GNUNET_CRYPTO_eddsa_key_get_public (&coin->details.reserve_withdraw.coin_priv.eddsa_priv,
&coin_pub.eddsa_pub);
break;
case OC_REFRESH_REVEAL:
{
const struct FreshCoin *fc;
unsigned int idx;
idx = ref->details.deposit.coin_idx;
GNUNET_assert (idx < coin->details.refresh_reveal.num_fresh_coins);
fc = &coin->details.refresh_reveal.fresh_coins[idx];
GNUNET_CRYPTO_eddsa_key_get_public (&fc->coin_priv.eddsa_priv,
&coin_pub.eddsa_pub);
}
break;
default:
GNUNET_assert (0);
}
wire = json_loads (ref->details.deposit.wire_details,
JSON_REJECT_DUPLICATES,
NULL);
GNUNET_assert (NULL != wire);
TALER_hash_json (wire,
&h_wire);
json_decref (wire);
contract = json_loads (ref->details.deposit.contract,
JSON_REJECT_DUPLICATES,
NULL);
GNUNET_assert (NULL != contract);
TALER_hash_json (contract,
&h_contract);
json_decref (contract);
cmd->details.deposit_wtid.dwh
= TALER_MINT_deposit_wtid (mint,
&ref->details.deposit.merchant_priv,
&h_wire,
&h_contract,
&coin_pub,
ref->details.deposit.transaction_id,
&deposit_wtid_cb,
is);
trigger_context_task ();
}
return;
default:
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unknown instruction %d at %u (%s)\n",
@ -1831,6 +2124,20 @@ do_shutdown (void *cls,
cmd->details.wire.wh = NULL;
}
break;
case OC_WIRE_DEPOSITS:
if (NULL != cmd->details.wire_deposits.wdh)
{
TALER_MINT_wire_deposits_cancel (cmd->details.wire_deposits.wdh);
cmd->details.wire_deposits.wdh = NULL;
}
break;
case OC_DEPOSIT_WTID:
if (NULL != cmd->details.deposit_wtid.dwh)
{
TALER_MINT_deposit_wtid_cancel (cmd->details.deposit_wtid.dwh);
cmd->details.deposit_wtid.dwh = NULL;
}
break;
default:
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unknown instruction %d at %u (%s)\n",