summaryrefslogtreecommitdiff
path: root/src/backenddb
diff options
context:
space:
mode:
authorJonathan Buchanan <jonathan.russ.buchanan@gmail.com>2020-05-24 03:17:06 -0400
committerJonathan Buchanan <jonathan.russ.buchanan@gmail.com>2020-05-24 03:17:06 -0400
commit892dd11795f7a646cf8a06dd50672c23f555e470 (patch)
tree457e51f84291af88e48785e9da733a9ead4f5d96 /src/backenddb
parent7c355636735d989ee5a60f855f6f64a6b6fe50d2 (diff)
downloadmerchant-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.c549
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);