Improved stability of tst_qsemaphore (especially on mac)
authorRohan McGovern <rohan.mcgovern@nokia.com>
Mon, 6 Feb 2012 04:17:08 +0000 (14:17 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 8 Feb 2012 01:10:51 +0000 (02:10 +0100)
Timers are not entirely precise; if we ask for a timeout of
10000 milliseconds, we might time out in 9999 instead.
Also, we know the expected elapsed time in each case, so do a fuzzy
comparison against that time.

Previously the test was verifying that the elapsed time was greater than
or equal to the timeout in the case where a timeout was expected, which
means the test would not detect bugs which incorrectly caused the
timeout to occur later than it should.

(cherry picked from qt4 commit 9a2573dc13b3e8df6cd15bef64370ea407480fc7)

Change-Id: I91d0c81f989ab43a3c48f6abbb4c5b28e2b35402
Reviewed-by: Jason McDonald <jason.mcdonald@nokia.com>
tests/auto/corelib/thread/qsemaphore/qsemaphore.pro
tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp

index cd87e68..0ad311d 100644 (file)
@@ -2,5 +2,3 @@ CONFIG += testcase parallel_test
 TARGET = tst_qsemaphore
 QT = core testlib
 SOURCES = tst_qsemaphore.cpp
-
-mac*:CONFIG+=insignificant_test
index 1d54c8e..884e871 100644 (file)
@@ -223,11 +223,21 @@ void tst_QSemaphore::tryAcquireWithTimeout()
 {
     QFETCH(int, timeout);
 
+    // timers are not guaranteed to be accurate down to the last millisecond,
+    // so we permit the elapsed times to be up to this far from the expected value.
+    int fuzz = 10;
+
     QSemaphore semaphore;
     QTime time;
 
-#define QVERIFYGE(a,b) QVERIFY2(a >= b, qPrintable(QString("%1 = %2 !>= %3 = %4").arg(#a).arg(a).arg(#b).arg(b)));
-#define QVERIFYLE(a,b) QVERIFY2(a <= b, qPrintable(QString("%1 = %2 !<= %3 = %4").arg(#a).arg(a).arg(#b).arg(b)));
+#define FUZZYCOMPARE(a,e) \
+    do { \
+        int a1 = a; \
+        int e1 = e; \
+        QVERIFY2(qAbs(a1-e1) < fuzz, \
+            qPrintable(QString("(%1=%2) is more than %3 milliseconds different from (%4=%5)") \
+                        .arg(#a).arg(a1).arg(fuzz).arg(#e).arg(e1))); \
+    } while (0)
 
     QCOMPARE(semaphore.available(), 0);
 
@@ -235,73 +245,72 @@ void tst_QSemaphore::tryAcquireWithTimeout()
     QCOMPARE(semaphore.available(), 1);
     time.start();
     QVERIFY(!semaphore.tryAcquire(2, timeout));
-    QVERIFYGE(time.elapsed(), timeout);
+    FUZZYCOMPARE(time.elapsed(), timeout);
     QCOMPARE(semaphore.available(), 1);
 
     semaphore.release();
     QCOMPARE(semaphore.available(), 2);
     time.start();
     QVERIFY(!semaphore.tryAcquire(3, timeout));
-    QVERIFYGE(time.elapsed(), timeout);
+    FUZZYCOMPARE(time.elapsed(), timeout);
     QCOMPARE(semaphore.available(), 2);
 
     semaphore.release(10);
     QCOMPARE(semaphore.available(), 12);
     time.start();
     QVERIFY(!semaphore.tryAcquire(100, timeout));
-    QVERIFYGE(time.elapsed(), timeout);
+    FUZZYCOMPARE(time.elapsed(), timeout);
     QCOMPARE(semaphore.available(), 12);
 
     semaphore.release(10);
     QCOMPARE(semaphore.available(), 22);
     time.start();
     QVERIFY(!semaphore.tryAcquire(100, timeout));
-    QVERIFYGE(time.elapsed(), timeout);
+    FUZZYCOMPARE(time.elapsed(), timeout);
     QCOMPARE(semaphore.available(), 22);
 
     time.start();
     QVERIFY(semaphore.tryAcquire(1, timeout));
-    QVERIFYLE(time.elapsed(), timeout);
+    FUZZYCOMPARE(time.elapsed(), 0);
     QCOMPARE(semaphore.available(), 21);
 
     time.start();
     QVERIFY(semaphore.tryAcquire(1, timeout));
-    QVERIFYLE(time.elapsed(), timeout);
+    FUZZYCOMPARE(time.elapsed(), 0);
     QCOMPARE(semaphore.available(), 20);
 
     time.start();
     QVERIFY(semaphore.tryAcquire(10, timeout));
-    QVERIFYLE(time.elapsed(), timeout);
+    FUZZYCOMPARE(time.elapsed(), 0);
     QCOMPARE(semaphore.available(), 10);
 
     time.start();
     QVERIFY(semaphore.tryAcquire(10, timeout));
-    QVERIFYLE(time.elapsed(), timeout);
+    FUZZYCOMPARE(time.elapsed(), 0);
     QCOMPARE(semaphore.available(), 0);
 
     // should not be able to acquire more
     time.start();
     QVERIFY(!semaphore.tryAcquire(1, timeout));
-    QVERIFYGE(time.elapsed(), timeout);
+    FUZZYCOMPARE(time.elapsed(), timeout);
     QCOMPARE(semaphore.available(), 0);
 
     time.start();
     QVERIFY(!semaphore.tryAcquire(1, timeout));
-    QVERIFYGE(time.elapsed(), timeout);
+    FUZZYCOMPARE(time.elapsed(), timeout);
     QCOMPARE(semaphore.available(), 0);
 
     time.start();
     QVERIFY(!semaphore.tryAcquire(10, timeout));
-    QVERIFYGE(time.elapsed(), timeout);
+    FUZZYCOMPARE(time.elapsed(), timeout);
     QCOMPARE(semaphore.available(), 0);
 
     time.start();
     QVERIFY(!semaphore.tryAcquire(10, timeout));
-    QVERIFYGE(time.elapsed(), timeout);
+    FUZZYCOMPARE(time.elapsed(), timeout);
     QCOMPARE(semaphore.available(), 0);
 
-#undef QVERIFYGE
-#undef QVERIFYLE
+#undef FUZZYCOMPARE
 }
 
 void tst_QSemaphore::tryAcquireWithTimeoutStarvation()