diff --git a/tests/include/test/helpers.h b/tests/include/test/helpers.h index ce8a1e285..8b56d3ad9 100644 --- a/tests/include/test/helpers.h +++ b/tests/include/test/helpers.h @@ -49,9 +49,75 @@ #include #include +typedef enum +{ + MBEDTLS_TEST_RESULT_SUCCESS = 0, + MBEDTLS_TEST_RESULT_FAILED, + MBEDTLS_TEST_RESULT_SKIPPED +} mbedtls_test_result_t; + +typedef struct +{ + mbedtls_test_result_t result; + const char *test; + const char *filename; + int line_no; + unsigned long step; +} +mbedtls_test_info_t; +extern mbedtls_test_info_t mbedtls_test_info; + int mbedtls_test_platform_setup( void ); void mbedtls_test_platform_teardown( void ); +/** + * \brief Record the current test case as a failure. + * + * This function can be called directly however it is usually + * called via macros such as TEST_ASSERT, TEST_EQUAL, + * PSA_ASSERT, etc... + * + * \note If the test case was already marked as failed, calling + * `mbedtls_test_fail( )` again will not overwrite any + * previous information about the failure. + * + * \param test Description of the failure or assertion that failed. This + * MUST be a string literal. + * \param line_no Line number where the failure originated. + * \param filename Filename where the failure originated. + */ +void mbedtls_test_fail( const char *test, int line_no, const char* filename ); + +/** + * \brief Record the current test case as skipped. + * + * This function can be called directly however it is usually + * called via the TEST_ASSUME macro. + * + * \param test Description of the assumption that caused the test case to + * be skipped. This MUST be a string literal. + * \param line_no Line number where the test case was skipped. + * \param filename Filename where the test case was skipped. + */ +void mbedtls_test_skip( const char *test, int line_no, const char* filename ); + +/** + * \brief Set the test step number for failure reports. + * + * Call this function to display "step NNN" in addition to the + * line number and file name if a test fails. Typically the "step + * number" is the index of a for loop but it can be whatever you + * want. + * + * \param step The step number to report. + */ +void mbedtls_test_set_step( unsigned long step ); + +/** + * \brief Reset mbedtls_test_info to a ready/starting state. + */ +void mbedtls_test_info_reset( void ); + /** * \brief This function decodes the hexadecimal representation of * data. diff --git a/tests/src/helpers.c b/tests/src/helpers.c index a18f1d4b8..e323275e5 100644 --- a/tests/src/helpers.c +++ b/tests/src/helpers.c @@ -44,6 +44,8 @@ static param_failed_ctx_t param_failed_ctx; static mbedtls_platform_context platform_ctx; #endif +mbedtls_test_info_t mbedtls_test_info; + /*----------------------------------------------------------------------------*/ /* Helper Functions */ @@ -77,6 +79,42 @@ static int ascii2uc(const char c, unsigned char *uc) return( 0 ); } +void mbedtls_test_fail( const char *test, int line_no, const char* filename ) +{ + if( mbedtls_test_info.result == MBEDTLS_TEST_RESULT_FAILED ) + { + /* We've already recorded the test as having failed. Don't + * overwrite any previous information about the failure. */ + return; + } + mbedtls_test_info.result = MBEDTLS_TEST_RESULT_FAILED; + mbedtls_test_info.test = test; + mbedtls_test_info.line_no = line_no; + mbedtls_test_info.filename = filename; +} + +void mbedtls_test_skip( const char *test, int line_no, const char* filename ) +{ + mbedtls_test_info.result = MBEDTLS_TEST_RESULT_SKIPPED; + mbedtls_test_info.test = test; + mbedtls_test_info.line_no = line_no; + mbedtls_test_info.filename = filename; +} + +void mbedtls_test_set_step( unsigned long step ) +{ + mbedtls_test_info.step = step; +} + +void mbedtls_test_info_reset( void ) +{ + mbedtls_test_info.result = MBEDTLS_TEST_RESULT_SUCCESS; + mbedtls_test_info.step = (unsigned long)( -1 ); + mbedtls_test_info.test = 0; + mbedtls_test_info.line_no = 0; + mbedtls_test_info.filename = 0; +} + int mbedtls_test_unhexify( unsigned char *obuf, size_t obufmax, const char *ibuf, diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function index 1dc672153..9762d414d 100644 --- a/tests/suites/helpers.function +++ b/tests/suites/helpers.function @@ -108,7 +108,7 @@ typedef struct data_tag do { \ if( ! (TEST) ) \ { \ - test_fail( #TEST, __LINE__, __FILE__ ); \ + mbedtls_test_fail( #TEST, __LINE__, __FILE__ ); \ goto exit; \ } \ } while( 0 ) @@ -201,13 +201,13 @@ typedef struct data_tag * * \param TEST The test expression to be tested. */ -#define TEST_ASSUME( TEST ) \ - do { \ - if( ! (TEST) ) \ - { \ - test_skip( #TEST, __LINE__, __FILE__ ); \ - goto exit; \ - } \ +#define TEST_ASSUME( TEST ) \ + do { \ + if( ! (TEST) ) \ + { \ + mbedtls_test_skip( #TEST, __LINE__, __FILE__ ); \ + goto exit; \ + } \ } while( 0 ) #if defined(MBEDTLS_CHECK_PARAMS) && !defined(MBEDTLS_PARAM_FAILED_ALT) @@ -237,7 +237,7 @@ typedef struct data_tag if( ( ( TEST ) != ( PARAM_ERR_VALUE ) ) || \ ( mbedtls_test_param_failed_check_expected_call( ) != 0 ) ) \ { \ - test_fail( #TEST, __LINE__, __FILE__ ); \ + mbedtls_test_fail( #TEST, __LINE__, __FILE__ ); \ goto exit; \ } \ mbedtls_test_param_failed_check_expected_call( ); \ @@ -270,7 +270,7 @@ typedef struct data_tag if( setjmp( mbedtls_test_param_failed_get_state_buf( ) ) == 0 ) \ { \ TEST; \ - test_fail( #TEST, __LINE__, __FILE__ ); \ + mbedtls_test_fail( #TEST, __LINE__, __FILE__ ); \ goto exit; \ } \ mbedtls_test_param_failed_reset_state( ); \ @@ -346,24 +346,6 @@ typedef struct data_tag /*----------------------------------------------------------------------------*/ /* Global variables */ -typedef enum -{ - TEST_RESULT_SUCCESS = 0, - TEST_RESULT_FAILED, - TEST_RESULT_SKIPPED -} test_result_t; - -typedef struct -{ - test_result_t result; - const char *test; - const char *filename; - int line_no; - unsigned long step; -} -test_info_t; -static test_info_t test_info; - #if defined(MBEDTLS_CHECK_PARAMS) jmp_buf jmp_tmp; #endif @@ -386,41 +368,6 @@ jmp_buf jmp_tmp; /*----------------------------------------------------------------------------*/ /* Helper Functions */ -/** Set the test step number for failure reports. - * - * Call this function to display "step NNN" in addition to the line number - * and file name if a test fails. Typically the "step number" is the index - * of a for loop but it can be whatever you want. - * - * \param step The step number to report. - */ -void test_set_step( unsigned long step ) -{ - test_info.step = step; -} - -void test_fail( const char *test, int line_no, const char* filename ) -{ - if( test_info.result == TEST_RESULT_FAILED ) - { - /* We've already recorded the test as having failed. Don't - * overwrite any previous information about the failure. */ - return; - } - test_info.result = TEST_RESULT_FAILED; - test_info.test = test; - test_info.line_no = line_no; - test_info.filename = filename; -} - -void test_skip( const char *test, int line_no, const char* filename ) -{ - test_info.result = TEST_RESULT_SKIPPED; - test_info.test = test; - test_info.line_no = line_no; - test_info.filename = filename; -} - #if defined(MBEDTLS_PSA_CRYPTO_C) /** Check that no PSA Crypto key slots are in use. * @@ -435,7 +382,7 @@ int test_fail_if_psa_leaking( int line_no, const char *filename ) return 0; else { - test_fail( msg, line_no, filename ); + mbedtls_test_fail( msg, line_no, filename ); return 1; } } diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function index 872a3a43a..3138c3365 100644 --- a/tests/suites/host_test.function +++ b/tests/suites/host_test.function @@ -428,15 +428,15 @@ static void write_outcome_entry( FILE *outcome_file, * \param unmet_dependencies The array of unmet dependencies. * \param missing_unmet_dependencies Non-zero if there was a problem tracking * all unmet dependencies, 0 otherwise. - * \param ret The test dispatch status (DISPATCH_xxx). - * \param test_info A pointer to the test info structure. + * \param ret The test dispatch status (DISPATCH_xxx). + * \param mbedtls_test_info A pointer to the test info structure. */ static void write_outcome_result( FILE *outcome_file, size_t unmet_dep_count, int unmet_dependencies[], int missing_unmet_dependencies, int ret, - const test_info_t *info ) + const mbedtls_test_info_t *info ) { if( outcome_file == NULL ) return; @@ -462,10 +462,10 @@ static void write_outcome_result( FILE *outcome_file, } switch( info->result ) { - case TEST_RESULT_SUCCESS: + case MBEDTLS_TEST_RESULT_SUCCESS: mbedtls_fprintf( outcome_file, "PASS;" ); break; - case TEST_RESULT_SKIPPED: + case MBEDTLS_TEST_RESULT_SKIPPED: mbedtls_fprintf( outcome_file, "SKIP;Runtime skip" ); break; default: @@ -601,7 +601,7 @@ int execute_tests( int argc , const char ** argv ) } /* Initialize the struct that holds information about the last test */ - memset( &test_info, 0, sizeof( test_info ) ); + mbedtls_test_info_reset( ); /* Now begin to execute the tests in the testfiles */ for ( testfile_index = 0; @@ -638,7 +638,8 @@ int execute_tests( int argc , const char ** argv ) if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 ) break; mbedtls_fprintf( stdout, "%s%.66s", - test_info.result == TEST_RESULT_FAILED ? "\n" : "", buf ); + mbedtls_test_info.result == MBEDTLS_TEST_RESULT_FAILED ? + "\n" : "", buf ); mbedtls_fprintf( stdout, " " ); for( i = strlen( buf ) + 1; i < 67; i++ ) mbedtls_fprintf( stdout, "." ); @@ -682,8 +683,7 @@ int execute_tests( int argc , const char ** argv ) // If there are no unmet dependencies execute the test if( unmet_dep_count == 0 ) { - test_info.result = TEST_RESULT_SUCCESS; - test_info.step = (unsigned long)( -1 ); + mbedtls_test_info_reset( ); #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) /* Suppress all output from the library unless we're verbose @@ -723,7 +723,7 @@ int execute_tests( int argc , const char ** argv ) write_outcome_result( outcome_file, unmet_dep_count, unmet_dependencies, missing_unmet_dependencies, - ret, &test_info ); + ret, &mbedtls_test_info ); if( unmet_dep_count > 0 || ret == DISPATCH_UNSUPPORTED_SUITE ) { total_skipped++; @@ -753,11 +753,11 @@ int execute_tests( int argc , const char ** argv ) } else if( ret == DISPATCH_TEST_SUCCESS ) { - if( test_info.result == TEST_RESULT_SUCCESS ) + if( mbedtls_test_info.result == MBEDTLS_TEST_RESULT_SUCCESS ) { mbedtls_fprintf( stdout, "PASS\n" ); } - else if( test_info.result == TEST_RESULT_SKIPPED ) + else if( mbedtls_test_info.result == MBEDTLS_TEST_RESULT_SKIPPED ) { mbedtls_fprintf( stdout, "----\n" ); total_skipped++; @@ -767,14 +767,15 @@ int execute_tests( int argc , const char ** argv ) total_errors++; mbedtls_fprintf( stdout, "FAILED\n" ); mbedtls_fprintf( stdout, " %s\n at ", - test_info.test ); - if( test_info.step != (unsigned long)( -1 ) ) + mbedtls_test_info.test ); + if( mbedtls_test_info.step != (unsigned long)( -1 ) ) { mbedtls_fprintf( stdout, "step %lu, ", - test_info.step ); + mbedtls_test_info.step ); } mbedtls_fprintf( stdout, "line %d, %s", - test_info.line_no, test_info.filename ); + mbedtls_test_info.line_no, + mbedtls_test_info.filename ); } fflush( stdout ); } diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function index 98dab3ebb..57395aebb 100644 --- a/tests/suites/main_test.function +++ b/tests/suites/main_test.function @@ -179,10 +179,9 @@ void execute_function_ptr(TestWrapper_t fp, void **params) { /* Unexpected parameter validation error */ mbedtls_test_param_failed_get_location_record( &location_record ); - test_fail( location_record.failure_condition, - location_record.line, - location_record.file ); - test_info.result = TEST_RESULT_FAILED; + mbedtls_test_fail( location_record.failure_condition, + location_record.line, + location_record.file ); } mbedtls_test_param_failed_reset_state( ); diff --git a/tests/suites/target_test.function b/tests/suites/target_test.function index 8354b968c..637a79d5e 100644 --- a/tests/suites/target_test.function +++ b/tests/suites/target_test.function @@ -384,8 +384,7 @@ int execute_tests( int args, const char ** argv ) while ( 1 ) { ret = 0; - test_info.result = TEST_RESULT_SUCCESS; - test_info.step = (unsigned long)( -1 ); + mbedtls_test_info_reset( ); data_len = 0; data = receive_data( &data_len ); @@ -443,7 +442,7 @@ int execute_tests( int args, const char ** argv ) if ( ret ) send_failure( ret ); else - send_status( test_info.result ); + send_status( mbedtls_test_info.result ); } return( 0 ); } diff --git a/tests/suites/test_suite_asn1parse.function b/tests/suites/test_suite_asn1parse.function index 990f343a7..47a43407d 100644 --- a/tests/suites/test_suite_asn1parse.function +++ b/tests/suites/test_suite_asn1parse.function @@ -130,7 +130,7 @@ int get_len_step( const data_t *input, size_t buffer_size, size_t parsed_length; int ret; - test_set_step( buffer_size ); + mbedtls_test_set_step( buffer_size ); /* Allocate a new buffer of exactly the length to parse each time. * This gives memory sanitizers a chance to catch buffer overreads. */ if( buffer_size == 0 ) @@ -198,7 +198,7 @@ static int traverse_callback( void *ctx, int tag, TEST_ASSERT( content > state->input_start ); offset = content - state->input_start; - test_set_step( offset ); + mbedtls_test_set_step( offset ); if( *rest == 0 ) return( RET_TRAVERSE_STOP ); @@ -252,7 +252,7 @@ void parse_prefixes( const data_t *input, */ for( buffer_size = 1; buffer_size <= input->len + 1; buffer_size++ ) { - test_set_step( buffer_size ); + mbedtls_test_set_step( buffer_size ); /* Allocate a new buffer of exactly the length to parse each time. * This gives memory sanitizers a chance to catch buffer overreads. */ ASSERT_ALLOC( buf, buffer_size ); @@ -594,6 +594,7 @@ void get_sequence_of( const data_t *input, int tag, unsigned char *p = input->x; const char *rest = description; unsigned long n; + unsigned int step = 0; TEST_EQUAL( mbedtls_asn1_get_sequence_of( &p, input->x + input->len, &head, tag ), @@ -614,7 +615,7 @@ void get_sequence_of( const data_t *input, int tag, cur = &head; while( *rest ) { - ++test_info.step; + mbedtls_test_set_step( step ); TEST_ASSERT( cur != NULL ); TEST_EQUAL( cur->buf.tag, tag ); n = strtoul( rest, (char **) &rest, 0 ); @@ -625,6 +626,7 @@ void get_sequence_of( const data_t *input, int tag, if( *rest ) ++rest; cur = cur->next; + ++step; } TEST_ASSERT( cur == NULL ); } diff --git a/tests/suites/test_suite_asn1write.function b/tests/suites/test_suite_asn1write.function index 21465c756..882473905 100644 --- a/tests/suites/test_suite_asn1write.function +++ b/tests/suites/test_suite_asn1write.function @@ -15,7 +15,7 @@ typedef struct int generic_write_start_step( generic_write_data_t *data ) { - test_set_step( data->size ); + mbedtls_test_set_step( data->size ); ASSERT_ALLOC( data->output, data->size == 0 ? 1 : data->size ); data->end = data->output + data->size; data->p = data->end; diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 1051e0cae..4cf53ca0b 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -532,7 +532,8 @@ static int exercise_signature_key( mbedtls_svc_key_id_t key, hash_alg = KNOWN_SUPPORTED_HASH_ALG; alg ^= PSA_ALG_ANY_HASH ^ hash_alg; #else - test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ ); + mbedtls_test_fail( "No hash algorithm for hash-and-sign testing", + __LINE__, __FILE__ ); return( 1 ); #endif } @@ -992,7 +993,7 @@ static int exported_key_sanity_check( psa_key_type_t type, size_t bits, mbedtls_snprintf( message, sizeof( message ), "No sanity check for public key type=0x%08lx", (unsigned long) type ); - test_fail( message, __LINE__, __FILE__ ); + mbedtls_test_fail( message, __LINE__, __FILE__ ); (void) p; (void) end; return( 0 ); @@ -1115,8 +1116,8 @@ exit: * asymmetric, also check \p psa_export_public_key. * * If the key fails the tests, this function calls the test framework's - * `test_fail` function and returns false. Otherwise this function returns - * true. Therefore it should be used as follows: + * `mbedtls_test_fail` function and returns false. Otherwise this function + * returns true. Therefore it should be used as follows: * ``` * if( ! exercise_key( ... ) ) goto exit; * ``` @@ -1162,7 +1163,7 @@ static int exercise_key( mbedtls_svc_key_id_t key, mbedtls_snprintf( message, sizeof( message ), "No code to exercise alg=0x%08lx", (unsigned long) alg ); - test_fail( message, __LINE__, __FILE__ ); + mbedtls_test_fail( message, __LINE__, __FILE__ ); ok = 0; } @@ -2677,7 +2678,7 @@ void hash_compute_compare( int alg_arg, data_t *input, /* Compare with corrupted value */ for( i = 0; i < output_length; i++ ) { - test_set_step( i ); + mbedtls_test_set_step( i ); output[i] ^= 1; TEST_EQUAL( psa_hash_compare( alg, input->x, input->len, output, output_length ), @@ -3152,7 +3153,7 @@ void mac_sign( int key_type_arg, ( output_size >= expected_mac->len ? PSA_SUCCESS : PSA_ERROR_BUFFER_TOO_SMALL ); - test_set_step( output_size ); + mbedtls_test_set_step( output_size ); ASSERT_ALLOC( actual_mac, output_size ); /* Calculate the MAC. */ @@ -3238,7 +3239,7 @@ void mac_verify( int key_type_arg, /* Test changing one byte. */ for( size_t i = 0; i < expected_mac->len; i++ ) { - test_set_step( i ); + mbedtls_test_set_step( i ); perturbed_mac[i] ^= 1; PSA_ASSERT( psa_mac_verify_setup( &operation, key, alg ) ); PSA_ASSERT( psa_mac_update( &operation, diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.function b/tests/suites/test_suite_psa_crypto_se_driver_hal.function index cf6ca5e6d..fa516c5d0 100644 --- a/tests/suites/test_suite_psa_crypto_se_driver_hal.function +++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.function @@ -45,7 +45,7 @@ do { \ if( ! (TEST) ) \ { \ - test_fail( #TEST, __LINE__, __FILE__ ); \ + mbedtls_test_fail( #TEST, __LINE__, __FILE__ ); \ return( PSA_ERROR_DETECTED_BY_DRIVER ); \ } \ } while( 0 ) @@ -61,7 +61,7 @@ do { \ if( ! (TEST) ) \ { \ - test_fail( #TEST, __LINE__, __FILE__ ); \ + mbedtls_test_fail( #TEST, __LINE__, __FILE__ ); \ status = PSA_ERROR_DETECTED_BY_DRIVER; \ goto exit; \ } \ @@ -72,10 +72,10 @@ * Run the code \p expr. If this returns \p expected_status, * do nothing. If this returns #PSA_ERROR_DETECTED_BY_DRIVER, * jump directly to the `exit` label. If this returns any other - * status, call test_fail() then jump to `exit`. + * status, call mbedtls_test_fail() then jump to `exit`. * * The special case for #PSA_ERROR_DETECTED_BY_DRIVER is because in this - * case, the test driver code is expected to have called test_fail() + * case, the test driver code is expected to have called mbedtls_test_fail() * already, so we make sure not to overwrite the failure information. */ #define PSA_ASSERT_VIA_DRIVER( expr, expected_status ) \ @@ -85,7 +85,7 @@ goto exit; \ if( PSA_ASSERT_VIA_DRIVER_status != ( expected_status ) ) \ { \ - test_fail( #expr, __LINE__, __FILE__ ); \ + mbedtls_test_fail( #expr, __LINE__, __FILE__ ); \ goto exit; \ } \ } while( 0 ) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index f377ffa99..568e66bb4 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -3609,7 +3609,7 @@ void ssl_decrypt_non_etm_cbc( int cipher_type, int hash_id, int trunc_hmac, */ for( i = block_size; i < buflen; i++ ) { - test_set_step( i ); + mbedtls_test_set_step( i ); /* Restore correct pre-encryption record */ rec = rec_save; @@ -3646,7 +3646,7 @@ void ssl_decrypt_non_etm_cbc( int cipher_type, int hash_id, int trunc_hmac, */ for( i = padlen; i <= pad_max_len; i++ ) { - test_set_step( i ); + mbedtls_test_set_step( i ); /* Restore correct pre-encryption record */ rec = rec_save; @@ -4466,7 +4466,7 @@ void ssl_cf_hmac( int hash ) */ for( max_in_len = 0; max_in_len <= 255 + block_size; max_in_len++ ) { - test_set_step( max_in_len * 10000 ); + mbedtls_test_set_step( max_in_len * 10000 ); /* Use allocated in buffer to catch overreads */ ASSERT_ALLOC( data, max_in_len ); @@ -4474,7 +4474,7 @@ void ssl_cf_hmac( int hash ) min_in_len = max_in_len > 255 ? max_in_len - 255 : 0; for( in_len = min_in_len; in_len <= max_in_len; in_len++ ) { - test_set_step( max_in_len * 10000 + in_len ); + mbedtls_test_set_step( max_in_len * 10000 + in_len ); /* Set up dummy data and add_data */ rec_num++; @@ -4531,7 +4531,7 @@ void ssl_cf_memcpy_offset( int offset_min, int offset_max, int len ) for( secret = offset_min; secret <= (size_t) offset_max; secret++ ) { - test_set_step( (int) secret ); + mbedtls_test_set_step( (int) secret ); TEST_CF_SECRET( &secret, sizeof( secret ) ); mbedtls_ssl_cf_memcpy_offset( dst, src, secret,