From 679560feaa0557d8a9ec389fb98cb49697fcf98b Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 21 Jun 2023 11:49:31 +0100 Subject: [PATCH] tests: Fix an intermittent timing error with testing g_usleep(0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code to test that `g_usleep(0)` returns immediately assumes that `g_usleep(1)` always takes longer, but that’s not necessarily always the case. Even if no sleeping happens, the function call for `g_usleep(0)` could get descheduled and take longer than normal. This results in occasional failures like this one: ``` GLib:ERROR:../glib/tests/timer.c:367:test_usleep_with_zero_wait: assertion failed (elapsed0 <= elapsed1): (0.000206 <= 0.000202) ``` (Source: https://gitlab.gnome.org/GNOME/glib/-/jobs/2898468) I can’t think of a suitable invariant comparison which can be done with the timers, but running the comparison 10 times and allowing it to fail once should work. A probabilistic test of `g_usleep(0)`. Signed-off-by: Philip Withnall --- glib/tests/timer.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/glib/tests/timer.c b/glib/tests/timer.c index be4cb957b..ae44dc8ea 100644 --- a/glib/tests/timer.c +++ b/glib/tests/timer.c @@ -350,21 +350,33 @@ static void test_usleep_with_zero_wait (void) { GTimer *timer; - gdouble elapsed0, elapsed1; + unsigned int n_times_shorter = 0; timer = g_timer_new (); - g_timer_start (timer); - g_usleep (0); - elapsed0 = g_timer_elapsed (timer, NULL); - g_timer_stop (timer); + /* Test that g_usleep(0) sleeps for less time than g_usleep(1). We can’t + * actually guarantee this, since the exact length of g_usleep(1) is not + * guaranteed, but we can say that it probably should be longer 9 times out + * of 10. */ + for (unsigned int i = 0; i < 10; i++) + { + gdouble elapsed0, elapsed1; - g_timer_start (timer); - g_usleep (1); - elapsed1 = g_timer_elapsed (timer, NULL); - g_timer_stop (timer); + g_timer_start (timer); + g_usleep (0); + elapsed0 = g_timer_elapsed (timer, NULL); + g_timer_stop (timer); - g_assert_cmpfloat (elapsed0, <=, elapsed1); + g_timer_start (timer); + g_usleep (1); + elapsed1 = g_timer_elapsed (timer, NULL); + g_timer_stop (timer); + + if (elapsed0 <= elapsed1) + n_times_shorter++; + } + + g_assert_cmpuint (n_times_shorter, >=, 9); g_clear_pointer (&timer, g_timer_destroy); }