test-utils-glib: Try to emit TAP diagnostics before aborting
authorSimon McVittie <smcv@collabora.com>
Wed, 27 Sep 2017 12:14:36 +0000 (13:14 +0100)
committerSimon McVittie <smcv@collabora.com>
Wed, 27 Sep 2017 13:45:34 +0000 (14:45 +0100)
We can't use normal I/O in a signal handler, so resort to write().

"Bail out!" is a special syntactic token in TAP. If I artifically force
the tests to time out by reducing timeouts and increasing the number of
operations, I get results like this:

ERROR: test-sd-activation - Bail out! Test timed out (GLib main loop timeout callback reached)
ERROR: test-refs - Bail out! Test timed out (SIGALRM received)

which is a lot easier to understand than "Not enough tests run" or
"nonzero exit status". The differing output is because test-sd-activation
iterates the main loop, whereas test-refs just blocks (it is joining a
series of worker threads, each of which is spamming refcount operations).

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=103009
Reviewed-by: Philip Withnall <withnall@endlessm.com>
[smcv: Use STDOUT_FILENO as per Philip's review]
Signed-off-by: Simon McVittie <smcv@collabora.com>
test/test-utils-glib.c

index bb48195..73416bb 100644 (file)
@@ -459,7 +459,9 @@ test_kill_pid (GPid pid)
 static gboolean
 time_out (gpointer data)
 {
-  g_error ("timed out");
+  puts ("Bail out! Test timed out (GLib main loop timeout callback reached)");
+  fflush (stdout);
+  abort ();
   return FALSE;
 }
 
@@ -469,6 +471,16 @@ static void wrap_abort (int signal) _DBUS_GNUC_NORETURN;
 static void
 wrap_abort (int signal)
 {
+  /* We might be halfway through writing out something else, so force this
+   * onto its own line */
+  const char message [] = "\nBail out! Test timed out (SIGALRM received)\n";
+
+  if (write (STDOUT_FILENO, message, sizeof (message) - 1) <
+      (ssize_t) sizeof (message) - 1)
+    {
+      /* ignore short write - what would we do about it? */
+    }
+
   abort ();
 }
 #endif
@@ -490,7 +502,7 @@ test_init (int *argcp, char ***argvp)
    * test). Die with SIGALRM shortly after if necessary. */
   alarm (TIMEOUT + 10);
 
-  /* Get a core dump from the SIGALRM. */
+  /* Get a log message and a core dump from the SIGALRM. */
     {
       struct sigaction act = { };