From 382fb837bd43ec7de93c8e17404732b4c95ccaca Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 27 Oct 2021 21:59:04 +0200 Subject: -work on testing FTBFS --- src/testing/testing_api_cmd_insert_deposit.c | 67 ++++----------- src/testing/testing_api_cmd_offline_sign_fees.c | 14 +--- src/testing/testing_api_cmd_offline_sign_keys.c | 5 +- src/testing/testing_api_cmd_recoup.c | 24 ++---- src/testing/testing_api_cmd_refresh.c | 107 ++++++++---------------- src/testing/testing_api_cmd_refund.c | 33 +------- src/testing/testing_api_cmd_revoke.c | 15 +--- src/testing/testing_api_cmd_rewind.c | 21 +---- src/testing/testing_api_loop.c | 5 +- 9 files changed, 74 insertions(+), 217 deletions(-) (limited to 'src/testing') diff --git a/src/testing/testing_api_cmd_insert_deposit.c b/src/testing/testing_api_cmd_insert_deposit.c index 0a0d5db2f..222ef758a 100644 --- a/src/testing/testing_api_cmd_insert_deposit.c +++ b/src/testing/testing_api_cmd_insert_deposit.c @@ -136,16 +136,19 @@ insert_deposit_run (void *cls, struct TALER_EXCHANGEDB_Deposit deposit; struct TALER_MerchantPrivateKeyP merchant_priv; struct TALER_EXCHANGEDB_DenominationKeyInformationP issue; - struct TALER_DenominationPublicKey dpk; + struct TALER_DenominationPublicKey dpk = { + .cipher = TALER_DENOMINATION_RSA + }; struct GNUNET_CRYPTO_RsaPrivateKey *denom_priv; struct GNUNET_HashCode hc; // prepare and store issue first. fake_issue (&issue); denom_priv = GNUNET_CRYPTO_rsa_private_key_create (1024); - dpk.rsa_public_key = GNUNET_CRYPTO_rsa_private_key_get_public (denom_priv); - GNUNET_CRYPTO_rsa_public_key_hash (dpk.rsa_public_key, - &issue.properties.denom_hash); + dpk.details.rsa_public_key = GNUNET_CRYPTO_rsa_private_key_get_public ( + denom_priv); + TALER_denom_pub_hash (&dpk, + &issue.properties.denom_hash); if ( (GNUNET_OK != ids->dbc->plugin->start (ids->dbc->plugin->cls, @@ -177,7 +180,7 @@ insert_deposit_run (void *cls, GNUNET_CRYPTO_eddsa_key_get_public (&merchant_priv.eddsa_priv, &deposit.merchant_pub.eddsa_pub); GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, - &deposit.h_contract_terms); + &deposit.h_contract_terms.hash); if ( (GNUNET_OK != TALER_string_to_amount (ids->amount_with_fee, &deposit.amount_with_fee)) || @@ -189,15 +192,17 @@ insert_deposit_run (void *cls, return; } - GNUNET_CRYPTO_rsa_public_key_hash (dpk.rsa_public_key, - &deposit.coin.denom_pub_hash); + TALER_denom_pub_hash (&dpk, + &deposit.coin.denom_pub_hash); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &deposit.coin.coin_pub, sizeof (deposit.coin.coin_pub)); GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &hc); - deposit.coin.denom_sig.rsa_signature = GNUNET_CRYPTO_rsa_sign_fdh (denom_priv, - &hc); + deposit.coin.denom_sig.cipher = TALER_DENOMINATION_RSA; + deposit.coin.denom_sig.details.rsa_signature + = GNUNET_CRYPTO_rsa_sign_fdh (denom_priv, + &hc); { char *str; struct TALER_WireSalt salt; @@ -245,8 +250,8 @@ insert_deposit_run (void *cls, TALER_TESTING_interpreter_fail (is); } - GNUNET_CRYPTO_rsa_signature_free (deposit.coin.denom_sig.rsa_signature); - GNUNET_CRYPTO_rsa_public_key_free (dpk.rsa_public_key); + TALER_denom_sig_free (&deposit.coin.denom_sig); + TALER_denom_pub_free (&dpk); GNUNET_CRYPTO_rsa_private_key_free (denom_priv); json_decref (deposit.receiver_wire_account); @@ -271,43 +276,6 @@ insert_deposit_cleanup (void *cls, } -/** - * Offer "insert-deposit" CMD internal data to other commands. - * - * @param cls closure. - * @param[out] ret result - * @param trait name of the trait. - * @param index index number of the object to offer. - * @return #GNUNET_OK on success. - */ -static int -insert_deposit_traits (void *cls, - const void **ret, - const char *trait, - unsigned int index) -{ - (void) cls; - (void) ret; - (void) trait; - (void) index; - return GNUNET_NO; -} - - -/** - * Make the "insert-deposit" CMD. - * - * @param label command label. - * @param dbc collects database plugin - * @param merchant_name Human-readable name of the merchant. - * @param merchant_account merchant's account name (NOT a payto:// URI) - * @param exchange_timestamp when did the exchange receive the deposit - * @param wire_deadline point in time where the aggregator should have - * wired money to the merchant. - * @param amount_with_fee amount to deposit (inclusive of deposit fee) - * @param deposit_fee deposit fee - * @return the command. - */ struct TALER_TESTING_Command TALER_TESTING_cmd_insert_deposit ( const char *label, @@ -336,8 +304,7 @@ TALER_TESTING_cmd_insert_deposit ( .cls = ids, .label = label, .run = &insert_deposit_run, - .cleanup = &insert_deposit_cleanup, - .traits = &insert_deposit_traits + .cleanup = &insert_deposit_cleanup }; return cmd; diff --git a/src/testing/testing_api_cmd_offline_sign_fees.c b/src/testing/testing_api_cmd_offline_sign_fees.c index 500953202..95f52a00b 100644 --- a/src/testing/testing_api_cmd_offline_sign_fees.c +++ b/src/testing/testing_api_cmd_offline_sign_fees.c @@ -134,7 +134,7 @@ offlinesign_cleanup (void *cls, * @param index index number of the object to offer. * @return #GNUNET_OK on success. */ -static int +static enum GNUNET_GenericReturnValue offlinesign_traits (void *cls, const void **ret, const char *trait, @@ -142,8 +142,7 @@ offlinesign_traits (void *cls, { struct OfflineSignState *ks = cls; struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_process (0, - &ks->offlinesign_proc), + TALER_TESTING_make_trait_process (&ks->offlinesign_proc), TALER_TESTING_trait_end () }; @@ -154,15 +153,6 @@ offlinesign_traits (void *cls, } -/** - * Sign a wire fee. - * - * @param label command label. - * @param config_filename configuration filename. - * @param wire_fee the wire fee to affirm (for the current year) - * @param closing_fee the closing fee to affirm (for the current year) - * @return the command - */ struct TALER_TESTING_Command TALER_TESTING_cmd_exec_offline_sign_fees (const char *label, const char *config_filename, diff --git a/src/testing/testing_api_cmd_offline_sign_keys.c b/src/testing/testing_api_cmd_offline_sign_keys.c index dd6170d90..2c99219b6 100644 --- a/src/testing/testing_api_cmd_offline_sign_keys.c +++ b/src/testing/testing_api_cmd_offline_sign_keys.c @@ -121,7 +121,7 @@ offlinesign_cleanup (void *cls, * @param index index number of the object to offer. * @return #GNUNET_OK on success. */ -static int +static enum GNUNET_GenericReturnValue offlinesign_traits (void *cls, const void **ret, const char *trait, @@ -129,8 +129,7 @@ offlinesign_traits (void *cls, { struct OfflineSignState *ks = cls; struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_process (0, - &ks->offlinesign_proc), + TALER_TESTING_make_trait_process (&ks->offlinesign_proc), TALER_TESTING_trait_end () }; diff --git a/src/testing/testing_api_cmd_recoup.c b/src/testing/testing_api_cmd_recoup.c index 7c4204d9e..d247e36ab 100644 --- a/src/testing/testing_api_cmd_recoup.c +++ b/src/testing/testing_api_cmd_recoup.c @@ -81,7 +81,7 @@ struct RecoupState * @param[out] idx where we set $INDEX * @return #GNUNET_SYSERR if $INDEX is present but not numeric */ -static int +static enum GNUNET_GenericReturnValue parse_coin_reference (const char *coin_reference, char **cref, unsigned int *idx) @@ -198,7 +198,7 @@ recoup_cb (void *cls, } if (GNUNET_OK != TALER_TESTING_get_trait_coin_priv (melt_cmd, - 0, + idx, &dirty_priv)) { GNUNET_break (0); @@ -227,7 +227,6 @@ recoup_cb (void *cls, } if (GNUNET_OK != TALER_TESTING_get_trait_reserve_priv (reserve_cmd, - idx, &reserve_priv)) { GNUNET_break (0); @@ -398,7 +397,7 @@ recoup_cleanup (void *cls, * @param index index number of the object to offer. * @return #GNUNET_OK on success */ -static int +static enum GNUNET_GenericReturnValue recoup_traits (void *cls, const void **ret, const char *trait, @@ -410,10 +409,8 @@ recoup_traits (void *cls, return GNUNET_SYSERR; /* no traits */ { struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_reserve_pub (0, - &ps->reserve_pub), - TALER_TESTING_make_trait_reserve_history (0, - &ps->reserve_history), + TALER_TESTING_make_trait_reserve_pub (&ps->reserve_pub), + TALER_TESTING_make_trait_reserve_history (&ps->reserve_history), TALER_TESTING_trait_end () }; @@ -425,17 +422,6 @@ recoup_traits (void *cls, } -/** - * Make a "recoup" command. - * - * @param label the command label - * @param expected_response_code expected HTTP status code - * @param coin_reference reference to any command which - * offers a coin & reserve private key. - * @param melt_reference NULL if coin was not refreshed - * @param amount how much do we expect to recoup? - * @return the command. - */ struct TALER_TESTING_Command TALER_TESTING_cmd_recoup (const char *label, unsigned int expected_response_code, diff --git a/src/testing/testing_api_cmd_refresh.c b/src/testing/testing_api_cmd_refresh.c index fcf8540c0..21b5be628 100644 --- a/src/testing/testing_api_cmd_refresh.c +++ b/src/testing/testing_api_cmd_refresh.c @@ -93,7 +93,7 @@ struct RefreshMeltState /** * "Crypto data" used in the refresh operation. */ - char *refresh_data; + json_t *refresh_data; /** * Reference to a previous melt command. @@ -136,11 +136,6 @@ struct RefreshMeltState */ struct GNUNET_TIME_Relative total_backoff; - /** - * Number of bytes in @e refresh_data. - */ - size_t refresh_data_length; - /** * Amounts to be generated during melt. */ @@ -419,8 +414,8 @@ reveal_cb (void *cls, } fc->coin_priv = coin_privs[i].coin_priv; fc->blinding_key = coin_privs[i].blinding_key; - fc->sig.rsa_signature = GNUNET_CRYPTO_rsa_signature_dup - (sigs[i].rsa_signature); + TALER_denom_sig_deep_copy (&fc->sig, + &sigs[i]); } if (0 != rrs->total_backoff.rel_value_us) { @@ -468,7 +463,6 @@ refresh_reveal_run (void *cls, } rms = melt_cmd->cls; rrs->rrh = TALER_EXCHANGE_refreshes_reveal (is->exchange, - rms->refresh_data_length, rms->refresh_data, rms->noreveal_index, &reveal_cb, @@ -512,7 +506,7 @@ refresh_reveal_cleanup (void *cls, } for (unsigned int j = 0; j < rrs->num_fresh_coins; j++) - GNUNET_CRYPTO_rsa_signature_free (rrs->fresh_coins[j].sig.rsa_signature); + TALER_denom_sig_free (&rrs->fresh_coins[j].sig); GNUNET_free (rrs->fresh_coins); rrs->fresh_coins = NULL; @@ -641,9 +635,8 @@ link_cb (void *cls, case MHD_HTTP_OK: /* check that number of coins returned matches */ if (GNUNET_OK != - TALER_TESTING_get_trait_uint (reveal_cmd, - 0, - &num_fresh_coins)) + TALER_TESTING_get_trait_array_length (reveal_cmd, + &num_fresh_coins)) { GNUNET_break (0); TALER_TESTING_interpreter_fail (rls->is); @@ -672,11 +665,10 @@ link_cb (void *cls, /* Will point to the pointer inside the cmd state. */ { - const struct TALER_TESTING_FreshCoinData *fc = NULL; + const struct TALER_TESTING_FreshCoinData **fc = NULL; if (GNUNET_OK != TALER_TESTING_get_trait_fresh_coins (reveal_cmd, - 0, &fc)) { GNUNET_break (0); @@ -689,13 +681,13 @@ link_cb (void *cls, { if ( (0 == GNUNET_memcmp (&coin_privs[i], - &fc[j].coin_priv)) && + &(*fc)[j].coin_priv)) && (0 == - GNUNET_CRYPTO_rsa_signature_cmp (fc[i].sig.rsa_signature, - sigs[j].rsa_signature)) && + TALER_denom_sig_cmp (&(*fc)[i].sig, + &sigs[j])) && (0 == - GNUNET_CRYPTO_rsa_public_key_cmp (fc[i].pk->key.rsa_public_key, - pubs[j].rsa_public_key)) ) + TALER_denom_pub_cmp (&(*fc)[i].pk->key, + &pubs[j])) ) { found++; break; @@ -944,7 +936,6 @@ melt_cb (void *cls, TALER_LOG_DEBUG ("Doubling the melt (%s)\n", rms->is->commands[rms->is->ip].label); rms->rmh = TALER_EXCHANGE_melt (rms->is->exchange, - rms->refresh_data_length, rms->refresh_data, &melt_cb, rms); @@ -1063,8 +1054,8 @@ melt_run (void *cls, &fresh_pk->fee_withdraw)); rms->fresh_pks[i] = *fresh_pk; /* Make a deep copy of the RSA key */ - rms->fresh_pks[i].key.rsa_public_key - = GNUNET_CRYPTO_rsa_public_key_dup (fresh_pk->key.rsa_public_key); + TALER_denom_pub_deep_copy (&rms->fresh_pks[i].key, + &fresh_pk->key); } rms->refresh_data = TALER_EXCHANGE_refresh_prepare (rms->melt_priv, @@ -1072,9 +1063,7 @@ melt_run (void *cls, melt_sig, melt_denom_pub, num_fresh_coins, - rms->fresh_pks, - &rms->refresh_data_length); - + rms->fresh_pks); if (NULL == rms->refresh_data) { GNUNET_break (0); @@ -1082,7 +1071,6 @@ melt_run (void *cls, return; } rms->rmh = TALER_EXCHANGE_melt (is->exchange, - rms->refresh_data_length, rms->refresh_data, &melt_cb, rms); @@ -1126,13 +1114,12 @@ melt_cleanup (void *cls, if (NULL != rms->fresh_pks) { for (unsigned int i = 0; i < rms->num_fresh_coins; i++) - GNUNET_CRYPTO_rsa_public_key_free (rms->fresh_pks[i].key.rsa_public_key); + TALER_denom_pub_free (&rms->fresh_pks[i].key); } GNUNET_free (rms->fresh_pks); rms->fresh_pks = NULL; - GNUNET_free (rms->refresh_data); + json_decref (rms->refresh_data); rms->refresh_data = NULL; - rms->refresh_data_length = 0; GNUNET_free (rms->melt_fresh_amounts); GNUNET_free (rms); } @@ -1335,7 +1322,7 @@ TALER_TESTING_cmd_melt_with_retry (struct TALER_TESTING_Command cmd) * @param index index number of the object to offer. * @return #GNUNET_OK on success. */ -static int +static enum GNUNET_GenericReturnValue refresh_reveal_traits (void *cls, const void **ret, const char *trait, @@ -1348,33 +1335,39 @@ refresh_reveal_traits (void *cls, /* Making coin privs traits */ for (unsigned int i = 0; ifresh_coins[i].coin_priv); + traits[i] = TALER_TESTING_make_trait_coin_priv ( + i, + &rrs->fresh_coins[i].coin_priv); /* Making denom pubs traits */ for (unsigned int i = 0; ifresh_coins[i].pk); + = TALER_TESTING_make_trait_denom_pub ( + i, + rrs->fresh_coins[i].pk); /* Making denom sigs traits */ for (unsigned int i = 0; ifresh_coins[i].sig); + = TALER_TESTING_make_trait_denom_sig ( + i, + &rrs->fresh_coins[i].sig); /* blinding key traits */ for (unsigned int i = 0; ifresh_coins[i].blinding_key), + = TALER_TESTING_make_trait_blinding_key ( + i, + &rrs->fresh_coins[i].blinding_key); - /* number of fresh coins */ - traits[(num_coins * 4)] = TALER_TESTING_make_trait_uint - (0, &rrs->num_fresh_coins); + /* number of fresh coins */ + traits[(num_coins * 4)] + = TALER_TESTING_make_trait_array_length ( + &rrs->num_fresh_coins); /* whole array of fresh coins */ traits[(num_coins * 4) + 1] - = TALER_TESTING_make_trait_fresh_coins (0, rrs->fresh_coins), + = TALER_TESTING_make_trait_fresh_coins ( + (const struct TALER_TESTING_FreshCoinData **) &rrs->fresh_coins), /* end of traits */ traits[(num_coins * 4) + 2] = TALER_TESTING_trait_end (); @@ -1386,14 +1379,6 @@ refresh_reveal_traits (void *cls, } -/** - * Create a "refresh reveal" command. - * - * @param label command label. - * @param melt_reference reference to a "refresh melt" command. - * @param expected_response_code expected HTTP response code. - * @return the command. - */ struct TALER_TESTING_Command TALER_TESTING_cmd_refresh_reveal (const char *label, const char *melt_reference, @@ -1418,12 +1403,6 @@ TALER_TESTING_cmd_refresh_reveal (const char *label, } -/** - * Modify a "refresh reveal" command to enable retries. - * - * @param cmd command - * @return modified command. - */ struct TALER_TESTING_Command TALER_TESTING_cmd_refresh_reveal_with_retry (struct TALER_TESTING_Command cmd) { @@ -1436,14 +1415,6 @@ TALER_TESTING_cmd_refresh_reveal_with_retry (struct TALER_TESTING_Command cmd) } -/** - * Create a "refresh link" command. - * - * @param label command label. - * @param reveal_reference reference to a "refresh reveal" CMD. - * @param expected_response_code expected HTTP response code - * @return the "refresh link" command - */ struct TALER_TESTING_Command TALER_TESTING_cmd_refresh_link (const char *label, const char *reveal_reference, @@ -1467,12 +1438,6 @@ TALER_TESTING_cmd_refresh_link (const char *label, } -/** - * Modify a "refresh link" command to enable retries. - * - * @param cmd command - * @return modified command. - */ struct TALER_TESTING_Command TALER_TESTING_cmd_refresh_link_with_retry (struct TALER_TESTING_Command cmd) { diff --git a/src/testing/testing_api_cmd_refund.c b/src/testing/testing_api_cmd_refund.c index 30f257696..c288e9e15 100644 --- a/src/testing/testing_api_cmd_refund.c +++ b/src/testing/testing_api_cmd_refund.c @@ -127,7 +127,7 @@ refund_run (void *cls, const struct TALER_CoinSpendPrivateKeyP *coin_priv; struct TALER_CoinSpendPublicKeyP coin; const json_t *contract_terms; - struct GNUNET_HashCode h_contract_terms; + struct TALER_PrivateContractHash h_contract_terms; struct TALER_Amount refund_amount; const struct TALER_MerchantPrivateKeyP *merchant_priv; const struct TALER_TESTING_Command *coin_cmd; @@ -157,7 +157,6 @@ refund_run (void *cls, } if (GNUNET_OK != TALER_TESTING_get_trait_contract_terms (coin_cmd, - 0, &contract_terms)) { GNUNET_break (0); @@ -183,7 +182,6 @@ refund_run (void *cls, &coin.eddsa_pub); if (GNUNET_OK != TALER_TESTING_get_trait_merchant_priv (coin_cmd, - 0, &merchant_priv)) { GNUNET_break (0); @@ -228,17 +226,6 @@ refund_cleanup (void *cls, } -/** - * Create a "refund" command. - * - * @param label command label. - * @param expected_response_code expected HTTP status code. - * @param refund_amount the amount to ask a refund for. - * @param coin_reference reference to a command that can - * provide a coin to be refunded. - * - * @return the command. - */ struct TALER_TESTING_Command TALER_TESTING_cmd_refund (const char *label, unsigned int expected_response_code, @@ -265,23 +252,9 @@ TALER_TESTING_cmd_refund (const char *label, } -/** - * Create a "refund" command, allow to specify refund transaction - * id. Mainly used to create conflicting requests. - * - * @param label command label. - * @param expected_response_code expected HTTP status code. - * @param refund_amount the amount to ask a refund for. - * @param coin_reference reference to a command that can - * provide a coin to be refunded. - * @param refund_transaction_id transaction id to use - * in the request. - * - * @return the command. - */ struct TALER_TESTING_Command -TALER_TESTING_cmd_refund_with_id - (const char *label, +TALER_TESTING_cmd_refund_with_id ( + const char *label, unsigned int expected_response_code, const char *refund_amount, const char *coin_reference, diff --git a/src/testing/testing_api_cmd_revoke.c b/src/testing/testing_api_cmd_revoke.c index 9f904454e..4522dede1 100644 --- a/src/testing/testing_api_cmd_revoke.c +++ b/src/testing/testing_api_cmd_revoke.c @@ -100,7 +100,7 @@ revoke_cleanup (void *cls, * @param index index number of the object to offer. * @return #GNUNET_OK on success */ -static int +static enum GNUNET_GenericReturnValue revoke_traits (void *cls, const void **ret, const char *trait, @@ -110,8 +110,7 @@ revoke_traits (void *cls, struct TALER_TESTING_Trait traits[] = { /* Needed by the handler which waits the proc' * death and calls the next command */ - TALER_TESTING_make_trait_process (0, - &rs->revoke_proc), + TALER_TESTING_make_trait_process (&rs->revoke_proc), TALER_TESTING_trait_end () }; @@ -183,16 +182,6 @@ revoke_run (void *cls, } -/** - * Make a "revoke" command. - * - * @param label the command label. - * @param expected_response_code expected HTTP status code. - * @param coin_reference reference to a CMD that will offer the - * denomination to revoke. - * @param config_filename configuration file name. - * @return the command. - */ struct TALER_TESTING_Command TALER_TESTING_cmd_revoke (const char *label, unsigned int expected_response_code, diff --git a/src/testing/testing_api_cmd_rewind.c b/src/testing/testing_api_cmd_rewind.c index 9e19773cc..dae456248 100644 --- a/src/testing/testing_api_cmd_rewind.c +++ b/src/testing/testing_api_cmd_rewind.c @@ -46,18 +46,6 @@ struct RewindIpState }; -/** - * Only defined to respect the API. - */ -static void -rewind_ip_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - (void) cls; - (void) cmd; -} - - /** * Seek for the @a target command in @a batch (and rewind to it * if successful). @@ -74,10 +62,10 @@ seek_batch (struct TALER_TESTING_Interpreter *is, const struct TALER_TESTING_Command *target) { unsigned int new_ip; - struct TALER_TESTING_Command *batch; + struct TALER_TESTING_Command **batch; struct TALER_TESTING_Command *current; struct TALER_TESTING_Command *icmd; - const struct TALER_TESTING_Command *match; + struct TALER_TESTING_Command *match; current = TALER_TESTING_cmd_batch_get_current (cmd); GNUNET_assert (GNUNET_OK == @@ -85,7 +73,7 @@ seek_batch (struct TALER_TESTING_Interpreter *is, &batch)); match = NULL; for (new_ip = 0; - NULL != (icmd = &batch[new_ip]); + NULL != (icmd = &(*batch)[new_ip]); new_ip++) { if (current == target) @@ -201,8 +189,7 @@ TALER_TESTING_cmd_rewind_ip (const char *label, struct TALER_TESTING_Command cmd = { .cls = ris, .label = label, - .run = &rewind_ip_run, - .cleanup = &rewind_ip_cleanup + .run = &rewind_ip_run }; return cmd; diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c index ba1555895..0de4230ea 100644 --- a/src/testing/testing_api_loop.c +++ b/src/testing/testing_api_loop.c @@ -289,8 +289,9 @@ do_shutdown (void *cls) for (unsigned int j = 0; NULL != (cmd = &is->commands[j])->label; j++) - cmd->cleanup (cmd->cls, - cmd); + if (NULL != cmd->cleanup) + cmd->cleanup (cmd->cls, + cmd); if (NULL != is->exchange) { -- cgit v1.2.3