mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-23 03:25:38 +01:00
Timing unit tests: more protection against infinite loops
If timing_timer_simple fails because it detects that timers are likely to never expire (e.g. going backward or not incrementing), skip all tests that rely on timers.
This commit is contained in:
parent
078f1a1512
commit
2a26d620fb
@ -38,6 +38,14 @@ static int expected_delay_status( uint32_t int_ms, uint32_t fin_ms,
|
|||||||
0 );
|
0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Some conditions in timing_timer_simple suggest that timers are unreliable.
|
||||||
|
Most other test cases rely on timers to terminate, and could loop
|
||||||
|
indefinitely if timers are too broken. So if timing_timer_simple detected a
|
||||||
|
timer that risks not terminating (going backwards, or not reaching the
|
||||||
|
desired count in the alloted clock cycles), set this flag to immediately
|
||||||
|
fail those other tests without running any timers. */
|
||||||
|
static int timers_are_badly_broken = 0;
|
||||||
|
|
||||||
/* END_HEADER */
|
/* END_HEADER */
|
||||||
|
|
||||||
/* BEGIN_DEPENDENCIES
|
/* BEGIN_DEPENDENCIES
|
||||||
@ -73,6 +81,15 @@ void timing_timer_simple( )
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
if( iterations >= TIMING_SHORT_TEST_ITERATIONS_MAX ||
|
||||||
|
new_millis < millis )
|
||||||
|
{
|
||||||
|
/* The timer was very unreliable: it didn't increment and the loop ran
|
||||||
|
out, or it went backwards. Other tests that use timers might go
|
||||||
|
into an infinite loop, so we'll skip them. */
|
||||||
|
timers_are_badly_broken = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* No cleanup needed, but show some diagnostic iterations, because timing
|
/* No cleanup needed, but show some diagnostic iterations, because timing
|
||||||
problems can be hard to reproduce. */
|
problems can be hard to reproduce. */
|
||||||
mbedtls_fprintf( stdout, " Finished with millis=%lu new_millis=%lu get(timer)<=%lu iterations=%lu\n",
|
mbedtls_fprintf( stdout, " Finished with millis=%lu new_millis=%lu get(timer)<=%lu iterations=%lu\n",
|
||||||
@ -87,6 +104,11 @@ void timing_timer_reset( )
|
|||||||
struct mbedtls_timing_hr_time timer;
|
struct mbedtls_timing_hr_time timer;
|
||||||
unsigned long millis = 0;
|
unsigned long millis = 0;
|
||||||
unsigned long iterations = 0;
|
unsigned long iterations = 0;
|
||||||
|
|
||||||
|
/* Skip this test if it looks like timers don't work at all, to avoid an
|
||||||
|
infinite loop below. */
|
||||||
|
TEST_ASSERT( !timers_are_badly_broken );
|
||||||
|
|
||||||
/* Start the timer. Timers are always reset to 0. */
|
/* Start the timer. Timers are always reset to 0. */
|
||||||
TEST_ASSERT( mbedtls_timing_get_timer( &timer, 1 ) == 0 );
|
TEST_ASSERT( mbedtls_timing_get_timer( &timer, 1 ) == 0 );
|
||||||
/* Busy-wait loop for a few milliseconds */
|
/* Busy-wait loop for a few milliseconds */
|
||||||
@ -107,6 +129,7 @@ void timing_timer_reset( )
|
|||||||
exit:
|
exit:
|
||||||
/* No cleanup needed, but show some diagnostic information, because timing
|
/* No cleanup needed, but show some diagnostic information, because timing
|
||||||
problems can be hard to reproduce. */
|
problems can be hard to reproduce. */
|
||||||
|
if( !timers_are_badly_broken )
|
||||||
mbedtls_fprintf( stdout, " Finished with millis=%lu get(timer)<=%lu iterations=%lu\n",
|
mbedtls_fprintf( stdout, " Finished with millis=%lu get(timer)<=%lu iterations=%lu\n",
|
||||||
millis, mbedtls_timing_get_timer( &timer, 0 ),
|
millis, mbedtls_timing_get_timer( &timer, 0 ),
|
||||||
iterations );
|
iterations );
|
||||||
@ -117,7 +140,11 @@ exit:
|
|||||||
void timing_two_timers( int delta )
|
void timing_two_timers( int delta )
|
||||||
{
|
{
|
||||||
struct mbedtls_timing_hr_time timer1, timer2;
|
struct mbedtls_timing_hr_time timer1, timer2;
|
||||||
unsigned long millis1, millis2;
|
unsigned long millis1 = 0, millis2 = 0;
|
||||||
|
|
||||||
|
/* Skip this test if it looks like timers don't work at all, to avoid an
|
||||||
|
infinite loop below. */
|
||||||
|
TEST_ASSERT( !timers_are_badly_broken );
|
||||||
|
|
||||||
/* Start the first timer and wait for a short time. */
|
/* Start the first timer and wait for a short time. */
|
||||||
(void) mbedtls_timing_get_timer( &timer1, 1 );
|
(void) mbedtls_timing_get_timer( &timer1, 1 );
|
||||||
@ -153,6 +180,7 @@ void timing_two_timers( int delta )
|
|||||||
exit:
|
exit:
|
||||||
/* No cleanup needed, but show some diagnostic iterations, because timing
|
/* No cleanup needed, but show some diagnostic iterations, because timing
|
||||||
problems can be hard to reproduce. */
|
problems can be hard to reproduce. */
|
||||||
|
if( !timers_are_badly_broken )
|
||||||
mbedtls_fprintf( stdout, " Finished with millis1=%lu get(timer1)<=%lu millis2=%lu get(timer2)<=%lu\n",
|
mbedtls_fprintf( stdout, " Finished with millis1=%lu get(timer1)<=%lu millis2=%lu get(timer2)<=%lu\n",
|
||||||
millis1, mbedtls_timing_get_timer( &timer1, 0 ),
|
millis1, mbedtls_timing_get_timer( &timer1, 0 ),
|
||||||
millis2, mbedtls_timing_get_timer( &timer2, 0 ) );
|
millis2, mbedtls_timing_get_timer( &timer2, 0 ) );
|
||||||
@ -177,6 +205,10 @@ void timing_alarm( int seconds )
|
|||||||
TIMING_ALARM_0_DELAY_MS );
|
TIMING_ALARM_0_DELAY_MS );
|
||||||
unsigned long iterations = 0;
|
unsigned long iterations = 0;
|
||||||
|
|
||||||
|
/* Skip this test if it looks like timers don't work at all, to avoid an
|
||||||
|
infinite loop below. */
|
||||||
|
TEST_ASSERT( !timers_are_badly_broken );
|
||||||
|
|
||||||
/* Set an alarm and count how long it takes with a timer. */
|
/* Set an alarm and count how long it takes with a timer. */
|
||||||
(void) mbedtls_timing_get_timer( &timer, 1 );
|
(void) mbedtls_timing_get_timer( &timer, 1 );
|
||||||
mbedtls_set_alarm( seconds );
|
mbedtls_set_alarm( seconds );
|
||||||
@ -209,6 +241,7 @@ void timing_alarm( int seconds )
|
|||||||
exit:
|
exit:
|
||||||
/* Show some diagnostic iterations, because timing
|
/* Show some diagnostic iterations, because timing
|
||||||
problems can be hard to reproduce. */
|
problems can be hard to reproduce. */
|
||||||
|
if( !timers_are_badly_broken )
|
||||||
mbedtls_fprintf( stdout, " Finished with alarmed=%d millis=%lu get(timer)<=%lu iterations=%lu\n",
|
mbedtls_fprintf( stdout, " Finished with alarmed=%d millis=%lu get(timer)<=%lu iterations=%lu\n",
|
||||||
mbedtls_timing_alarmed,
|
mbedtls_timing_alarmed,
|
||||||
millis, mbedtls_timing_get_timer( &timer, 0 ),
|
millis, mbedtls_timing_get_timer( &timer, 0 ),
|
||||||
@ -228,7 +261,7 @@ void timing_delay( int int_ms, int fin_ms )
|
|||||||
|
|
||||||
mbedtls_timing_delay_context delay;
|
mbedtls_timing_delay_context delay;
|
||||||
struct mbedtls_timing_hr_time timer;
|
struct mbedtls_timing_hr_time timer;
|
||||||
unsigned long delta; /* delay started between timer=0 and timer=delta */
|
unsigned long delta = 0; /* delay started between timer=0 and timer=delta */
|
||||||
unsigned long before = 0, after = 0;
|
unsigned long before = 0, after = 0;
|
||||||
unsigned long iterations = 0;
|
unsigned long iterations = 0;
|
||||||
int status = -2;
|
int status = -2;
|
||||||
@ -238,6 +271,10 @@ void timing_delay( int int_ms, int fin_ms )
|
|||||||
assert( int_ms >= 0 );
|
assert( int_ms >= 0 );
|
||||||
assert( fin_ms >= 0 );
|
assert( fin_ms >= 0 );
|
||||||
|
|
||||||
|
/* Skip this test if it looks like timers don't work at all, to avoid an
|
||||||
|
infinite loop below. */
|
||||||
|
TEST_ASSERT( !timers_are_badly_broken );
|
||||||
|
|
||||||
/* Start a reference timer. Program a delay, and verify that the status of
|
/* Start a reference timer. Program a delay, and verify that the status of
|
||||||
the delay is consistent with the time given by the reference timer. */
|
the delay is consistent with the time given by the reference timer. */
|
||||||
(void) mbedtls_timing_get_timer( &timer, 1 );
|
(void) mbedtls_timing_get_timer( &timer, 1 );
|
||||||
@ -310,6 +347,7 @@ void timing_delay( int int_ms, int fin_ms )
|
|||||||
exit:
|
exit:
|
||||||
/* No cleanup needed, but show some diagnostic iterations, because timing
|
/* No cleanup needed, but show some diagnostic iterations, because timing
|
||||||
problems can be hard to reproduce. */
|
problems can be hard to reproduce. */
|
||||||
|
if( !timers_are_badly_broken )
|
||||||
mbedtls_fprintf( stdout, " Finished with delta=%lu before=%lu after=%lu status=%d iterations=%lu\n",
|
mbedtls_fprintf( stdout, " Finished with delta=%lu before=%lu after=%lu status=%d iterations=%lu\n",
|
||||||
delta, before, after, status, iterations );
|
delta, before, after, status, iterations );
|
||||||
if( warn_inconclusive )
|
if( warn_inconclusive )
|
||||||
@ -326,7 +364,11 @@ void timing_hardclock( )
|
|||||||
completely nonsensical values. */
|
completely nonsensical values. */
|
||||||
|
|
||||||
struct mbedtls_timing_hr_time timer;
|
struct mbedtls_timing_hr_time timer;
|
||||||
unsigned long hardclock0, hardclock1, delta1;
|
unsigned long hardclock0 = -1, hardclock1 = -1, delta1 = -1;
|
||||||
|
|
||||||
|
/* Skip this test if it looks like timers don't work at all, to avoid an
|
||||||
|
infinite loop below. */
|
||||||
|
TEST_ASSERT( !timers_are_badly_broken );
|
||||||
|
|
||||||
hardclock0 = mbedtls_timing_hardclock( );
|
hardclock0 = mbedtls_timing_hardclock( );
|
||||||
/* Wait 2ms to ensure a nonzero delay. Since the timer interface has 1ms
|
/* Wait 2ms to ensure a nonzero delay. Since the timer interface has 1ms
|
||||||
@ -354,6 +396,7 @@ void timing_hardclock( )
|
|||||||
exit:
|
exit:
|
||||||
/* No cleanup needed, but show some diagnostic iterations, because timing
|
/* No cleanup needed, but show some diagnostic iterations, because timing
|
||||||
problems can be hard to reproduce. */
|
problems can be hard to reproduce. */
|
||||||
|
if( !timers_are_badly_broken )
|
||||||
mbedtls_fprintf( stdout, " Finished with hardclock=%lu,%lu\n",
|
mbedtls_fprintf( stdout, " Finished with hardclock=%lu,%lu\n",
|
||||||
hardclock0, hardclock1 );
|
hardclock0, hardclock1 );
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user