mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-11-04 04:32:24 -05: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,9 +129,10 @@ 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. */
 | 
				
			||||||
    mbedtls_fprintf( stdout, "  Finished with millis=%lu get(timer)<=%lu iterations=%lu\n",
 | 
					    if( !timers_are_badly_broken )
 | 
				
			||||||
                     millis, mbedtls_timing_get_timer( &timer, 0 ),
 | 
					        mbedtls_fprintf( stdout, "  Finished with millis=%lu get(timer)<=%lu iterations=%lu\n",
 | 
				
			||||||
                     iterations );
 | 
					                         millis, mbedtls_timing_get_timer( &timer, 0 ),
 | 
				
			||||||
 | 
					                         iterations );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
/* END_CASE */
 | 
					/* END_CASE */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -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,9 +180,10 @@ 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. */
 | 
				
			||||||
    mbedtls_fprintf( stdout, "  Finished with millis1=%lu get(timer1)<=%lu millis2=%lu get(timer2)<=%lu\n",
 | 
					    if( !timers_are_badly_broken )
 | 
				
			||||||
                     millis1, mbedtls_timing_get_timer( &timer1, 0 ),
 | 
					        mbedtls_fprintf( stdout, "  Finished with millis1=%lu get(timer1)<=%lu millis2=%lu get(timer2)<=%lu\n",
 | 
				
			||||||
                     millis2, mbedtls_timing_get_timer( &timer2, 0 ) );
 | 
					                         millis1, mbedtls_timing_get_timer( &timer1, 0 ),
 | 
				
			||||||
 | 
					                         millis2, mbedtls_timing_get_timer( &timer2, 0 ) );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
/* END_CASE */
 | 
					/* END_CASE */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -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,10 +241,11 @@ 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. */
 | 
				
			||||||
    mbedtls_fprintf( stdout, "  Finished with alarmed=%d millis=%lu get(timer)<=%lu iterations=%lu\n",
 | 
					    if( !timers_are_badly_broken )
 | 
				
			||||||
                     mbedtls_timing_alarmed,
 | 
					        mbedtls_fprintf( stdout, "  Finished with alarmed=%d millis=%lu get(timer)<=%lu iterations=%lu\n",
 | 
				
			||||||
                     millis, mbedtls_timing_get_timer( &timer, 0 ),
 | 
					                         mbedtls_timing_alarmed,
 | 
				
			||||||
                     iterations );
 | 
					                         millis, mbedtls_timing_get_timer( &timer, 0 ),
 | 
				
			||||||
 | 
					                         iterations );
 | 
				
			||||||
    /* Cleanup */
 | 
					    /* Cleanup */
 | 
				
			||||||
    mbedtls_timing_alarmed = 0;
 | 
					    mbedtls_timing_alarmed = 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,8 +347,9 @@ 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. */
 | 
				
			||||||
    mbedtls_fprintf( stdout, "  Finished with delta=%lu before=%lu after=%lu status=%d iterations=%lu\n",
 | 
					    if( !timers_are_badly_broken )
 | 
				
			||||||
                     delta, before, after, status, iterations );
 | 
					        mbedtls_fprintf( stdout, "  Finished with delta=%lu before=%lu after=%lu status=%d iterations=%lu\n",
 | 
				
			||||||
 | 
					                         delta, before, after, status, iterations );
 | 
				
			||||||
    if( warn_inconclusive )
 | 
					    if( warn_inconclusive )
 | 
				
			||||||
        mbedtls_fprintf( stdout, "  Inconclusive test, try running it on a less heavily loaded machine.\n" );
 | 
					        mbedtls_fprintf( stdout, "  Inconclusive test, try running it on a less heavily loaded machine.\n" );
 | 
				
			||||||
 }
 | 
					 }
 | 
				
			||||||
@ -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,7 +396,8 @@ 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. */
 | 
				
			||||||
    mbedtls_fprintf( stdout, "  Finished with hardclock=%lu,%lu\n",
 | 
					    if( !timers_are_badly_broken )
 | 
				
			||||||
                     hardclock0, hardclock1 );
 | 
					        mbedtls_fprintf( stdout, "  Finished with hardclock=%lu,%lu\n",
 | 
				
			||||||
 | 
					                         hardclock0, hardclock1 );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
/* END_CASE */
 | 
					/* END_CASE */
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user