From a2f78ea0a147301222cb5346fad7e09121d87d59 Mon Sep 17 00:00:00 2001
From: Jan-Marek Glogowski <glogow@fbihome.de>
Date: Tue, 11 Mar 2014 15:14:16 +0100
Subject: [PATCH] Fix tst_QEventLoop::processEventsExcludeSocket test

The testcase always returns the expected result, independently of the
QEventLoop::ExcludeSocketNotifiers flag to processEvents.

In Qt4 the same test uses an intermediate QEventLoop and already runs
it before the QEventLoop::ExcludeSocketNotifiers:

  QEventLoop loop;
  // allow the TCP/IP stack time to loopback the data,
  //  so our socket is ready to read
  QTimer::singleShot(200, &loop, SLOT(quit()));
  loop.exec(QEventLoop::ExcludeSocketNotifiers);

This fixes and improves the test by connecting, processing and
checking the bytesWritten signal for the pending connection socket.

Change-Id: I1b1d2b7b83910c87ba3fe48e29ac9fd585ac62ad
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
---
 .../kernel/qeventloop/tst_qeventloop.cpp      | 52 +++++++++++++++----
 1 file changed, 43 insertions(+), 9 deletions(-)

diff --git a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp
index 5cfbce0d7ae..befd45018a8 100644
--- a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp
+++ b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp
@@ -40,6 +40,7 @@
 #include <private/qeventloop_p.h>
 #if defined(Q_OS_UNIX)
   #include <private/qeventdispatcher_unix_p.h>
+  #include <QtCore/private/qcore_unix_p.h>
   #if defined(HAVE_GLIB)
     #include <private/qeventdispatcher_glib_p.h>
   #endif
@@ -172,7 +173,9 @@ private slots:
     void execAfterExit();
     void wakeUp();
     void quit();
+#if defined(Q_OS_UNIX)
     void processEventsExcludeSocket();
+#endif
     void processEventsExcludeTimers();
     void deliverInDefinedOrder();
 
@@ -383,6 +386,7 @@ void tst_QEventLoop::customEvent(QEvent *e)
     }
 }
 
+#if defined(Q_OS_UNIX)
 class SocketEventsTester: public QObject
 {
     Q_OBJECT
@@ -391,8 +395,10 @@ public:
     {
         socket = 0;
         server = 0;
-        dataArrived = false;
+        dataSent = false;
+        dataReadable = false;
         testResult = false;
+        dataArrived = false;
     }
     ~SocketEventsTester()
     {
@@ -415,8 +421,10 @@ public:
 
     QTcpSocket *socket;
     QTcpServer *server;
-    bool dataArrived;
+    bool dataSent;
+    bool dataReadable;
     bool testResult;
+    bool dataArrived;
 public slots:
     void sendAck()
     {
@@ -428,12 +436,26 @@ public slots:
         qint64 size = sizeof(data);
 
         QTcpSocket *serverSocket = server->nextPendingConnection();
+        QCoreApplication::processEvents();
         serverSocket->write(data, size);
-        serverSocket->flush();
-        QTest::qSleep(200); //allow the TCP/IP stack time to loopback the data, so our socket is ready to read
-        QCoreApplication::processEvents(QEventLoop::ExcludeSocketNotifiers);
-        testResult = dataArrived;
-        QCoreApplication::processEvents(); //check the deferred event is processed
+        dataSent = serverSocket->waitForBytesWritten(-1);
+
+        if (dataSent) {
+            fd_set fdread;
+            int fd = socket->socketDescriptor();
+            FD_ZERO(&fdread);
+            FD_SET(fd, &fdread);
+            dataReadable = (1 == qt_safe_select(fd + 1, &fdread, 0, 0, 0));
+        }
+
+        if (!dataReadable) {
+            testResult = dataArrived;
+        } else {
+            QCoreApplication::processEvents(QEventLoop::ExcludeSocketNotifiers);
+            testResult = dataArrived;
+            // to check if the deferred event is processed
+            QCoreApplication::processEvents();
+        }
         serverSocket->close();
         QThread::currentThread()->exit(0);
     }
@@ -449,12 +471,16 @@ public:
         SocketEventsTester *tester = new SocketEventsTester();
         if (tester->init())
             exec();
+        dataSent = tester->dataSent;
+        dataReadable = tester->dataReadable;
         testResult = tester->testResult;
         dataArrived = tester->dataArrived;
         delete tester;
     }
-     bool testResult;
-     bool dataArrived;
+    bool dataSent;
+    bool dataReadable;
+    bool testResult;
+    bool dataArrived;
 };
 
 void tst_QEventLoop::processEventsExcludeSocket()
@@ -462,9 +488,17 @@ void tst_QEventLoop::processEventsExcludeSocket()
     SocketTestThread thread;
     thread.start();
     QVERIFY(thread.wait());
+    QVERIFY(thread.dataSent);
+    QVERIFY(thread.dataReadable);
+  #if defined(HAVE_GLIB)
+    QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher();
+    if (qobject_cast<QEventDispatcherGlib *>(eventDispatcher))
+        QEXPECT_FAIL("", "ExcludeSocketNotifiers is currently broken in the Glib dispatchers", Continue);
+  #endif
     QVERIFY(!thread.testResult);
     QVERIFY(thread.dataArrived);
 }
+#endif
 
 class TimerReceiver : public QObject
 {
-- 
GitLab