diff options
Diffstat (limited to 'src/backenddb/test_merchantdb.c')
-rw-r--r-- | src/backenddb/test_merchantdb.c | 2079 |
1 files changed, 424 insertions, 1655 deletions
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c index 69a376aa..fbb662f8 100644 --- a/src/backenddb/test_merchantdb.c +++ b/src/backenddb/test_merchantdb.c @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2014-2021 Taler Systems SA + (C) 2014-2024 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -42,28 +42,28 @@ static struct TALER_MERCHANTDB_Plugin *plugin; * @param test 0 on success, non-zero on failure */ #define TEST_WITH_FAIL_CLAUSE(test, on_fail) \ - if ((test)) \ - { \ - GNUNET_break (0); \ - on_fail \ - } + if ((test)) \ + { \ + GNUNET_break (0); \ + on_fail \ + } #define TEST_COND_RET_ON_FAIL(cond, msg) \ - if (! (cond)) \ - { \ - GNUNET_break (0); \ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ - msg); \ - return 1; \ - } + if (! (cond)) \ + { \ + GNUNET_break (0); \ + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ + msg); \ + return 1; \ + } /** * @param __test 0 on success, non-zero on failure */ #define TEST_RET_ON_FAIL(__test) \ - TEST_WITH_FAIL_CLAUSE (__test, \ - return 1; \ - ) + TEST_WITH_FAIL_CLAUSE (__test, \ + return 1; \ + ) /* ********** Instances ********** */ @@ -117,15 +117,7 @@ make_instance (char *instance_id, GNUNET_assert (NULL != instance->instance.jurisdiction); GNUNET_assert (0 == json_array_append_new (instance->instance.jurisdiction, json_string ("Ohio"))); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:1200.40", - &instance->instance. - default_max_deposit_fee)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:1200.40", - &instance->instance. - default_max_wire_fee)); - instance->instance.default_wire_fee_amortization = 1; + instance->instance.use_stefan = true; instance->instance.default_wire_transfer_delay = GNUNET_TIME_relative_get_minute_ (); instance->instance.default_pay_delay = GNUNET_TIME_relative_get_second_ (); @@ -153,6 +145,9 @@ free_instance_data (struct InstanceData *instance) static void make_account (struct TALER_MERCHANTDB_AccountDetails *account) { + memset (account, + 0, + sizeof (*account)); GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, &account->h_wire.hash); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, @@ -232,15 +227,7 @@ check_instances_equal (const struct TALER_MERCHANTDB_InstanceSettings *a, b->address)) || (1 != json_equal (a->jurisdiction, b->jurisdiction)) || - (GNUNET_OK != TALER_amount_cmp_currency (&a->default_max_deposit_fee, - &b->default_max_deposit_fee)) || - (0 != TALER_amount_cmp (&a->default_max_deposit_fee, - &b->default_max_deposit_fee)) || - (GNUNET_OK != TALER_amount_cmp_currency (&a->default_max_wire_fee, - &b->default_max_wire_fee)) || - (0 != TALER_amount_cmp (&a->default_max_wire_fee, - &b->default_max_wire_fee)) || - (a->default_wire_fee_amortization != b->default_wire_fee_amortization) || + (a->use_stefan != b->use_stefan) || (a->default_wire_transfer_delay.rel_value_us != b->default_wire_transfer_delay.rel_value_us) || (a->default_pay_delay.rel_value_us != b->default_pay_delay.rel_value_us)) @@ -272,6 +259,19 @@ check_accounts_equal (const struct TALER_MERCHANTDB_AccountDetails *a, } +// FIXME: use this! +void +lookup_accounts_cb (void *cls, + const struct TALER_MERCHANTDB_AccountDetails *account) +{ + const struct TALER_MERCHANTDB_AccountDetails *want = cls; + + GNUNET_assert (0 == + check_accounts_equal (want, + account)); +} + + /** * Called after testing 'lookup_instances'. * @@ -280,50 +280,26 @@ check_accounts_equal (const struct TALER_MERCHANTDB_AccountDetails *a, * @param merchant_priv private key of the instance, NULL if not available * @param is general instance settings * @param ias instance authentication settings - * @param accounts_length length of the @a accounts array - * @param accounts list of accounts of the merchant */ static void lookup_instances_cb (void *cls, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantPrivateKeyP *merchant_priv, const struct TALER_MERCHANTDB_InstanceSettings *is, - const struct TALER_MERCHANTDB_InstanceAuthSettings *ias, - unsigned int accounts_length, - const struct TALER_MERCHANTDB_AccountDetails accounts[]) + const struct TALER_MERCHANTDB_InstanceAuthSettings *ias) { struct TestLookupInstances_Closure *cmp = cls; + if (NULL == cmp) return; cmp->results_length += 1; /* Look through the closure and test each instance for equality */ for (unsigned int i = 0; cmp->instances_to_cmp_length > i; ++i) { - int accounts_matching[accounts_length]; - bool accounts_match = true; if (0 != check_instances_equal (cmp->instances_to_cmp[i].instance, is)) continue; - if (accounts_length != cmp->instances_to_cmp[i].accounts_length) - continue; - /* Count matches between the accounts found and accounts in cls */ - for (unsigned int j = 0; accounts_length > j; ++j) - accounts_matching[j] = 0; - for (unsigned int j = 0; accounts_length > j; ++j) - { - for (unsigned int k = 0; accounts_length > k; ++k) - { - if (0 == check_accounts_equal (&cmp->instances_to_cmp[i].accounts[j], - &accounts[k])) - accounts_matching[j] += 1; - } - } - /* Each account from the lookup should match with one and only one from cls */ - for (unsigned int j = 0; accounts_length > j; ++j) - if (1 != accounts_matching[j]) - accounts_match = false; - if (true == accounts_match) - cmp->results_matching[i] += 1; + cmp->results_matching[i] += 1; } } @@ -385,7 +361,7 @@ test_lookup_instances (bool active_only, unsigned int instances_length, struct InstanceWithAccounts instances[]) { - unsigned int results_matching[instances_length]; + unsigned int results_matching[GNUNET_NZL (instances_length)]; struct TestLookupInstances_Closure cmp = { .instances_to_cmp_length = instances_length, .instances_to_cmp = instances, @@ -433,9 +409,9 @@ test_delete_instance_private_key (const struct InstanceData *instance, enum GNUNET_DB_QueryStatus expected_result) { TEST_COND_RET_ON_FAIL (expected_result == - plugin->delete_instance_private_key (plugin->cls, - instance->instance - .id), + plugin->delete_instance_private_key ( + plugin->cls, + instance->instance.id), "Delete instance private key failed\n"); return 0; } @@ -596,15 +572,7 @@ run_test_instances (struct TestInstances_Closure *cls) json_array_append_new (cls->instances[0].instance.jurisdiction, json_pack ("{s:s}", "vegetables", "bad")); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:0.04", - &cls->instances[0].instance. - default_max_deposit_fee)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:1.23", - &cls->instances[0].instance. - default_max_wire_fee)); - cls->instances[0].instance.default_wire_fee_amortization = 2; + cls->instances[0].instance.use_stefan = false; cls->instances[0].instance.default_wire_transfer_delay = GNUNET_TIME_UNIT_HOURS; cls->instances[0].instance.default_pay_delay = GNUNET_TIME_UNIT_MINUTES; @@ -819,7 +787,7 @@ check_products_equal (const struct TALER_MERCHANTDB_ProductDetails *a, !=, b->next_restock))) - return 1; + return 1; return 0; } @@ -938,13 +906,17 @@ struct TestLookupProducts_Closure * Function called after calling @e test_lookup_products * * @param cls a pointer to the lookup closure. + * @param product_serial DB row ID * @param product_id the identifier of the product found. */ static void lookup_products_cb (void *cls, + uint64_t product_serial, const char *product_id) { struct TestLookupProducts_Closure *cmp = cls; + + GNUNET_assert (product_serial > 0); if (NULL == cmp) return; cmp->results_length += 1; @@ -970,7 +942,7 @@ test_lookup_products (const struct InstanceData *instance, unsigned int products_length, const struct ProductData *products) { - unsigned int results_matching[products_length]; + unsigned int results_matching[GNUNET_NZL (products_length)]; struct TestLookupProducts_Closure cls = { .products_to_cmp_length = products_length, .products_to_cmp = products, @@ -980,6 +952,8 @@ test_lookup_products (const struct InstanceData *instance, memset (results_matching, 0, sizeof (unsigned int) * products_length); if (0 > plugin->lookup_products (plugin->cls, instance->instance.id, + 0, + 20, &lookup_products_cb, &cls)) { @@ -1162,7 +1136,8 @@ run_test_products (struct TestProducts_Closure *cls) stock_dec.product.total_stock = 40; TEST_RET_ON_FAIL (test_update_product (&cls->instance, &stock_dec, - GNUNET_DB_STATUS_SUCCESS_NO_RESULTS)); + GNUNET_DB_STATUS_SUCCESS_NO_RESULTS)) + ; } { struct ProductData lost_dec = cls->products[0]; @@ -1170,7 +1145,8 @@ run_test_products (struct TestProducts_Closure *cls) lost_dec.product.total_lost = 1; TEST_RET_ON_FAIL (test_update_product (&cls->instance, &lost_dec, - GNUNET_DB_STATUS_SUCCESS_NO_RESULTS)); + GNUNET_DB_STATUS_SUCCESS_NO_RESULTS)) + ; } TEST_RET_ON_FAIL (test_lookup_product (&cls->instance, &cls->products[0])); @@ -1360,10 +1336,13 @@ test_insert_order (const struct InstanceData *instance, plugin->insert_order (plugin->cls, instance->instance.id, order->id, + NULL, /* session_id */ &h_post, order->pay_deadline, &order->claim_token, - order->contract), + order->contract, + NULL, + 0), "Insert order failed\n"); return 0; } @@ -1493,7 +1472,7 @@ test_lookup_orders (const struct InstanceData *instance, unsigned int orders_length, const struct OrderData *orders) { - bool results_match[orders_length]; + bool results_match[GNUNET_NZL (orders_length)]; struct TestLookupOrders_Closure cls = { .orders_to_cmp_length = orders_length, .orders_to_cmp = orders, @@ -1694,7 +1673,6 @@ test_lookup_contract_terms (const struct InstanceData *instance, { json_t *contract = NULL; uint64_t order_serial; - bool paid; if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->lookup_contract_terms (plugin->cls, @@ -1702,7 +1680,6 @@ test_lookup_contract_terms (const struct InstanceData *instance, order->id, &contract, &order_serial, - &paid, NULL)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -1842,6 +1819,7 @@ test_lookup_order_by_fulfillment (const struct InstanceData *instance, instance->instance.id, fulfillment_url, session_id, + false, &order_id)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -1872,25 +1850,44 @@ test_lookup_order_by_fulfillment (const struct InstanceData *instance, * @return 0 on success, 1 otherwise. */ static int -test_lookup_payment_status (uint64_t order_id, +test_lookup_payment_status (const char *instance_id, + const char *order_id, const char *session_id, bool expected_paid, bool expected_wired) { bool paid; bool wired; + bool matches; + uint64_t os; + TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == - plugin->lookup_payment_status (plugin->cls, - order_id, - session_id, - &paid, - &wired), + plugin->lookup_contract_terms3 (plugin->cls, + instance_id, + order_id, + session_id, + NULL, + &os, + &paid, + &wired, + &matches, + NULL), "Lookup payment status failed\n"); - if ((expected_paid != paid) || - (expected_wired != wired)) + if ( (NULL != session_id) && (! matches) ) + { + paid = false; + wired = false; + } + if (expected_wired != wired) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup payment status failed: wired status is wrong\n"); + return 1; + } + if (expected_paid != paid) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup payment status failed\n"); + "Lookup payment status failed: paid status is wrong\n"); return 1; } return 0; @@ -2080,7 +2077,6 @@ run_test_orders (struct TestOrders_Closure *cls) { json_t *lookup_contract = NULL; uint64_t lookup_order_serial; - bool paid; if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != plugin->lookup_contract_terms (plugin->cls, @@ -2088,7 +2084,6 @@ run_test_orders (struct TestOrders_Closure *cls) cls->orders[1].id, &lookup_contract, &lookup_order_serial, - &paid, NULL)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -2127,21 +2122,11 @@ run_test_orders (struct TestOrders_Closure *cls) } } /* Test lookup payment status */ - TEST_RET_ON_FAIL (test_lookup_payment_status (serial, + TEST_RET_ON_FAIL (test_lookup_payment_status (cls->instance.instance.id, + cls->orders[0].id, NULL, false, false)); - { - bool paid; - bool wired; - TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == - plugin->lookup_payment_status (plugin->cls, - 256, - NULL, - &paid, - &wired), - "Lookup payment status failed\n"); - } /* Test lookup order status fails for nonexistent order */ { struct TALER_PrivateContractHashP h_contract_terms; @@ -2163,25 +2148,21 @@ run_test_orders (struct TestOrders_Closure *cls) TEST_RET_ON_FAIL (test_mark_contract_paid (&cls->instance, &cls->orders[0], GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); - TEST_RET_ON_FAIL (test_lookup_payment_status (serial, + TEST_RET_ON_FAIL (test_lookup_payment_status (cls->instance.instance.id, + cls->orders[0].id, NULL, true, false)); - TEST_RET_ON_FAIL (test_lookup_payment_status (serial, + TEST_RET_ON_FAIL (test_lookup_payment_status (cls->instance.instance.id, + cls->orders[0].id, "test_orders_session", true, false)); - { - bool paid; - bool wired; - TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == - plugin->lookup_payment_status (plugin->cls, - serial, - "bad_session", - &paid, - &wired), - "Lookup payment status failed\n"); - } + TEST_RET_ON_FAIL (test_lookup_payment_status (cls->instance.instance.id, + cls->orders[0].id, + "bad_session", + false, + false)); /* Test lookup order by fulfillment */ TEST_RET_ON_FAIL (test_lookup_order_by_fulfillment (&cls->instance, &cls->orders[0], @@ -2193,6 +2174,7 @@ run_test_orders (struct TestOrders_Closure *cls) cls->instance.instance.id, "fulfillment_url", "test_orders_session", + false, &order_id)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -2215,13 +2197,16 @@ run_test_orders (struct TestOrders_Closure *cls) cls->orders)); /* Test marking orders as wired */ TEST_RET_ON_FAIL (test_mark_order_wired (serial, - GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); - TEST_RET_ON_FAIL (test_lookup_payment_status (serial, + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)) + ; + TEST_RET_ON_FAIL (test_lookup_payment_status (cls->instance.instance.id, + cls->orders[0].id, NULL, true, true)); TEST_RET_ON_FAIL (test_mark_order_wired (1007, - GNUNET_DB_STATUS_SUCCESS_NO_RESULTS)); + GNUNET_DB_STATUS_SUCCESS_NO_RESULTS)) + ; /* If an order has been claimed and we aren't past the pay deadline, we can't delete it. */ TEST_RET_ON_FAIL (test_delete_order (&cls->instance, @@ -2386,6 +2371,11 @@ struct DepositData struct TALER_CoinSpendPublicKeyP coin_pub; /** + * Signature of the coin that has been deposited. + */ + struct TALER_CoinSpendSignatureP coin_sig; + + /** * URL of the exchange. */ const char *exchange_url; @@ -2424,39 +2414,6 @@ struct DepositData /** - * Private key for my_sign_cb(). - */ -static const struct TALER_ExchangePrivateKeyP *msc_exchange_priv; - -/** - * Function that signs the message in @a purpose with the - * exchange's signing key from #msc_exchange_priv. - * - * The @a purpose data is the beginning of the data of which the signature is - * to be created. The `size` field in @a purpose must correctly indicate the - * number of bytes of the data structure, including its header. * - * @param purpose the message to sign - * @param[out] pub set to the current public signing key of the exchange - * @param[out] sig signature over purpose using current signing key - * @return #TALER_EC_NONE on success - */ -static enum TALER_ErrorCode -my_sign_cb ( - const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, - struct TALER_ExchangePublicKeyP *pub, - struct TALER_ExchangeSignatureP *sig) -{ - GNUNET_assert (GNUNET_OK == - GNUNET_CRYPTO_eddsa_sign_ (&msc_exchange_priv->eddsa_priv, - purpose, - &sig->eddsa_signature)); - GNUNET_CRYPTO_eddsa_key_get_public (&msc_exchange_priv->eddsa_priv, - &pub->eddsa_pub); - return TALER_EC_NONE; -} - - -/** * Generates deposit data for an order. * * @param instance the instance to make the deposit to. @@ -2475,7 +2432,6 @@ make_deposit (const struct InstanceData *instance, struct TALER_CoinSpendPrivateKeyP coin_priv; struct GNUNET_TIME_Timestamp now; struct TALER_Amount amount_without_fee; - struct TALER_ExchangePublicKeyP exchange_pub; now = GNUNET_TIME_timestamp_get (); deposit->timestamp = now; @@ -2503,22 +2459,12 @@ make_deposit (const struct InstanceData *instance, &deposit->amount_with_fee, &deposit->deposit_fee)); deposit->h_wire = account->h_wire; - msc_exchange_priv = &signkey->exchange_priv; - GNUNET_assert (TALER_EC_NONE == - TALER_exchange_online_deposit_confirmation_sign ( - &my_sign_cb, - &deposit->h_contract_terms, - &deposit->h_wire, - NULL, - now, - now, - now, - &amount_without_fee, - &deposit->coin_pub, - &instance->merchant_pub, - &exchange_pub, - &deposit->exchange_sig)); - msc_exchange_priv = NULL; + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, + &deposit->exchange_sig, + sizeof (deposit->exchange_sig)); + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, + &deposit->coin_sig, + sizeof (deposit->coin_sig)); } @@ -2536,7 +2482,8 @@ test_insert_exchange_signkey (const struct ExchangeSignkeyData *signkey, TEST_COND_RET_ON_FAIL (expected_result == plugin->insert_exchange_signkey (plugin->cls, &signkey->master_pub, - &signkey->exchange_pub, + &signkey->exchange_pub + , signkey->start_date, signkey->expire_date, signkey->end_date, @@ -2561,21 +2508,39 @@ test_insert_deposit (const struct InstanceData *instance, const struct DepositData *deposit, enum GNUNET_DB_QueryStatus expected_result) { - TEST_COND_RET_ON_FAIL (expected_result == - plugin->insert_deposit (plugin->cls, - instance->instance.id, - 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, - &signkey->exchange_pub), - "Insert deposit failed\n"); + uint64_t row; + struct TALER_Amount awf; + + GNUNET_assert (0 <= + TALER_amount_subtract (&awf, + &deposit->amount_with_fee, + &deposit->deposit_fee)); + TEST_COND_RET_ON_FAIL ( + expected_result == + plugin->insert_deposit_confirmation (plugin->cls, + instance->instance.id, + deposit->timestamp, + &deposit->h_contract_terms, + deposit->exchange_url, + deposit->timestamp, + &awf, + &deposit->wire_fee, + &deposit->h_wire, + &deposit->exchange_sig, + &signkey->exchange_pub, + &row), + "Insert deposit confirmation failed\n"); + TEST_COND_RET_ON_FAIL ( + expected_result == + plugin->insert_deposit (plugin->cls, + 0, + row, + &deposit->coin_pub, + &deposit->coin_sig, + &deposit->amount_with_fee, + &deposit->deposit_fee, + &deposit->refund_fee), + "Insert deposit failed\n"); return 0; } @@ -2615,7 +2580,6 @@ struct TestLookupDeposits_Closure * @param amount_with_fee amount of the deposit with fees. * @param deposit_fee fee charged for the deposit. * @param refund_fee fee charged in case of a refund. - * @param wire_fee fee charged when the money is wired. */ static void lookup_deposits_cb (void *cls, @@ -2623,8 +2587,7 @@ lookup_deposits_cb (void *cls, 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) + const struct TALER_Amount *refund_fee) { struct TestLookupDeposits_Closure *cmp = cls; if (NULL == cmp) @@ -2652,14 +2615,7 @@ lookup_deposits_cb (void *cls, 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))) + refund_fee))) { cmp->results_matching[i] += 1; } @@ -2683,7 +2639,7 @@ test_lookup_deposits (const struct InstanceData *instance, unsigned int deposits_length, const struct DepositData *deposits) { - unsigned int results_matching[deposits_length]; + unsigned int results_matching[GNUNET_NZL (deposits_length)]; struct TestLookupDeposits_Closure cmp = { .deposits_to_cmp_length = deposits_length, .deposits_to_cmp = deposits, @@ -2855,8 +2811,8 @@ test_lookup_deposits_contract_and_coin ( * @param cls pointer to the test lookup closure. * @param deposit_serial row number of the deposit in the database. * @param exchange_url URL to the exchange - * @param amount_with_fee amount of the deposit with fees. * @param h_wire hash of the wire transfer details. + * @param deposit_timestamp when was the deposit made * @param amount_with_fee amount of the deposit with fees. * @param deposit_fee fee charged for the deposit. * @param coin_pub public key of the coin deposited. @@ -2866,11 +2822,13 @@ lookup_deposits_order_cb (void *cls, uint64_t deposit_serial, const char *exchange_url, const struct TALER_MerchantWireHashP *h_wire, + struct GNUNET_TIME_Timestamp deposit_timestamp, const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *deposit_fee, const struct TALER_CoinSpendPublicKeyP *coin_pub) { struct TestLookupDeposits_Closure *cmp = cls; + if (NULL == cmp) return; cmp->results_length += 1; @@ -2920,11 +2878,11 @@ test_lookup_deposits_by_order (uint64_t order_serial, memset (results_matching, 0, sizeof (unsigned int) * deposits_length); - if (deposits_length != plugin->lookup_deposits_by_order (plugin->cls, - order_serial, - & - lookup_deposits_order_cb, - &cmp)) + if (deposits_length != + plugin->lookup_deposits_by_order (plugin->cls, + order_serial, + &lookup_deposits_order_cb, + &cmp)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Lookup deposits by order failed\n"); @@ -2972,8 +2930,8 @@ struct LookupDepositSerial_Closure * @param cls pointer to the test lookup closure. * @param deposit_serial row number of the deposit in the database. * @param exchange_url URL to the exchange - * @param amount_with_fee amount of the deposit with fees. * @param h_wire hash of the wire transfer details. + * @param deposit_timestamp when was the deposit made. * @param amount_with_fee amount of the deposit with fees. * @param deposit_fee fee charged for the deposit. * @param coin_pub public key of the coin deposited. @@ -2983,11 +2941,14 @@ get_deposit_serial_cb (void *cls, uint64_t deposit_serial, const char *exchange_url, const struct TALER_MerchantWireHashP *h_wire, + struct GNUNET_TIME_Timestamp deposit_timestamp, const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *deposit_fee, const struct TALER_CoinSpendPublicKeyP *coin_pub) { struct LookupDepositSerial_Closure *lookup_cls = cls; + + (void) deposit_timestamp; if (NULL == lookup_cls) return; if ((0 == strcmp (lookup_cls->deposit->exchange_url, @@ -3364,9 +3325,11 @@ struct TransferData static void make_transfer (const struct ExchangeSignkeyData *signkey, unsigned int deposits_length, - const struct DepositData deposits[], + const struct DepositData deposits[static deposits_length], struct TransferData *transfer) { + struct TALER_TrackTransferDetails *details = NULL; + GNUNET_CRYPTO_seed_weak_random (585); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &transfer->wtid, @@ -3374,9 +3337,6 @@ make_transfer (const struct ExchangeSignkeyData *signkey, transfer->exchange_url = deposits[0].exchange_url; transfer->verified = false; transfer->confirmed = false; - - struct TALER_TrackTransferDetails *details = NULL; - transfer->data.details_length = 0; GNUNET_assert (GNUNET_OK == TALER_amount_set_zero (deposits[0].amount_with_fee.currency, @@ -3804,11 +3764,12 @@ test_lookup_transfer_details_by_order ( memset (results_matching, 0, sizeof (unsigned int) * transfers_length); - if (transfers_length != plugin->lookup_transfer_details_by_order (plugin->cls, - order_serial, - & - lookup_transfer_details_order_cb, - &cmp)) + if (transfers_length != + plugin->lookup_transfer_details_by_order ( + plugin->cls, + order_serial, + &lookup_transfer_details_order_cb, + &cmp)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Lookup transfer details by order failed\n"); @@ -4139,7 +4100,8 @@ test_insert_transfer_details ( TEST_COND_RET_ON_FAIL (expected_result == plugin->insert_transfer_details (plugin->cls, instance->instance.id, - transfer->exchange_url, + transfer->exchange_url + , account->payto_uri, &transfer->wtid, &transfer->data), @@ -4246,6 +4208,9 @@ pre_test_transfers (struct TestTransfers_Closure *cls) static void post_test_transfers (struct TestTransfers_Closure *cls) { + GNUNET_array_grow (cls->transfers->data.details, + cls->transfers->data.details_length, + 0); free_instance_data (&cls->instance); free_order_data (&cls->order); } @@ -4341,21 +4306,23 @@ run_test_transfers (struct TestTransfers_Closure *cls) &cls->account, &cls->transfers[0], GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); - TEST_RET_ON_FAIL (test_lookup_payment_status (order_serial, + TEST_RET_ON_FAIL (test_lookup_payment_status (cls->instance.instance.id, + cls->order.id, NULL, false, true)); TEST_RET_ON_FAIL (test_lookup_transfer (&cls->instance, &cls->transfers[0])); - TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == - plugin->set_transfer_status_to_verified (plugin->cls, - cls->deposit. - exchange_url, - &cls-> - transfers[0]. - wtid), - "Set transfer status to verified failed\n"); - cls->transfers[0].verified = true; + TEST_COND_RET_ON_FAIL ( + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == + plugin->set_transfer_status_to_confirmed ( + plugin->cls, + cls->instance.instance.id, + cls->deposit.exchange_url, + &cls->transfers[0].wtid, + &cls->deposit.amount_with_fee), + "Set transfer status to confirmed failed\n"); + cls->transfers[0].confirmed = true; TEST_RET_ON_FAIL (test_lookup_transfer (&cls->instance, &cls->transfers[0])); TEST_RET_ON_FAIL (test_lookup_transfer_summary (cls->deposit.exchange_url, @@ -4401,1285 +4368,6 @@ test_transfers (void) } -/* Reserves and tips */ - - -struct ReserveData -{ - /** - * The reserve public key - */ - struct TALER_ReservePublicKeyP reserve_pub; - - /** - * The reserve private key - */ - struct TALER_ReservePrivateKeyP reserve_priv; - - /** - * The reserve initial amount - */ - struct TALER_Amount initial_amount; - - /** - * The exchange url - */ - const char *exchange_url; - - /** - * The payto URI - */ - const char *payto_uri; - - /** - * The expiration date - */ - struct GNUNET_TIME_Timestamp expiration; -}; - - -/** - * Tests inserting a reserve into the database. - * @paper instance the instance the reserve is for. - * @param reserve the reserve to insert. - * @param expected_result the result we expect to receive from the db. - * - * @return 0 on success, 1 otherwise. - */ -static int -test_insert_reserve (const struct InstanceData *instance, - const struct ReserveData *reserve, - enum TALER_ErrorCode expected_result) -{ - TEST_COND_RET_ON_FAIL (expected_result == - plugin->insert_reserve (plugin->cls, - instance->instance.id, - &reserve->reserve_priv, - &reserve->reserve_pub, - reserve->exchange_url, - reserve->payto_uri, - &reserve->initial_amount, - reserve->expiration), - "Insert reserve failed\n"); - return 0; -} - - -/** - * Container for looking up reserves. - */ -struct TestLookupReserve_Closure -{ - /** - * The reserve we expect to find. - */ - const struct ReserveData *reserve_to_cmp; - - /** - * The length of @e tips. - */ - unsigned int tips_length; - - /** - * The tips that have been authorized from the reserve. - */ - const struct TALER_MERCHANTDB_TipDetails *tips; - - /** - * 1 if the result matches, 0 otherwise. - */ - int result_matches; -}; - - -/** - * Called after test_lookup_reserve. - * @param cls a pointer to TestLookupReserve_Closure. - * @param creation_time time when the reserve was setup - * @param expiration_time time when the reserve will be closed by the exchange - * @param merchant_initial_amount initial amount that the merchant claims to have filled the - * reserve with - * @param exchange_initial_amount initial amount that the exchange claims to have received - * @param picked_up_amount total of tips that were picked up from this reserve - * @param committed_amount total of tips that the merchant committed to, but that were not - * picked up yet - * @param active true if the reserve is still active (we have the private key) - * @param exchange_url base URL of the exchange hosting the reserve, NULL if not @a active - * @param payto_uri URI to use to fund the reserve, NULL if not @a active - * @param tips_length length of the @a tips array - * @param tips information about the tips created by this reserve - * - * @return 0 on success, 1 otherwise. - */ -static void -lookup_reserve_cb (void *cls, - struct GNUNET_TIME_Timestamp creation_time, - struct GNUNET_TIME_Timestamp expiration_time, - const struct TALER_Amount *merchant_initial_amount, - const struct TALER_Amount *exchange_initial_amount, - const struct TALER_Amount *picked_up_amount, - const struct TALER_Amount *committed_amount, - bool active, - const char *exchange_url, - const char *payto_uri, - unsigned int tips_length, - const struct TALER_MERCHANTDB_TipDetails *tips) -{ - struct TestLookupReserve_Closure *cmp = cls; - unsigned int tip_cmp_results[tips_length]; - - if (NULL == cmp) - return; - if (GNUNET_TIME_timestamp_cmp (cmp->reserve_to_cmp->expiration, - !=, - expiration_time) || - (GNUNET_OK != - TALER_amount_cmp_currency ( - &cmp->reserve_to_cmp->initial_amount, - merchant_initial_amount)) || - (0 != TALER_amount_cmp (&cmp->reserve_to_cmp->initial_amount, - merchant_initial_amount)) || - (cmp->tips_length != tips_length)) - { - cmp->result_matches = 1; - return; - } - if (0 != strcmp (exchange_url, - "https://exch-url/")) - { - GNUNET_break (0); - cmp->result_matches = 0; - return; - } - if (0 != strcmp (payto_uri, - "payto://other-uri")) - { - GNUNET_break (0); - cmp->result_matches = 0; - return; - } - memset (tip_cmp_results, - 0, - sizeof (tip_cmp_results)); - for (unsigned int i = 0; tips_length > i; ++i) - { - for (unsigned int j = 0; tips_length > j; ++j) - { - if ((GNUNET_OK == TALER_amount_cmp_currency (&cmp->tips[i].total_amount, - &tips[j].total_amount)) && - (0 == TALER_amount_cmp (&cmp->tips[i].total_amount, - &tips[j].total_amount)) && - (0 == strcmp (cmp->tips[i].reason, - tips[j].reason))) - { - tip_cmp_results[i] += 1; - } - } - } - for (unsigned int i = 0; tips_length > i; ++i) - { - if (1 != tip_cmp_results[i]) - { - cmp->result_matches = 1; - return; - } - } - cmp->result_matches = 0; -} - - -/** - * Tests looking up details of a reserve from the database. - * @param instance the instance to lookup the reserve from. - * @param reserve_pub the public key of the reserve we are looking for. - * @param reserve the data we expect to find. - * - * @return 0 on success, 1 otherwise. - */ -static int -test_lookup_reserve (const struct InstanceData *instance, - const struct TALER_ReservePublicKeyP *reserve_pub, - const struct ReserveData *reserve) -{ - struct TestLookupReserve_Closure cmp = { - .reserve_to_cmp = reserve, - .tips_length = 0, - .tips = NULL, - .result_matches = 0 - }; - if (1 != plugin->lookup_reserve (plugin->cls, - instance->instance.id, - reserve_pub, - false, - &lookup_reserve_cb, - &cmp)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup reserve failed\n"); - return 1; - } - if (0 != cmp.result_matches) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup reserve failed: result does not match\n"); - return 1; - } - return 0; -} - - -/** - * Container for looking up multiple reserves. - */ -struct TestLookupReserves_Closure -{ - /** - * The length of @e reserves_to_cmp. - */ - unsigned int reserves_to_cmp_length; - - /** - * The reserves we expect to find from the lookup. - */ - const struct ReserveData *reserves_to_cmp; - - /** - * The number of results matching each reserve we were looking for. - */ - unsigned int *results_matching; - - /** - * The total number of results found from the lookup. - */ - unsigned int results_length; -}; - - -/** - * Called after test_lookup_reserves. - * @param cls pointer to a TestLookupReserves_Closure. - * @param reserve_pub public key of the reserve - * @param creation_time time when the reserve was setup - * @param expiration_time time when the reserve will be closed by the exchange - * @param merchant_initial_amount initial amount that the merchant claims to have filled the - * reserve with - * @param exchange_initial_amount initial amount that the exchange claims to have received - * @param pickup_amount total of tips that were picked up from this reserve - * @param committed_amount total of tips that the merchant committed to, but that were not - * picked up yet - * @param active true if the reserve is still active (we have the private key) - */ -static void -lookup_reserves_cb (void *cls, - const struct TALER_ReservePublicKeyP *reserve_pub, - struct GNUNET_TIME_Timestamp creation_time, - struct GNUNET_TIME_Timestamp expiration_time, - const struct TALER_Amount *merchant_initial_amount, - const struct TALER_Amount *exchange_initial_amount, - const struct TALER_Amount *pickup_amount, - const struct TALER_Amount *committed_amount, - bool active) -{ - struct TestLookupReserves_Closure *cmp = cls; - if (NULL == cmp) - return; - for (unsigned int i = 0; cmp->reserves_to_cmp_length > i; ++i) - { - if ((0 == - GNUNET_memcmp (&cmp->reserves_to_cmp[i].reserve_pub, - reserve_pub)) && - (GNUNET_TIME_timestamp_cmp (cmp->reserves_to_cmp[i].expiration, - ==, - expiration_time)) && - (GNUNET_OK == - TALER_amount_cmp_currency ( - &cmp->reserves_to_cmp[i].initial_amount, - merchant_initial_amount)) && - (0 == TALER_amount_cmp (&cmp->reserves_to_cmp[i].initial_amount, - merchant_initial_amount))) - { - cmp->results_matching[i] += 1; - } - } - cmp->results_length += 1; -} - - -/** - * Test looking up reserves for an instance. - * @param instance the instance to get the reserves from. - * - * @return 0 on success, 1 otherwise. - */ -static int -test_lookup_reserves (const struct InstanceData *instance, - unsigned int reserves_length, - const struct ReserveData *reserves) -{ - unsigned int results_matching[reserves_length]; - struct TestLookupReserves_Closure cmp = { - .reserves_to_cmp_length = reserves_length, - .reserves_to_cmp = reserves, - .results_matching = results_matching, - .results_length = 0 - }; - memset (results_matching, 0, sizeof (unsigned int) * reserves_length); - if (1 != plugin->lookup_reserves (plugin->cls, - instance->instance.id, - GNUNET_TIME_UNIT_ZERO_TS, - TALER_EXCHANGE_YNA_ALL, - TALER_EXCHANGE_YNA_ALL, - &lookup_reserves_cb, - &cmp)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup reserves failed\n"); - return 1; - } - if (reserves_length != cmp.results_length) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup reserves failed: incorrect number of results (%d)\n", - cmp.results_length); - return 1; - } - for (unsigned int i = 0; reserves_length > i; ++i) - { - if (1 != cmp.results_matching[i]) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup reserves failed: mismatched data\n"); - return 1; - } - } - return 0; -} - - -/** - * Called after test_lookup_pending_reserves. - * @param cls pointer to a TestLookupReserves_Closure. - * @param instance_id the id of the instance the reserve belongs to. - * @param exchange_url url of the exchange for this reserve. - * @param reserve_pub public key of this reserve. - * @param expected_amount what the amount in the reserve is, according to the db. - */ -static void -lookup_pending_reserves_cb (void *cls, - const char *instance_id, - const char *exchange_url, - const struct TALER_ReservePublicKeyP *reserve_pub, - const struct TALER_Amount *expected_amount) -{ - struct TestLookupReserves_Closure *cmp = cls; - if (NULL == cmp) - return; - for (unsigned int i = 0; cmp->reserves_to_cmp_length > i; ++i) - { - if ((0 == GNUNET_memcmp (&cmp->reserves_to_cmp[i].reserve_pub, - reserve_pub)) && - (0 == strcmp (cmp->reserves_to_cmp[i].exchange_url, - exchange_url)) && - (GNUNET_OK == TALER_amount_cmp_currency ( - &cmp->reserves_to_cmp[i].initial_amount, - expected_amount)) && - (0 == TALER_amount_cmp (&cmp->reserves_to_cmp[i].initial_amount, - expected_amount))) - { - cmp->results_matching[i] += 1; - } - } - cmp->results_length += 1; -} - - -/** - * Tests looking up reserves that are not activated from the database. - * @param reserves_length length of @e reserves. - * @param reserves the reserves that the db is expected to return. - * - * @return 0 on success, 1 otherwise. - */ -static int -test_lookup_pending_reserves (unsigned int reserves_length, - const struct ReserveData *reserves) -{ - unsigned int results_matching[reserves_length]; - struct TestLookupReserves_Closure cmp = { - .reserves_to_cmp_length = reserves_length, - .reserves_to_cmp = reserves, - .results_matching = results_matching, - .results_length = 0 - }; - memset (results_matching, 0, sizeof (unsigned int) * reserves_length); - if (0 > plugin->lookup_pending_reserves (plugin->cls, - &lookup_pending_reserves_cb, - &cmp)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup pending reserves failed\n"); - return 1; - } - if (reserves_length != cmp.results_length) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup pending reserves failed: incorrect number of results (%d)\n", - cmp.results_length); - return 1; - } - for (unsigned int i = 0; reserves_length > i; ++i) - { - if (1 != cmp.results_matching[i]) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup pending reserves failed: mismatched data\n"); - return 1; - } - } - return 0; -} - - -/** - * Container for all tip data relevant to the database. - */ -struct TipData -{ - /** - * The details of the tip. - */ - struct TALER_MERCHANTDB_TipDetails details; - - /** - * Where the user should be redirected. - */ - const char *next_url; - - /** - * When the tip expires. - */ - struct GNUNET_TIME_Timestamp expiration; -}; - - -/** - * Creates a tip for testing. - * @param tip the tip to fill with data. - */ -static void -make_tip (struct TipData *tip) -{ - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:0.99", - &tip->details.total_amount)); - tip->details.reason = "because"; - tip->next_url = "https://taler.net"; -} - - -/** - * Tests authorizing a tip. - * @param instance the instance authorizing the tip. - * @param reserve where the tip is coming from. - * @param tip the tip to authorize. - * - * @return 0 on success, 1 otherwise. - */ -static int -test_authorize_tip (const struct InstanceData *instance, - const struct ReserveData *reserve, - struct TipData *tip) -{ - TEST_COND_RET_ON_FAIL (TALER_EC_NONE == - plugin->authorize_tip (plugin->cls, - instance->instance.id, - &reserve->reserve_pub, - &tip->details.total_amount, - tip->details.reason, - tip->next_url, - &tip->details.tip_id, - &tip->expiration), - "Authorize tip failed\n"); - return 0; -} - - -/** - * Tests looking up a tip from the database. - * @param instance the instance to look up tips from. - * @param reserve the reserve to look up tips from. - * @param tip the tip we expect to find (uses @e tip_id to perform lookup). - * @param expected_total_picked_up how much of the tip should have been - * picked up. - * - * @return 0 on success, 1 otherwise. - */ -static int -test_lookup_tip (const struct InstanceData *instance, - const struct ReserveData *reserve, - const struct TipData *tip, - const struct TALER_Amount *expected_total_picked_up) -{ - struct TALER_Amount total_authorized; - struct TALER_Amount total_picked_up; - struct GNUNET_TIME_Timestamp expiration; - char *exchange_url = NULL; - struct TALER_ReservePrivateKeyP reserve_priv; - - if (1 != plugin->lookup_tip (plugin->cls, - instance->instance.id, - &tip->details.tip_id, - &total_authorized, - &total_picked_up, - &expiration, - &exchange_url, - &reserve_priv)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup tip failed\n"); - GNUNET_free (exchange_url); - return 1; - } - if ((GNUNET_OK != - TALER_amount_cmp_currency (&tip->details.total_amount, - &total_authorized)) || - (0 != TALER_amount_cmp (&tip->details.total_amount, - &total_authorized)) || - (GNUNET_OK != - TALER_amount_cmp_currency (expected_total_picked_up, - &total_picked_up)) || - (0 != TALER_amount_cmp (expected_total_picked_up, - &total_picked_up)) || - (GNUNET_TIME_timestamp_cmp (tip->expiration, - !=, - expiration)) || - (0 != strcmp (reserve->exchange_url, - exchange_url)) || - (0 != GNUNET_memcmp (&reserve->reserve_priv, - &reserve_priv))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup tip failed: mismatched data\n"); - GNUNET_free (exchange_url); - return 1; - } - GNUNET_free (exchange_url); - return 0; -} - - -/** - * Tests looking up the details of a tip from the database. - * - * @param instance the instance the tip is in. - * @param reserve the reserve the tip was authorized from. - * @param tip the tip we expect to find (uses @e tip_id to perform lookup). - * @param expected_total_picked_up how much of the tip should have been - * picked up. - * @param expected_pickups_length the length of @e expected_pickups. - * @param expected_pickups the pickups that we expect to be associated with - * the tip. - * @return 0 on success, 1 otherwise. - */ -static int -test_lookup_tip_details ( - const struct InstanceData *instance, - const struct ReserveData *reserve, - const struct TipData *tip, - const struct TALER_Amount *expected_total_picked_up, - unsigned int expected_pickups_length, - const struct TALER_MERCHANTDB_PickupDetails *expected_pickups) -{ - struct TALER_Amount total_authorized; - struct TALER_Amount total_picked_up; - char *justification = NULL; - struct GNUNET_TIME_Timestamp expiration; - struct TALER_ReservePublicKeyP reserve_pub; - unsigned int pickups_length; - struct TALER_MERCHANTDB_PickupDetails *pickups = NULL; - unsigned int results_matching[expected_pickups_length]; - - if (0 > - plugin->lookup_tip_details (plugin->cls, - instance->instance.id, - &tip->details.tip_id, - true, - &total_authorized, - &total_picked_up, - &justification, - &expiration, - &reserve_pub, - &pickups_length, - &pickups)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup tip details failed\n"); - GNUNET_free (justification); - GNUNET_free (pickups); - return 1; - } - if ( (GNUNET_OK != - TALER_amount_cmp_currency (&tip->details.total_amount, - &total_authorized)) || - (0 != TALER_amount_cmp (&tip->details.total_amount, - &total_authorized)) || - (GNUNET_OK != - TALER_amount_cmp_currency (expected_total_picked_up, - &total_picked_up)) || - (0 != TALER_amount_cmp (expected_total_picked_up, - &total_picked_up)) || - (0 != strcmp (tip->details.reason, - justification)) || - (GNUNET_TIME_timestamp_cmp (tip->expiration, - !=, - expiration)) || - (0 != GNUNET_memcmp (&reserve->reserve_pub, - &reserve_pub)) || - (expected_pickups_length != pickups_length) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup tip details failed: mismatched data\n"); - GNUNET_free (justification); - GNUNET_free (pickups); - return 1; - } - memset (results_matching, - 0, - sizeof (unsigned int) * expected_pickups_length); - for (unsigned int i = 0; expected_pickups_length > i; ++i) - { - for (unsigned int j = 0; pickups_length > j; ++j) - { - /* Compare expected_pickups[i] with pickups[j] */ - if ((0 == GNUNET_memcmp (&expected_pickups[i].pickup_id, - &pickups[j].pickup_id)) && - (GNUNET_OK == TALER_amount_cmp_currency ( - &expected_pickups[i].requested_amount, - &pickups[j].requested_amount)) && - (0 == TALER_amount_cmp (&expected_pickups[i].requested_amount, - &pickups[j].requested_amount)) && - (expected_pickups[i].num_planchets == pickups[j].num_planchets)) - { - results_matching[i] += 1; - } - } - } - for (unsigned int i = 0; expected_pickups_length > i; ++i) - { - if (1 != results_matching[i]) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup tip details failed: mismatched data\n"); - GNUNET_free (justification); - GNUNET_free (pickups); - return 1; - } - } - return 0; -} - - -/** - * Utility function for freeing an array of RSA signatures. - * @param sigs_length length of @e sigs. - * @param sigs the signatures to free. - */ -static void -free_signature_array (unsigned int sigs_length, - struct TALER_BlindedDenominationSignature *sigs) -{ - for (unsigned int i = 0; sigs_length > i; ++i) - TALER_blinded_denom_sig_free (&sigs[i]); -} - - -/** - * Tests looking up a tip pickup. - * @param instance the instance to look up from. - * @param tip the tip the pickup was made for. - * @param pickup_id id of the pickup to look up. - * @param expected_exchange_url exchange url for the pickup. - * @param expected_reserve_priv reserve private key for the pickup. - * @param expected_sigs_length length of @e expected_sigs. - * @param expected_sigs the signatures we expect to be made for the pickup. - * - * @return 0 on success, 1 otherwise. - */ -static int -test_lookup_pickup ( - const struct InstanceData *instance, - const struct TipData *tip, - const struct TALER_PickupIdentifierP *pickup_id, - const char *expected_exchange_url, - const struct TALER_ReservePrivateKeyP *expected_reserve_priv, - unsigned int expected_sigs_length, - const struct TALER_BlindedDenominationSignature *expected_sigs) -{ - char *exchange_url = NULL; - struct TALER_ReservePrivateKeyP reserve_priv; - struct TALER_BlindedDenominationSignature sigs[expected_sigs_length]; - unsigned int results_matching[expected_sigs_length]; - - memset (sigs, - 0, - sizeof (sigs)); - if (0 > plugin->lookup_pickup (plugin->cls, - instance->instance.id, - &tip->details.tip_id, - pickup_id, - &exchange_url, - &reserve_priv, - expected_sigs_length, - sigs)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup pickup failed\n"); - GNUNET_free (exchange_url); - free_signature_array (expected_sigs_length, - sigs); - return 1; - } - if ((0 != strcmp (expected_exchange_url, - exchange_url)) || - (0 != GNUNET_memcmp (expected_reserve_priv, - &reserve_priv))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup pickup failed: mismatched data\n"); - GNUNET_free (exchange_url); - free_signature_array (expected_sigs_length, - sigs); - return 1; - } - memset (results_matching, - 0, - sizeof (unsigned int) * expected_sigs_length); - for (unsigned int i = 0; expected_sigs_length > i; ++i) - { - for (unsigned int j = 0; expected_sigs_length > j; ++j) - { - /* compare expected_sigs[i] to sigs[j] */ - if (0 == - TALER_blinded_denom_sig_cmp (&expected_sigs[i], - &sigs[j])) - { - results_matching[i] += 1; - } - } - } - for (unsigned int i = 0; expected_sigs_length > i; ++i) - { - if (1 != results_matching[i]) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup pickup failed: mismatched data\n"); - GNUNET_free (exchange_url); - free_signature_array (expected_sigs_length, - sigs); - return 1; - } - } - return 0; -} - - -/** - * Closure for testing lookup_tips. - */ -struct TestLookupTips_Closure -{ - /** - * The length of @e tips_to_cmp. - */ - unsigned int tips_to_cmp_length; - - /** - * The tips that we are expecting to find. - */ - const struct TipData *tips_to_cmp; - - /** - * The number of results found from the lookup. - */ - unsigned int results_length; - - /** - * Whether each result matches with the corresponding tip in @tips_to_cmp. - */ - bool *results_match; -}; - - -/** - * Called after test_lookup_tips. - * @param cls pointer to a TestLookupTips_Closure. - * @param row_id the row id of the tip. - * @param tip_id the id of the tip. - * @param amount the amount of the tip. - */ -static void -lookup_tips_cb (void *cls, - uint64_t row_id, - struct TALER_TipIdentifierP tip_id, - struct TALER_Amount amount) -{ - struct TestLookupTips_Closure *cmp = cls; - if (NULL == cmp) - return; - unsigned int i = cmp->results_length; - cmp->results_length += 1; - if (cmp->tips_to_cmp_length > i) - { - if ((0 == GNUNET_memcmp (&cmp->tips_to_cmp[i].details.tip_id, - &tip_id)) && - (GNUNET_OK == TALER_amount_cmp_currency ( - &cmp->tips_to_cmp[i].details.total_amount, - &amount)) && - (0 == TALER_amount_cmp (&cmp->tips_to_cmp[i].details.total_amount, - &amount))) - cmp->results_match[i] = true; - else - cmp->results_match[i] = false; - } -} - - -/** - * Tests looking up the tips from the database. - * @param instance the instance to look up tips from. - * @param expired how to filter expired tips. - * @param offset where to start retrieving tips. - * @param tips_length length of @e tips. - * @param tips the tips that we expect to find. - * - * @return 0 on success, 1 otherwise. - */ -static int -test_lookup_tips (const struct InstanceData *instance, - enum TALER_EXCHANGE_YesNoAll expired, - int64_t limit, - uint64_t offset, - unsigned int tips_length, - const struct TipData *tips) -{ - bool results_match[tips_length]; - struct TestLookupTips_Closure cmp = { - .tips_to_cmp_length = tips_length, - .tips_to_cmp = tips, - .results_length = 0, - .results_match = results_match - }; - - memset (results_match, - 0, - sizeof (bool) * tips_length); - if (0 > plugin->lookup_tips (plugin->cls, - instance->instance.id, - expired, - limit, - offset, - &lookup_tips_cb, - &cmp)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup tips failed\n"); - return 1; - } - if (tips_length != cmp.results_length) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup tips failed: incorrect number of results (%d)\n", - cmp.results_length); - return 1; - } - for (unsigned int i = 0; i < tips_length; ++i) - { - if (true != cmp.results_match[i]) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup tips failed: mismatched data\n"); - return 1; - } - } - return 0; -} - - -/** - * Convenience function for testing lookup tips with filters - * @param tips_length length of @e tips. - * @param tips the array of tips to reverse. - */ -static void -reverse_tip_data_array (unsigned int tips_length, - struct TipData *tips) -{ - struct TipData tmp[tips_length]; - for (unsigned int i = 0; i < tips_length; ++i) - tmp[i] = tips[tips_length - 1 - i]; - for (unsigned int i = 0; i < tips_length; ++i) - tips[i] = tmp[i]; -} - - -/** - * Container for data for testing tips. - */ -struct TestTips_Closure -{ - /** - * The instance. - */ - struct InstanceData instance; - - /** - * The tip reserve data. - */ - struct ReserveData reserve; - - /** - * Reserve data that is expired. - */ - struct ReserveData expired_reserve; - - /** - * A normal tip. - */ - struct TipData tip; - - /** - * A tip that is too large to authorize. - */ - struct TipData bigtip; - - /** - * Array of tips for testing lookups. - */ - struct TipData tips[5]; - - /** - * Id of a pickup. - */ - struct TALER_PickupIdentifierP pickup_id; - - /** - * Private key of the pickup. - */ - struct GNUNET_CRYPTO_RsaPrivateKey *pickup_priv; - - /** - * Signature for the pickup. - */ - struct TALER_BlindedDenominationSignature pickup_sig; -}; - - -/** - * Prepares for testing tips functionality. - * @param cls the data to prepare. - */ -static void -pre_test_tips (struct TestTips_Closure *cls) -{ - /* Instance */ - make_instance ("test_inst_tips", - &cls->instance); - - /* Reserve */ - GNUNET_CRYPTO_eddsa_key_create (&cls->reserve.reserve_priv.eddsa_priv); - GNUNET_CRYPTO_eddsa_key_get_public (&cls->reserve.reserve_priv.eddsa_priv, - &cls->reserve.reserve_pub.eddsa_pub); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:99.99", - &cls->reserve.initial_amount)); - cls->reserve.exchange_url = "https://exch-url/"; - cls->reserve.payto_uri = "payto://other-uri"; - cls->reserve.expiration = GNUNET_TIME_relative_to_timestamp ( - GNUNET_TIME_UNIT_WEEKS); - - GNUNET_CRYPTO_eddsa_key_create ( - &cls->expired_reserve.reserve_priv.eddsa_priv); - GNUNET_CRYPTO_eddsa_key_get_public ( - &cls->expired_reserve.reserve_priv.eddsa_priv, - &cls->expired_reserve.reserve_pub. - eddsa_pub); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:99.99", - &cls->expired_reserve.initial_amount)); - cls->expired_reserve.exchange_url = "exch-url"; - cls->expired_reserve.payto_uri = "payto://some-uri"; - cls->expired_reserve.expiration = GNUNET_TIME_UNIT_ZERO_TS; - - /* Tip/pickup */ - make_tip (&cls->tip); - make_tip (&cls->bigtip); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:99.90", - &cls->bigtip.details.total_amount)); - for (unsigned int i = 0; i < 5; ++i) - { - char amount[16]; - make_tip (&cls->tips[i]); - GNUNET_snprintf (amount, - 16, - "EUR:0.%u0", - i + 1); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (amount, - &cls->tips[i].details.total_amount)); - } - - cls->pickup_priv = GNUNET_CRYPTO_rsa_private_key_create (2048); - cls->pickup_sig.cipher = TALER_DENOMINATION_RSA; - cls->pickup_sig.details.blinded_rsa_signature - = GNUNET_CRYPTO_rsa_sign_fdh (cls->pickup_priv, - &cls->pickup_id.hash); -} - - -/** - * Cleans up after testing tips. - * @param cls the data to clean up. - */ -static void -post_test_tips (struct TestTips_Closure *cls) -{ - free_instance_data (&cls->instance); - GNUNET_CRYPTO_rsa_private_key_free (cls->pickup_priv); - TALER_blinded_denom_sig_free (&cls->pickup_sig); -} - - -/** - * Runs tests for tips. - * @param cls container of test data. - * - * @return 0 on success, 1 on failure. - */ -static int -run_test_tips (struct TestTips_Closure *cls) -{ - struct TALER_Amount zero; - - GNUNET_assert (GNUNET_OK == - TALER_amount_set_zero ("EUR", - &zero)); - TEST_RET_ON_FAIL (test_insert_instance (&cls->instance, - GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); - /* Test insert reserve */ - TEST_RET_ON_FAIL (test_insert_reserve (&cls->instance, - &cls->reserve, - TALER_EC_NONE)); - /* Test lookup reserve */ - TEST_RET_ON_FAIL (test_lookup_reserve (&cls->instance, - &cls->reserve.reserve_pub, - &cls->reserve)); - /* Test lookup pending reserves */ - TEST_RET_ON_FAIL (test_lookup_pending_reserves (1, - &cls->reserve)); - /* Test reserve activation */ - TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == - plugin->activate_reserve (plugin->cls, - cls->instance.instance.id, - &cls->reserve.reserve_pub, - &cls->reserve.initial_amount), - "Activate reserve failed\n"); - TEST_RET_ON_FAIL (test_lookup_pending_reserves (0, - NULL)); - /* Test inserting a tip */ - TEST_RET_ON_FAIL (test_authorize_tip (&cls->instance, - &cls->reserve, - &cls->tip)); - /* Test lookup tip */ - TEST_RET_ON_FAIL (test_lookup_tip (&cls->instance, - &cls->reserve, - &cls->tip, - &zero)); - /* Test lookup tip details */ - TEST_RET_ON_FAIL (test_lookup_tip_details (&cls->instance, - &cls->reserve, - &cls->tip, - &zero, - 0, - NULL)); - /* Test insert pickup */ - TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == - plugin->insert_pickup (plugin->cls, - cls->instance.instance.id, - &cls->tip.details.tip_id, - &cls->tip.details.total_amount, - &cls->pickup_id, - &cls->tip.details.total_amount), - "Insert pickup failed\n"); - /* Test lookup pickup */ - TEST_RET_ON_FAIL (test_lookup_pickup (&cls->instance, - &cls->tip, - &cls->pickup_id, - cls->reserve.exchange_url, - &cls->reserve.reserve_priv, - 0, - NULL)); - /* Test insert pickup blind signature */ - TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == - plugin->insert_pickup_blind_signature (plugin->cls, - &cls->pickup_id, - 0, - &cls->pickup_sig), - "Insert pickup blind signature failed\n"); - /* Test that overdrawing the reserve fails */ - TEST_COND_RET_ON_FAIL (TALER_EC_NONE != - plugin->authorize_tip (plugin->cls, - cls->instance.instance.id, - &cls->reserve.reserve_pub, - &cls->bigtip.details. - total_amount, - cls->bigtip.details.reason, - cls->bigtip.next_url, - &cls->bigtip.details.tip_id, - &cls->reserve.expiration), - "Authorize tip failed\n"); - /* Test lookup tips */ - TEST_RET_ON_FAIL (test_lookup_tips (&cls->instance, - TALER_EXCHANGE_YNA_ALL, - 1, - 0, - 1, - &cls->tip)); - /* Test lookup reserves */ - TEST_RET_ON_FAIL (test_lookup_reserves (&cls->instance, - 1, - &cls->reserve)); - { - /* Test lookup tips & friends */ - struct TipData expected_tips[6]; - expected_tips[0] = cls->tip; - TEST_RET_ON_FAIL (test_insert_reserve (&cls->instance, - &cls->expired_reserve, - TALER_EC_NONE)); - TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == - plugin->activate_reserve (plugin->cls, - cls->instance.instance.id, - &cls->expired_reserve. - reserve_pub, - &cls->expired_reserve. - initial_amount), - "Activate reserve failed\n"); - for (unsigned int i = 0; i < 5; ++i) - { - if (i % 2 == 0) - { - TEST_RET_ON_FAIL (test_authorize_tip (&cls->instance, - &cls->expired_reserve, - &cls->tips[i])); - } - else - { - TEST_RET_ON_FAIL (test_authorize_tip (&cls->instance, - &cls->reserve, - &cls->tips[i])); - } - } - GNUNET_memcpy (&expected_tips[1], - cls->tips, - sizeof (struct TipData) * 5); - /* Test lookup tips inc */ - TEST_RET_ON_FAIL (test_lookup_tips (&cls->instance, - TALER_EXCHANGE_YNA_ALL, - 6, - 0, - 6, - expected_tips)); - reverse_tip_data_array (6, - expected_tips); - /* Test lookup tips dec */ - TEST_RET_ON_FAIL (test_lookup_tips (&cls->instance, - TALER_EXCHANGE_YNA_ALL, - -6, - 10, - 6, - expected_tips)); - /* Test lookup tips expired inc */ - expected_tips[0] = cls->tips[0]; - expected_tips[1] = cls->tips[2]; - expected_tips[2] = cls->tips[4]; - TEST_RET_ON_FAIL (test_lookup_tips (&cls->instance, - TALER_EXCHANGE_YNA_YES, - 6, - 0, - 3, - expected_tips)); - /* Test lookup tips expired dec */ - reverse_tip_data_array (3, - expected_tips); - TEST_RET_ON_FAIL (test_lookup_tips (&cls->instance, - TALER_EXCHANGE_YNA_YES, - -6, - 10, - 3, - expected_tips)); - /* Test lookup tips unexpired inc */ - expected_tips[0] = cls->tip; - expected_tips[1] = cls->tips[1]; - expected_tips[2] = cls->tips[3]; - TEST_RET_ON_FAIL (test_lookup_tips (&cls->instance, - TALER_EXCHANGE_YNA_NO, - 6, - 0, - 3, - expected_tips)); - /* Test lookup tips unexpired dec */ - reverse_tip_data_array (3, - expected_tips); - TEST_RET_ON_FAIL (test_lookup_tips (&cls->instance, - TALER_EXCHANGE_YNA_NO, - -6, - 10, - 3, - expected_tips)); - } - /* Test delete reserve private key */ - TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == - plugin->delete_reserve (plugin->cls, - cls->instance.instance.id, - &cls->reserve.reserve_pub), - "Delete reserve private key failed\n"); - TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == - plugin->delete_reserve (plugin->cls, - cls->instance.instance.id, - &cls->reserve.reserve_pub), - "Delete reserve private key failed\n"); - /* Test purging a reserve */ - TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == - plugin->purge_reserve (plugin->cls, - cls->instance.instance.id, - &cls->reserve.reserve_pub), - "Purge reserve failed\n"); - TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == - plugin->purge_reserve (plugin->cls, - cls->instance.instance.id, - &cls->reserve.reserve_pub), - "Purge reserve failed\n"); - - return 0; -} - - -/** - * Handles all logic for testing tips in the database. - * - * @return 0 on success, 1 on failure. - */ -static int -test_tips (void) -{ - struct TestTips_Closure test_cls; - pre_test_tips (&test_cls); - int test_result = run_test_tips (&test_cls); - post_test_tips (&test_cls); - return test_result; -} - - /** * Closure for testing lookup_refunds. */ @@ -5781,7 +4469,8 @@ test_lookup_refunds (const struct InstanceData *instance, if (refunds_length != cmp.results_length) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup refunds failed: incorrect number of results returned\n"); + "Lookup refunds failed: incorrect number of results returned\n") + ; return 1; } for (unsigned int i = 0; refunds_length > i; ++i) @@ -5989,7 +4678,8 @@ test_lookup_refunds_detailed ( if (refunds_length != cmp.results_length) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup refunds detailed failed: incorrect number of results\n"); + "Lookup refunds detailed failed: incorrect number of results\n") + ; return 1; } for (unsigned int i = 0; refunds_length > i; ++i) @@ -6303,7 +4993,8 @@ run_test_refunds (struct TestRefunds_Closure *cls) TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == plugin->refund_coin (plugin->cls, cls->instance.instance.id, - &cls->deposits[0].h_contract_terms, + &cls->deposits[0].h_contract_terms + , cls->refunds[0].timestamp, cls->refunds[0].coin_pub, cls->refunds[0].reason), @@ -6315,7 +5006,8 @@ run_test_refunds (struct TestRefunds_Closure *cls) TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == plugin->refund_coin (plugin->cls, cls->instance.instance.id, - &cls->deposits[0].h_contract_terms, + &cls->deposits[0].h_contract_terms + , cls->refunds[0].timestamp, cls->refunds[0].coin_pub, cls->refunds[0].reason), @@ -6339,14 +5031,16 @@ run_test_refunds (struct TestRefunds_Closure *cls) refund_serial, &cls->refund_proof. exchange_sig, - &cls->signkey.exchange_pub), + &cls->signkey.exchange_pub + ), "Insert refund proof failed\n"); TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == plugin->insert_refund_proof (plugin->cls, refund_serial, &cls->refund_proof. exchange_sig, - &cls->signkey.exchange_pub), + &cls->signkey.exchange_pub + ), "Insert refund proof failed\n"); /* Test that we can't give too much in refunds */ GNUNET_assert (GNUNET_OK == @@ -6512,9 +5206,10 @@ pre_test_lookup_orders_all_filters ( i); make_order (cls->order_ids[i], &cls->orders[i]); - GNUNET_assert (0 == json_object_set (cls->orders[i].contract, - "order_id", - json_string (cls->order_ids[i]))); + GNUNET_assert (0 == + json_object_set_new (cls->orders[i].contract, + "order_id", + json_string (cls->order_ids[i]))); make_deposit (&cls->instance, &cls->account, &cls->orders[i], @@ -6718,7 +5413,8 @@ kyc_status_ok (void *cls, const char *payto_uri, const char *exchange_url, struct GNUNET_TIME_Timestamp last_check, - bool kyc_ok) + bool kyc_ok, + enum TALER_AmlDecisionState ades) { bool *fail = cls; @@ -6734,7 +5430,8 @@ kyc_status_fail (void *cls, const char *payto_uri, const char *exchange_url, struct GNUNET_TIME_Timestamp last_check, - bool kyc_ok) + bool kyc_ok, + enum TALER_AmlDecisionState ades) { bool *fail = cls; @@ -6774,7 +5471,8 @@ test_kyc (void) NULL, NULL, now, - false)); + false, + TALER_AML_NORMAL)); TEST_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->account_kyc_set_status (plugin->cls, instance.instance.id, @@ -6784,7 +5482,8 @@ test_kyc (void) NULL, NULL, now, - false)); + false, + TALER_AML_NORMAL)); TEST_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->account_kyc_set_status (plugin->cls, instance.instance.id, @@ -6794,7 +5493,8 @@ test_kyc (void) NULL, NULL, now, - true)); + true, + TALER_AML_NORMAL)); fail = true; TEST_RET_ON_FAIL (1 != plugin->account_kyc_get_status (plugin->cls, @@ -6831,6 +5531,8 @@ test_kyc (void) &kyc_status_ok, &fail)); TEST_RET_ON_FAIL (fail); + json_decref (instance.instance.address); + json_decref (instance.instance.jurisdiction); return 0; } @@ -6866,7 +5568,7 @@ make_template (const char *id, { template->id = id; template->template.template_description = "This is a test template"; - template->template.image = NULL; + template->template.otp_id = NULL; template->template.template_contract = json_array (); GNUNET_assert (NULL != template->template.template_contract); } @@ -6880,7 +5582,7 @@ make_template (const char *id, static void free_template_data (struct TemplateData *template) { - GNUNET_free (template->template.image); + GNUNET_free (template->template.otp_id); json_decref (template->template.template_contract); } @@ -6898,9 +5600,10 @@ check_templates_equal (const struct TALER_MERCHANTDB_TemplateDetails *a, { if ((0 != strcmp (a->template_description, b->template_description)) || - ( (NULL == a->image) && (NULL != b->image)) || - ( (NULL != a->image) && (NULL == b->image)) || - ( (NULL != a->image) && (0 != strcmp (a->image, b->image))) || + ( (NULL == a->otp_id) && (NULL != b->otp_id)) || + ( (NULL != a->otp_id) && (NULL == b->otp_id)) || + ( (NULL != a->otp_id) && (0 != strcmp (a->otp_id, + b->otp_id))) || (1 != json_equal (a->template_contract, b->template_contract))) return 1; @@ -6925,6 +5628,7 @@ test_insert_template (const struct InstanceData *instance, plugin->insert_template (plugin->cls, instance->instance.id, template->id, + 0, &template->template), "Insert template failed\n"); return 0; @@ -6966,11 +5670,12 @@ test_lookup_template (const struct InstanceData *instance, const struct TemplateData *template) { struct TALER_MERCHANTDB_TemplateDetails lookup_result; + if (0 > plugin->lookup_template (plugin->cls, instance->instance.id, template->id, &lookup_result)) - { + { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Lookup template failed\n"); TALER_MERCHANTDB_template_details_free (&lookup_result); @@ -7030,15 +5735,16 @@ lookup_templates_cb (void *cls, const char *template_description) { struct TestLookupTemplates_Closure *cmp = cls; + if (NULL == cmp) return; cmp->results_length += 1; for (unsigned int i = 0; cmp->templates_to_cmp_length > i; ++i) { - if ((0 == strcmp (cmp->templates_to_cmp[i].id, - template_id)) && - (0 == strcmp (cmp->templates_to_cmp[i].template.template_description, - template_description)) ) + if ( (0 == strcmp (cmp->templates_to_cmp[i].id, + template_id)) && + (0 == strcmp (cmp->templates_to_cmp[i].template.template_description, + template_description)) ) cmp->results_matching[i] += 1; } } @@ -7064,7 +5770,10 @@ test_lookup_templates (const struct InstanceData *instance, .results_matching = results_matching, .results_length = 0 }; - memset (results_matching, 0, sizeof (unsigned int) * templates_length); + + memset (results_matching, + 0, + sizeof (unsigned int) * templates_length); if (0 > plugin->lookup_templates (plugin->cls, instance->instance.id, &lookup_templates_cb, @@ -7211,8 +5920,22 @@ run_test_templates (struct TestTemplates_Closure *cls) /* Test template update */ cls->templates[0].template.template_description = "This is a test template that has been updated!"; - GNUNET_free (cls->templates[0].template.image); - cls->templates[0].template.image = GNUNET_strdup ("image"); + GNUNET_free (cls->templates[0].template.otp_id); + cls->templates[0].template.otp_id = GNUNET_strdup ("otp_id"); + { + /* ensure OTP device exists */ + struct TALER_MERCHANTDB_OtpDeviceDetails td = { + .otp_description = "my otp", + .otp_key = "my key", + .otp_algorithm = 1, + .otp_ctr = 42 + }; + GNUNET_assert (0 <= + plugin->insert_otp (plugin->cls, + cls->instance.instance.id, + "otp_id", + &td)); + } GNUNET_assert (0 == json_array_append_new ( cls->templates[0].template.template_contract, @@ -7220,7 +5943,6 @@ run_test_templates (struct TestTemplates_Closure *cls) TEST_RET_ON_FAIL (test_update_template (&cls->instance, &cls->templates[0], GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); - TEST_RET_ON_FAIL (test_lookup_template (&cls->instance, &cls->templates[0])); TEST_RET_ON_FAIL (test_update_template (&cls->instance, @@ -7258,8 +5980,13 @@ static int test_templates (void) { struct TestTemplates_Closure test_cls; + int test_result; + + memset (&test_cls, + 0, + sizeof (test_cls)); pre_test_templates (&test_cls); - int test_result = run_test_templates (&test_cls); + test_result = run_test_templates (&test_cls); post_test_templates (&test_cls); return test_result; } @@ -7514,6 +6241,7 @@ test_lookup_webhooks (const struct InstanceData *instance, return 0; } + /** * Function called after calling @e test_lookup_webhooks * @@ -7538,16 +6266,17 @@ lookup_webhook_by_event_cb (void *cls, if ((0 == strcmp (cmp->webhooks_to_cmp[i].webhook.event_type, event_type)) && (0 == strcmp (cmp->webhooks_to_cmp[i].webhook.url, - url)) && + url)) && (0 == strcmp (cmp->webhooks_to_cmp[i].webhook.http_method, - http_method)) && + http_method)) && (0 == strcmp (cmp->webhooks_to_cmp[i].webhook.header_template, - header_template)) && + header_template)) && (0 == strcmp (cmp->webhooks_to_cmp[i].webhook.body_template, body_template)) ) cmp->results_matching[i] += 1; } - } +} + /** * Tests looking up webhooks by event for an instance. @@ -7600,7 +6329,6 @@ test_lookup_webhook_by_event (const struct InstanceData *instance, } - /** * Tests deleting a webhook. * @@ -7794,7 +6522,6 @@ test_webhooks (void) } - /* *********** Pending Webhooks ********** */ /** @@ -7805,7 +6532,7 @@ struct PendingWebhookData /** * Reference to the configured webhook template. */ - uint64_t webhook_serial; + uint64_t webhook_serial; /** * The details of the pending webhook. @@ -7814,8 +6541,6 @@ struct PendingWebhookData }; - - /** * Creates a pending webhook for testing with. * @@ -7828,43 +6553,13 @@ make_pending_webhook (uint64_t webhook_serial, { pwebhook->webhook_serial = webhook_serial; pwebhook->pwebhook.next_attempt = GNUNET_TIME_UNIT_ZERO_ABS; - pwebhook->pwebhook.retries= 0; + pwebhook->pwebhook.retries = 0; pwebhook->pwebhook.url = "https://exampletest.com"; pwebhook->pwebhook.http_method = "POST"; pwebhook->pwebhook.header = "Authorization:XYJAORKJEO"; pwebhook->pwebhook.body = "$Amount"; } -/** - * Compare two pending webhooks for equality. - * - * @param a the first pending webhook. - * @param b the second pending webhook. - * @return 0 on equality, 1 otherwise. - */ -static int -check_pending_webhooks_equal (const struct TALER_MERCHANTDB_PendingWebhookDetails *a, - const struct TALER_MERCHANTDB_PendingWebhookDetails *b) -{ - if (GNUNET_TIME_absolute_cmp (a->next_attempt, - !=, - b->next_attempt) || - (a->retries != b->retries) || - (0 != strcmp (a->url, - b->url)) || - (0 != strcmp (a->http_method, - b->http_method)) || - (0 != strcmp (a->header, - b->header)) || - (0 != strcmp (a->body, - b->body))) - { - fprintf(stdout, " retries %d vs %d", a->retries, b->retries); - return 1; - } - return 0; -} - /** * Tests inserting pending webhook data into the database. @@ -7883,11 +6578,15 @@ test_insert_pending_webhook (const struct InstanceData *instance, TEST_COND_RET_ON_FAIL (expected_result == plugin->insert_pending_webhook (plugin->cls, instance->instance.id, - pwebhook->webhook_serial, + pwebhook-> + webhook_serial, pwebhook->pwebhook.url, - pwebhook->pwebhook.http_method, - pwebhook->pwebhook.header, - pwebhook->pwebhook.body), + pwebhook->pwebhook. + http_method, + pwebhook->pwebhook. + header, + pwebhook->pwebhook.body + ), "Insert pending webhook failed\n"); return 0; } @@ -7906,51 +6605,108 @@ test_update_pending_webhook (const struct InstanceData *instance, struct PendingWebhookData *pwebhook, enum GNUNET_DB_QueryStatus expected_result) { + pwebhook->pwebhook.next_attempt = GNUNET_TIME_relative_to_absolute ( + GNUNET_TIME_UNIT_HOURS); + pwebhook->pwebhook.retries++; TEST_COND_RET_ON_FAIL (expected_result == plugin->update_pending_webhook (plugin->cls, - pwebhook->webhook_serial, - pwebhook->pwebhook.next_attempt), + pwebhook-> + webhook_serial, + pwebhook->pwebhook. + next_attempt), "Update pending webhook failed\n"); return 0; } /** - * Tests looking up a pending webhook from the db. + * Container for information for looking up the row number of a deposit. + */ +struct LookupPendingWebhookSerial_Closure +{ + /** + * The pending webhook we're looking for. + */ + const struct PendingWebhookData *pwebhook; + + /** + * The serial found. + */ + uint64_t webhook_pending_serial; +}; + + +/** + * Function called after calling @e test_lookup_all_webhook, + * test_lookup_future_webhook and test_lookup_pending_webhook * - * @param instance the instance to query from. - * @param pwebhook the pending webhook to query and compare to. - * @return 0 when successful, 1 otherwise. + * @param cls a pointer to the lookup closure. + * @param webhook_serial reference to the configured webhook template. */ -static int -test_lookup_pending_webhook (const struct InstanceData *instance, - struct PendingWebhookData *pwebhook) -{ - struct TALER_MERCHANTDB_PendingWebhookDetails lookup_result; - if (0 > plugin->lookup_pending_webhook (plugin->cls, - instance->instance.id, - &pwebhook->webhook_serial, - &lookup_result)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup pending webhook failed\n"); - TALER_MERCHANTDB_pending_webhook_details_free (&lookup_result); - return 1; - } - const struct TALER_MERCHANTDB_PendingWebhookDetails *to_cmp = &pwebhook->pwebhook; - if (0 != check_pending_webhooks_equal (&lookup_result, - to_cmp)) +static void +get_pending_serial_cb (void *cls, + uint64_t webhook_pending_serial, + struct GNUNET_TIME_Absolute next_attempt, + uint32_t retries, + const char *url, + const char *http_method, + const char *header, + const char *body) +{ + struct LookupPendingWebhookSerial_Closure *lpw = cls; + + if ((0 == strcmp (lpw->pwebhook->pwebhook.url, + url)) && + (0 == strcmp (lpw->pwebhook->pwebhook.http_method, + http_method)) && + (0 == strcmp (lpw->pwebhook->pwebhook.header, + header)) && + (0 == strcmp (lpw->pwebhook->pwebhook.body, + body)) ) + { + lpw->webhook_pending_serial = webhook_pending_serial; + } + /* else { - GNUNET_break (0); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup pending webhook failed: incorrect pending webhook returned\n"); - TALER_MERCHANTDB_pending_webhook_details_free (&lookup_result); - return 1; - } - TALER_MERCHANTDB_pending_webhook_details_free (&lookup_result); - return 0; + fprintf(stdout, "next_attempt: %lu vs %lu\n", lpw->pwebhook->pwebhook.next_attempt.abs_value_us, next_attempt.abs_value_us); + fprintf(stdout, "retries: %d vs %d\n", lpw->pwebhook->pwebhook.retries, retries); + fprintf(stdout, "url: %s vs %s\n", lpw->pwebhook->pwebhook.url, url); + fprintf(stdout, "http_method: %s vs %s\n", lpw->pwebhook->pwebhook.http_method, http_method); + fprintf(stdout, "header: %s vs %s\n", lpw->pwebhook->pwebhook.header, header); + fprintf(stdout, "body: %s vs %s\n", lpw->pwebhook->pwebhook.body, body); + }*/ } + +/** + * Convenience function to retrieve the row number of a webhook pending in the database. + * + * @param instance the instance to get webhook pending(wp) from. + * @param webhook pending the wp to lookup the serial for. + * @return the row number of the deposit. + */ +static uint64_t +get_pending_serial (const struct InstanceData *instance, + const struct PendingWebhookData *pwebhook) +{ + struct LookupPendingWebhookSerial_Closure lpw = { + .pwebhook = pwebhook, + .webhook_pending_serial = 0 + }; + + GNUNET_assert (0 < + plugin->lookup_all_webhooks (plugin->cls, + instance->instance.id, + 0, + INT_MAX, + &get_pending_serial_cb, + &lpw)); + GNUNET_assert (0 != lpw.webhook_pending_serial); + + return lpw.webhook_pending_serial; +} + + /** * Closure for testing pending webhook lookup */ @@ -7977,6 +6733,7 @@ struct TestLookupPendingWebhooks_Closure unsigned int results_length; }; + /** * Function called after calling @e test_lookup_all_webhook, * test_lookup_future_webhook and test_lookup_pending_webhook @@ -7986,7 +6743,7 @@ struct TestLookupPendingWebhooks_Closure */ static void lookup_pending_webhooks_cb (void *cls, - uint64_t webhook_serial, + uint64_t webhook_pending_serial, struct GNUNET_TIME_Absolute next_attempt, uint32_t retries, const char *url, @@ -7995,16 +6752,21 @@ lookup_pending_webhooks_cb (void *cls, const char *body) { struct TestLookupPendingWebhooks_Closure *cmp = cls; - if (NULL == cmp) - return; - cmp->results_length += 1; + + cmp->results_length++; for (unsigned int i = 0; cmp->webhooks_to_cmp_length > i; ++i) { - if ((cmp->webhooks_to_cmp[i].webhook_serial != webhook_serial) && - (GNUNET_TIME_absolute_cmp (cmp->webhooks_to_cmp[i].pwebhook.next_attempt, - !=, - next_attempt))) - cmp->results_matching[i] += 1; + if ((0 == strcmp (cmp->webhooks_to_cmp[i].pwebhook.url, + url)) && + (0 == strcmp (cmp->webhooks_to_cmp[i].pwebhook.http_method, + http_method)) && + (0 == strcmp (cmp->webhooks_to_cmp[i].pwebhook.header, + header)) && + (0 == strcmp (cmp->webhooks_to_cmp[i].pwebhook.body, + body)) ) + { + cmp->results_matching[i]++; + } } } @@ -8019,8 +6781,8 @@ lookup_pending_webhooks_cb (void *cls, */ static int test_lookup_pending_webhooks (const struct InstanceData *instance, - unsigned int pwebhooks_length, - const struct PendingWebhookData *pwebhooks) + unsigned int pwebhooks_length, + const struct PendingWebhookData *pwebhooks) { unsigned int results_matching[pwebhooks_length]; struct TestLookupPendingWebhooks_Closure cls = { @@ -8029,10 +6791,11 @@ test_lookup_pending_webhooks (const struct InstanceData *instance, .results_matching = results_matching, .results_length = 0 }; - memset (results_matching, 0, sizeof (unsigned int) * pwebhooks_length); + + memset (results_matching, 0, sizeof (results_matching)); if (0 > plugin->lookup_pending_webhooks (plugin->cls, - &lookup_pending_webhooks_cb, - &cls)) + &lookup_pending_webhooks_cb, + &cls)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Lookup pending webhook failed\n"); @@ -8044,7 +6807,7 @@ test_lookup_pending_webhooks (const struct InstanceData *instance, "Lookup pending webhook failed: incorrect number of results\n"); return 1; } - for (unsigned int i = 0; pwebhooks_length > i; ++i) + for (unsigned int i = 0; i < pwebhooks_length; i++) { if (1 != cls.results_matching[i]) { @@ -8054,7 +6817,8 @@ test_lookup_pending_webhooks (const struct InstanceData *instance, } } return 0; - } +} + /** * Tests looking up the future webhook to send for an instance. @@ -8066,8 +6830,8 @@ test_lookup_pending_webhooks (const struct InstanceData *instance, */ static int test_lookup_future_webhook (const struct InstanceData *instance, - unsigned int pwebhooks_length, - const struct PendingWebhookData *pwebhooks) + unsigned int pwebhooks_length, + const struct PendingWebhookData *pwebhooks) { unsigned int results_matching[pwebhooks_length]; struct TestLookupPendingWebhooks_Closure cls = { @@ -8076,7 +6840,8 @@ test_lookup_future_webhook (const struct InstanceData *instance, .results_matching = results_matching, .results_length = 0 }; - memset (results_matching, 0, sizeof (unsigned int) * pwebhooks_length); + + memset (results_matching, 0, sizeof (results_matching)); if (0 > plugin->lookup_future_webhook (plugin->cls, &lookup_pending_webhooks_cb, &cls)) @@ -8103,6 +6868,7 @@ test_lookup_future_webhook (const struct InstanceData *instance, return 0; } + /** * Tests looking up all the pending webhook for an instance. * @@ -8116,16 +6882,19 @@ test_lookup_all_webhooks (const struct InstanceData *instance, unsigned int pwebhooks_length, const struct PendingWebhookData *pwebhooks) { - uint64_t max_results=2; - uint64_t min_row=0; - unsigned int results_matching[pwebhooks_length]; + uint64_t max_results = 2; + uint64_t min_row = 0; + unsigned int results_matching[GNUNET_NZL (pwebhooks_length)]; struct TestLookupPendingWebhooks_Closure cls = { .webhooks_to_cmp_length = pwebhooks_length, .webhooks_to_cmp = pwebhooks, .results_matching = results_matching, .results_length = 0 }; - memset (results_matching, 0, sizeof (unsigned int) * pwebhooks_length); + + memset (results_matching, + 0, + sizeof (results_matching)); if (0 > plugin->lookup_all_webhooks (plugin->cls, instance->instance.id, min_row, @@ -8165,12 +6934,13 @@ test_lookup_all_webhooks (const struct InstanceData *instance, * @return 0 when successful, 1 otherwise. */ static int -test_delete_pending_webhook (const struct PendingWebhookData *webhook, +test_delete_pending_webhook (uint64_t webhooks_pending_serial, enum GNUNET_DB_QueryStatus expected_result) { + TEST_COND_RET_ON_FAIL (expected_result == plugin->delete_pending_webhook (plugin->cls, - webhook->webhook_serial), + webhooks_pending_serial), "Delete webhook failed\n"); return 0; } @@ -8252,40 +7022,40 @@ run_test_pending_webhooks (struct TestPendingWebhooks_Closure *cls) TEST_RET_ON_FAIL (test_insert_pending_webhook (&cls->instance, &cls->pwebhooks[0], GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); - /* Test lookup of individual pending webhook */ - TEST_RET_ON_FAIL (test_lookup_pending_webhook (&cls->instance, - &cls->pwebhooks[0])); + TEST_RET_ON_FAIL (test_insert_pending_webhook (&cls->instance, + &cls->pwebhooks[1], + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); + /* Test collective pending webhook lookup */ + TEST_RET_ON_FAIL (test_lookup_pending_webhooks (&cls->instance, + 2, + cls->pwebhooks)); /* Test pending webhook update */ - cls->pwebhooks[0].pwebhook.next_attempt = GNUNET_TIME_absolute_get (); - TEST_RET_ON_FAIL (test_update_pending_webhook (&cls->instance, &cls->pwebhooks[0], GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); + TEST_RET_ON_FAIL (test_lookup_future_webhook (&cls->instance, + 1, + &cls->pwebhooks[1])); TEST_RET_ON_FAIL (test_update_pending_webhook (&cls->instance, &cls->pwebhooks[1], GNUNET_DB_STATUS_SUCCESS_NO_RESULTS)); - - /* Test collective pending webhook lookup */ - TEST_RET_ON_FAIL (test_insert_pending_webhook (&cls->instance, - &cls->pwebhooks[1], - GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); - TEST_RET_ON_FAIL (test_lookup_future_webhook (&cls->instance, - 1, - cls->pwebhooks)); - TEST_RET_ON_FAIL (test_lookup_pending_webhooks (&cls->instance, - 2, - cls->pwebhooks)); + // ??? TEST_RET_ON_FAIL (test_lookup_all_webhooks (&cls->instance, 2, cls->pwebhooks)); + uint64_t webhook_pending_serial0 = get_pending_serial (&cls->instance, + &cls->pwebhooks[0]); + uint64_t webhook_pending_serial1 = get_pending_serial (&cls->instance, + &cls->pwebhooks[1]); + /* Test webhook deletion */ - TEST_RET_ON_FAIL (test_delete_pending_webhook (&cls->pwebhooks[1], + TEST_RET_ON_FAIL (test_delete_pending_webhook (webhook_pending_serial1, GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); /* Test double deletion fails */ - TEST_RET_ON_FAIL (test_delete_pending_webhook (&cls->pwebhooks[1], + TEST_RET_ON_FAIL (test_delete_pending_webhook (webhook_pending_serial1, GNUNET_DB_STATUS_SUCCESS_NO_RESULTS)); - TEST_RET_ON_FAIL (test_delete_pending_webhook (&cls->pwebhooks[0], + TEST_RET_ON_FAIL (test_delete_pending_webhook (webhook_pending_serial0, GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); TEST_RET_ON_FAIL (test_lookup_all_webhooks (&cls->instance, 0, @@ -8323,7 +7093,6 @@ run_tests (void) TEST_RET_ON_FAIL (test_orders ()); TEST_RET_ON_FAIL (test_deposits ()); TEST_RET_ON_FAIL (test_transfers ()); - TEST_RET_ON_FAIL (test_tips ()); TEST_RET_ON_FAIL (test_refunds ()); TEST_RET_ON_FAIL (test_lookup_orders_all_filters ()); TEST_RET_ON_FAIL (test_kyc ()); |