From 172f6acd6bc5f313e9e7c58cb73df31aed2e01e4 Mon Sep 17 00:00:00 2001
From: Tomas Pecka <peckato1@fit.cvut.cz>
Date: Thu, 11 Mar 2021 11:13:50 +0100
Subject: [PATCH] tests: Fix wrong select timeout handling since glibc=2.33

In recent Arch Linux builds we encountered some timeouts in tests.
Interestingly, the 30s timeouts were encountered not after 30s but
right-away. See the ctest output attached at the end of the message.

I remembered that Arch switched to glibc=2.33 recently. And by stracing
the test process I have noticed that indeed, the select in waitSignalTimeout
function timeouted early.
It seemed that the timeval struct is the problem and indeed it was. It
didn't like setting the 30s timeout as {.tv_sec = 0, .tv_usec = 30 *
1000 * 1000}. However, I can't find in any manpage why this is wrong...

It seems to be fixed by limiting tv_usec to be from [0; 1000*1000)
range and transfer the whole seconds into the tv_sec field.
And the glibc docs [1] says it so explicitely:

> When struct timeval values are produced by GNU C Library functions,
> the value in this field will always be greater than or equal to zero,
> and less than 1,000,000. When struct timeval values are supplied to GNU
> C Library functions, the value in this field must be in the same range.

[1] https://www.gnu.org/software/libc/manual/html_mono/libc.html#Time-Types

 -------------------------------------------------------------------------------
 aql/AutomatonIteration.aql
 -------------------------------------------------------------------------------
 /builds/algorithms-library-toolkit/infrastructure/cd-release/src/algorithms-library-snapshot/build/tests/AutomatonIteration.cpp:17
 ...............................................................................

 /builds/algorithms-library-toolkit/infrastructure/cd-release/src/algorithms-library-snapshot/tests/testing/TimeoutAqlTest.cpp:206: warning:
   AqlTest: timeout (30000000 us) reached
   Trying to execute testfile /builds/algorithms-library-toolkit/infrastructure/cd-release/src/algorithms-library-snapshot/tests/aql/AutomatonIteration.aql

 Seed was: 1053288110
   Child aqlout was: ><
   Child stdout was: ><
   Child stderr was: ><

 /builds/algorithms-library-toolkit/infrastructure/cd-release/src/algorithms-library-snapshot/tests/testing/TimeoutAqlTest.cpp:208: FAILED:

 ===============================================================================
 test cases: 1 | 1 failed
 assertions: 3 | 2 passed | 1 failed
---
 tests/testing/TimeoutAqlTest.cpp | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/tests/testing/TimeoutAqlTest.cpp b/tests/testing/TimeoutAqlTest.cpp
index 3e0c058f9e..329eaf948f 100644
--- a/tests/testing/TimeoutAqlTest.cpp
+++ b/tests/testing/TimeoutAqlTest.cpp
@@ -1,4 +1,5 @@
 #include "TimeoutAqlTest.hpp"
+#include <chrono>
 #include <cstring>
 #include <exception>
 #include <fstream>
@@ -26,12 +27,14 @@
 int g_Wakeup [ 2 ];  // pipe for wakeup
 int g_RecvSignal; // signalled flag
 
-int waitSignalTimeout ( int timeout ) {
+int waitSignalTimeout ( const std::chrono::microseconds& duration ) {
 	struct timeval tv;
 	fd_set rd;
 
-	tv.tv_sec = 0;
-	tv.tv_usec = timeout;
+	auto duration_secs = std::chrono::duration_cast < std::chrono::seconds > ( duration );
+	auto duration_usecs = std::chrono::duration_cast < std::chrono::microseconds > ( duration - duration_secs );
+	tv.tv_sec = duration_secs.count ( );
+	tv.tv_usec = duration_usecs.count ( );
 	FD_ZERO ( &rd );
 	FD_SET ( g_Wakeup [ PIPE_RD ], &rd );
 
@@ -131,10 +134,10 @@ ChildStatus _TimeoutAqlTestImpl ( const std::chrono::microseconds & timeout, std
 	close ( pipeStderr [ PIPE_WR ] );
 
 	/* lets wait the specified time of microseconds, maybe the child will terminate on its own */
-	if ( ! waitSignalTimeout ( timeout.count ( ) ) ) {
+	if ( ! waitSignalTimeout ( timeout ) ) {
 		/* ... and in case it did not ... */
 		kill ( pid, SIGTERM );
-		while ( ! waitSignalTimeout ( 250000 ) ) /* 1/4 second */
+		while ( ! waitSignalTimeout ( 250ms ) ) /* 1/4 second */
 			kill ( pid, SIGKILL );
 	}
 
-- 
GitLab