diff options
author | Jonathan Buchanan <jonathan.russ.buchanan@gmail.com> | 2020-05-24 03:17:06 -0400 |
---|---|---|
committer | Jonathan Buchanan <jonathan.russ.buchanan@gmail.com> | 2020-05-24 03:17:06 -0400 |
commit | 892dd11795f7a646cf8a06dd50672c23f555e470 (patch) | |
tree | 457e51f84291af88e48785e9da733a9ead4f5d96 /src/backenddb | |
parent | 7c355636735d989ee5a60f855f6f64a6b6fe50d2 (diff) | |
download | merchant-892dd11795f7a646cf8a06dd50672c23f555e470.tar.gz merchant-892dd11795f7a646cf8a06dd50672c23f555e470.tar.bz2 merchant-892dd11795f7a646cf8a06dd50672c23f555e470.zip |
refactored instance test code
Diffstat (limited to 'src/backenddb')
-rw-r--r-- | src/backenddb/test_merchantdb.c | 549 |
1 files changed, 275 insertions, 274 deletions
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c index 5354d8e7..9940c5ea 100644 --- a/src/backenddb/test_merchantdb.c +++ b/src/backenddb/test_merchantdb.c @@ -41,90 +41,55 @@ static struct TALER_MERCHANTDB_Plugin *plugin; return 1; \ } -/** - * Number of instances detected. - */ -static int instance_count; /** - * An array of instance settings found from the lookup method. + * Instance settings along with corresponding accounts */ -static struct TALER_MERCHANTDB_InstanceSettings instances_found[8]; +struct InstanceWithAccounts +{ + /** + * Pointer to the instance settings + */ + const struct TALER_MERCHANTDB_InstanceSettings *instance; -/** - * An array containing the number of accounts of each instance from lookup. - */ -static int instances_accounts_length[8]; + /** + * Length of the array of accounts + */ + unsigned int accounts_length; -/** - * An array containing the array of accounts of each instance from lookup. - */ -static struct TALER_MERCHANTDB_AccountDetails *instances_accounts[8]; + /** + * Pointer to the array of accounts + */ + const struct TALER_MERCHANTDB_AccountDetails *accounts; -static void -copy_instance (struct TALER_MERCHANTDB_InstanceSettings *dest, - const struct TALER_MERCHANTDB_InstanceSettings *src) -{ - dest->id = GNUNET_malloc (sizeof (char) * (strlen (src->id) + 1)); - strcpy (dest->id, - src->id); - dest->name = GNUNET_malloc (sizeof (char) * (strlen (src->name) + 1)); - strcpy (dest->name, - src->name); - dest->address = json_copy (src->address); - dest->jurisdiction = json_copy (src->jurisdiction); - dest->default_max_deposit_fee = src->default_max_deposit_fee; - dest->default_max_wire_fee = src->default_max_wire_fee; - dest->default_wire_fee_amortization = src->default_wire_fee_amortization; - dest->default_wire_transfer_delay = src->default_wire_transfer_delay; - dest->default_pay_delay = src->default_pay_delay; -} +}; -static void -free_instance (struct TALER_MERCHANTDB_InstanceSettings *is) +/** + * Closure for testing instance lookup + */ +struct TestLookupInstances_Closure { - GNUNET_free (is->id); - GNUNET_free (is->name); - json_decref (is->address); - json_decref (is->jurisdiction); -} + /** + * Number of instances to compare to + */ + unsigned int instances_to_cmp_length; + /** + * Pointer to array of instances + */ + const struct InstanceWithAccounts *instances_to_cmp; -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, - unsigned int accounts_length, - const struct TALER_MERCHANTDB_AccountDetails accounts[]) -{ - instance_count += 1; - if (8 >= instance_count) - { - /* Duplicate the instance settings */ - copy_instance (&instances_found[instance_count - 1], - is); - instances_accounts_length[instance_count - 1] = accounts_length; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "CB: %d\n", accounts_length); - instances_accounts[instance_count - 1] = GNUNET_new_array (accounts_length, - struct - TALER_MERCHANTDB_AccountDetails); - for (int i = 0; accounts_length > i; ++i) - { - struct TALER_MERCHANTDB_AccountDetails *dest = - &instances_accounts[instance_count - 1][i]; - dest->h_wire = accounts[i].h_wire; - dest->salt = accounts[i].salt; - dest->payto_uri = GNUNET_malloc (sizeof (char) * (strlen ( - accounts[i].payto_uri) - + 1)); - strcpy (dest->payto_uri, - accounts[i].payto_uri); - dest->active = accounts[i].active; - } - } -} + /** + * Pointer to array of number of matches for each instance + */ + unsigned int *results_matching; + + /** + * Total number of results returned + */ + unsigned int results_length; +}; static int @@ -172,19 +137,62 @@ check_accounts_equal (const struct TALER_MERCHANTDB_AccountDetails *a, } +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, + unsigned int accounts_length, + const struct TALER_MERCHANTDB_AccountDetails accounts[]) +{ + if (cls == NULL) + return; + struct TestLookupInstances_Closure *cmp = cls; + 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) + { + 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 */ + int accounts_matching[accounts_length]; + 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 */ + bool accounts_match = true; + 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; + } +} + + static int test_insert_instance (const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantPrivateKeyP *merchant_priv, const struct TALER_MERCHANTDB_InstanceSettings *is) { - if (0 > plugin->insert_instance (plugin->cls, - merchant_pub, - merchant_priv, - is)) + if (1 != plugin->insert_instance (plugin->cls, + merchant_pub, + merchant_priv, + is)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Instance insertion failed\n"); - plugin->drop_tables (plugin->cls); return 1; } return 0; @@ -192,18 +200,42 @@ test_insert_instance (const struct TALER_MerchantPublicKeyP *merchant_pub, static int -test_lookup_instances (bool active_only) +test_lookup_instances (bool active_only, + unsigned int instances_length, + struct InstanceWithAccounts instances[]) { + struct TestLookupInstances_Closure cls; + cls.instances_to_cmp_length = instances_length; + cls.instances_to_cmp = instances; + unsigned int results_matching[instances_length]; + for (unsigned int i = 0; instances_length > i; ++i) + results_matching[i] = 0; + cls.results_matching = results_matching; + cls.results_length = 0; if (0 > plugin->lookup_instances (plugin->cls, active_only, &lookup_instances_cb, - NULL)) + &cls)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Lookup instances failed\n"); - plugin->drop_tables (plugin->cls); return 1; } + if (instances_length != cls.results_length) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup instances failed: incorrect number of results\n"); + return 1; + } + for (unsigned int i = 0; instances_length > i; ++i) + { + if (1 != cls.results_matching[i]) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup instances failed: mismatched data\n"); + return 1; + } + } return 0; } @@ -212,13 +244,12 @@ static int test_insert_account (const char *instance_id, const struct TALER_MERCHANTDB_AccountDetails *account) { - if (1 > plugin->insert_account (plugin->cls, - instance_id, - account)) + if (1 != plugin->insert_account (plugin->cls, + instance_id, + account)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Insert account failed\n"); - plugin->drop_tables (plugin->cls); return 1; } return 0; @@ -226,223 +257,186 @@ test_insert_account (const char *instance_id, /** + * Closure for instance tests + */ +struct TestInstances_Closure +{ + /** + * The instance settings + */ + struct TALER_MERCHANTDB_InstanceSettings is; + + /** + * The instance public key + */ + struct TALER_MerchantPublicKeyP merchant_pub; + + /** + * The instance private key + */ + struct TALER_MerchantPrivateKeyP merchant_priv; + + /** + * The accounts array + */ + struct TALER_MERCHANTDB_AccountDetails accounts[2]; +}; + + +/** + * Sets up the data structures used in the instance tests + */ +static void +pre_test_instances (struct TestInstances_Closure *cls) +{ + GNUNET_CRYPTO_eddsa_key_create (&cls->merchant_priv.eddsa_priv); + GNUNET_CRYPTO_eddsa_key_get_public (&cls->merchant_priv.eddsa_priv, + &cls->merchant_pub.eddsa_pub); + cls->is.id = "test_inst"; + cls->is.name = "Test"; + cls->is.address = json_array (); + GNUNET_assert (NULL != cls->is.address); + GNUNET_assert (0 == json_array_append (cls->is.address, + json_string ("123 Example St"))); + cls->is.jurisdiction = json_array (); + GNUNET_assert (NULL != cls->is.jurisdiction); + GNUNET_assert (0 == json_array_append (cls->is.jurisdiction, + json_string ("Ohio"))); + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("EUR:1200.40", + &cls->is.default_max_deposit_fee)); + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("EUR:1200.40", + &cls->is.default_max_wire_fee)); + cls->is.default_wire_fee_amortization = 1; + cls->is.default_wire_transfer_delay = GNUNET_TIME_relative_get_minute_ (); + cls->is.default_pay_delay = GNUNET_TIME_relative_get_second_ (); + + GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, + &cls->accounts[0].h_wire); + GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, + &cls->accounts[0].salt); + cls->accounts[0].payto_uri = "payto://x-taler-bank/bank.demo.taler.net/4"; + cls->accounts[0].active = true; + + GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, + &cls->accounts[1].h_wire); + GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, + &cls->accounts[1].salt); + cls->accounts[1].payto_uri = "payto://other-bank/bank.demo.other.net/4"; + cls->accounts[1].active = true; +} + + +/** + * Handles all teardown after testing + */ +static void +post_test_instances (struct TestInstances_Closure *cls) +{ + json_decref (cls->is.address); + json_decref (cls->is.jurisdiction); +} + + +/** * Function that tests instances. * * @param cls closure with config */ static int -test_instances (void *cls) +run_test_instances (struct TestInstances_Closure *cls) { - /* Test making an instance */ - struct TALER_MerchantPublicKeyP merchant_pub; - struct TALER_MerchantPrivateKeyP merchant_priv; - GNUNET_CRYPTO_eddsa_key_create (&merchant_priv.eddsa_priv); - GNUNET_CRYPTO_eddsa_key_get_public (&merchant_priv.eddsa_priv, - &merchant_pub.eddsa_pub); - struct TALER_MERCHANTDB_InstanceSettings is; - is.id = "test_inst"; - is.name = "Test"; - is.address = json_array (); - json_array_append (is.address, - json_string ("123 Example St")); - is.jurisdiction = json_array (); - json_array_append (is.jurisdiction, - json_string ("Ohio")); - TALER_string_to_amount ("EUR:1200.40", - &is.default_max_deposit_fee); - TALER_string_to_amount ("EUR:1200.40", - &is.default_max_wire_fee); - is.default_wire_fee_amortization = 1; - is.default_wire_transfer_delay = GNUNET_TIME_relative_get_minute_ (); - is.default_pay_delay = GNUNET_TIME_relative_get_second_ (); - TEST_RET_ON_FAIL (test_insert_instance (&merchant_pub, - &merchant_priv, - &is)); + /* Test inserting an instance */ + TEST_RET_ON_FAIL (test_insert_instance (&cls->merchant_pub, + &cls->merchant_priv, + &cls->is)); /* Test lookup instances- is our new instance there? */ - instance_count = 0; - TEST_RET_ON_FAIL (test_lookup_instances (false)); - if (instance_count != 1) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Instance count doesn't match number of instances inserted\n"); - plugin->drop_tables (plugin->cls); - return 1; - } - if (0 != check_instances_equal (&is, - &instances_found[0])) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup instance failed: incorrect instance returned\n"); - plugin->drop_tables (plugin->cls); - return 1; - } - free_instance (&instances_found[0]); - if (0 != instances_accounts_length[0]) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup instance failed: incorrect accounts returned\n"); - plugin->drop_tables (plugin->cls); - return 1; - } + struct InstanceWithAccounts instances[1]; + instances[0].accounts_length = 0; + instances[0].accounts = NULL; + instances[0].instance = &cls->is; + TEST_RET_ON_FAIL (test_lookup_instances (false, + 1, + instances)); /* Test update instance */ - is.name = "Test - updated"; + cls->is.name = "Test - updated"; if (0 > plugin->update_instance (plugin->cls, - &is)) + &cls->is)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Update instance failed\n"); - plugin->drop_tables (plugin->cls); - return 1; - } - instance_count = 0; - TEST_RET_ON_FAIL (test_lookup_instances (false)); - if (1 != instance_count) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Update instance failed: Instance count doesn't match number of instances inserted/updated\n"); - plugin->drop_tables (plugin->cls); return 1; } - if (0 != check_instances_equal (&is, - &instances_found[0])) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Update instance failed: result from lookup doesn't match\n"); - plugin->drop_tables (plugin->cls); - return 1; - } - free_instance (&instances_found[0]); + TEST_RET_ON_FAIL (test_lookup_instances (false, + 1, + instances)); /* Test account creation */ - struct TALER_MERCHANTDB_AccountDetails account; - GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, - &account.h_wire); - GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, - &account.salt); - account.payto_uri = "payto://x-taler-bank/bank.demo.taler.net/4"; - account.active = true; - TEST_RET_ON_FAIL (test_insert_account ("test_inst", &account)); + TEST_RET_ON_FAIL (test_insert_account ("test_inst", &cls->accounts[0])); /* Test accounts from instance lookup */ - instance_count = 0; - TEST_RET_ON_FAIL (test_lookup_instances (false)); - free_instance (&instances_found[0]); - if (1 != instances_accounts_length[0]) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup instance failed: incorrect number of accounts returned\n"); - plugin->drop_tables (plugin->cls); - return 1; - } - if (0 != check_accounts_equal (&account, - &instances_accounts[0][0])) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup instance failed: incorrect accounts returned\n"); - plugin->drop_tables (plugin->cls); - return 1; - } - GNUNET_free (instances_accounts[0][0].payto_uri); + instances[0].accounts_length = 1; + instances[0].accounts = cls->accounts; + TEST_RET_ON_FAIL (test_lookup_instances (false, + 1, + instances)); /* Test account inactivation */ if (0 > plugin->inactivate_account (plugin->cls, - &account.h_wire)) + &cls->accounts[0].h_wire)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Inactivate account failed\n"); - plugin->drop_tables (plugin->cls); return 1; } - account.active = false; - instance_count = 0; - TEST_RET_ON_FAIL (test_lookup_instances (false)); - free_instance (&instances_found[0]); - if (1 != instances_accounts_length[0]) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup instance failed: incorrect number of accounts returned\n"); - plugin->drop_tables (plugin->cls); - return 1; - } - if (0 != check_accounts_equal (&account, - &instances_accounts[0][0])) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup instance failed: incorrect accounts returned\n"); - plugin->drop_tables (plugin->cls); - return 1; - } - GNUNET_free (instances_accounts[0][0].payto_uri); + cls->accounts[0].active = false; + TEST_RET_ON_FAIL (test_lookup_instances (false, + 1, + instances)); /* Test multiple accounts */ - /* This fails currently */ - /*struct TALER_MERCHANTDB_AccountDetails account1; - GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, - &account1.h_wire); - GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, - &account1.salt); - account1.payto_uri = "payto://other-bank/bank.demo.taler.net/4"; - account1.active = true; - TEST_RET_ON_FAIL (test_insert_account ("test_inst", &account1)); - instance_count = 0; - TEST_RET_ON_FAIL (test_lookup_instances (false)); - free_instance (&instances_found[0]); - if (2 != instances_accounts_length[0]) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup instance failed: incorrect number of accounts returned %d\n", instances_accounts_length[0]); - //plugin->drop_tables (plugin->cls); - return 1; - }*//* Test instance private key deletion */if (0 > plugin->delete_instance_private_key (plugin->cls, + + /* Test instance private key deletion */ + if (0 > plugin->delete_instance_private_key (plugin->cls, "test_inst")) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Delete instance private key failed\n"); - plugin->drop_tables (plugin->cls); - return 1; - } - instance_count = 0; - TEST_RET_ON_FAIL (test_lookup_instances (true)); - if (0 != instance_count) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup instances failed: instance without private key not excluded when only counting active instances\n"); - plugin->drop_tables (plugin->cls); - return 1; - } - instance_count = 0; - TEST_RET_ON_FAIL (test_lookup_instances (false)); - if (1 != instance_count) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup instances failed: instance without private key not included when counting all instances\n"); - plugin->drop_tables (plugin->cls); return 1; } - /* Delete the instance we just copied */ - free_instance (&instances_found[0]); + TEST_RET_ON_FAIL (test_lookup_instances (true, + 0, + NULL)); + TEST_RET_ON_FAIL (test_lookup_instances (false, + 1, + instances)); /* Test instance deletion */ - /* This test currently FAILS */ - /*instance_count = 0; - if (0 > plugin->purge_instance (plugin->cls, - "test_inst")) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Purge instance failed\n"); - result = 1; - plugin->drop_tables (plugin->cls); - return; - }*/json_decref (is.address); - json_decref (is.jurisdiction); return 0; } /** + * Function that tests instances. + * + * @param cls closure with config + */ +static int +test_instances (void *cls) +{ + struct TestInstances_Closure test_cls; + pre_test_instances (&test_cls); + int test_result = run_test_instances (&test_cls); + post_test_instances (&test_cls); + return test_result; +} + + +/** * Number of products detected. */ static int product_count; @@ -1024,6 +1018,28 @@ test_orders (void *cls) /** + * Function that runs all tests and returns upon error. + */ +static int +run_tests (void *cls) +{ + /* Test instances */ + if (0 != test_instances (cls)) + return 1; + + /* Test products */ + if (0 != test_products (cls)) + return 1; + + /* Test orders */ + if (0 != test_orders (cls)) + return 1; + + return 0; +} + + +/** * Main function that will be run by the scheduler. * * @param cls closure with config @@ -1044,21 +1060,7 @@ run (void *cls) /* Run the preflight */ plugin->preflight (plugin->cls); - /* TODO: break reused code into functions */ - /* Test instances */ - result = test_instances (cls); - if (0 != result) - return; - - /* Test products */ - result = test_products (cls); - if (0 != result) - return; - - /* Test orders */ - result = test_orders (cls); - if (0 != result) - return; + result = run_tests (cls); /* Test dropping tables */ if (GNUNET_OK != plugin->drop_tables (plugin->cls)) @@ -1079,7 +1081,6 @@ run (void *cls) return; } - result = 0; GNUNET_break (GNUNET_OK == plugin->drop_tables (plugin->cls)); TALER_MERCHANTDB_plugin_unload (plugin); |