Changeset 141598 in webkit


Ignore:
Timestamp:
Feb 1, 2013 8:34:05 AM (11 years ago)
Author:
Simon Hausmann
Message:

[Qt] Make QWebHistory unit tests more robust

Reviewed by Jocelyn Turcotten.

The tests were using a QEventLoop::exec() call to verify the emission
of the loadFinished() signal after calling for example back() or forward().
However sometimes the call to back() may emit the signal immediately and
sometimes async, causing instabilities in test runs. The call to exec()
also means that if there was a bug then the rest would hang forever because
exec() has no timeout.

This patch introduces a simple SignalBarrier class that solves both issues:

(1) ensureSignalEmitted() supports the immediate signal emission case as well
as the async one.

(2) Through the use of QSignalSpy's wait() there's an actual timeout.

  • tests/qwebhistory/tst_qwebhistory.cpp:

(tst_QWebHistory::init):
(tst_QWebHistory::cleanup):
(tst_QWebHistory::back):
(tst_QWebHistory::forward):
(tst_QWebHistory::goToItem):
(tst_QWebHistory::serialize_2):

  • tests/util.h:

(waitForSignal):
(SignalBarrier):
(SignalBarrier::SignalBarrier):
(SignalBarrier::ensureSignalEmitted):

Location:
trunk/Source/WebKit/qt
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/qt/ChangeLog

    r141582 r141598  
     12013-02-01  Simon Hausmann  <simon.hausmann@digia.com>
     2
     3        [Qt] Make QWebHistory unit tests more robust
     4
     5        Reviewed by Jocelyn Turcotten.
     6
     7        The tests were using a QEventLoop::exec() call to verify the emission
     8        of the loadFinished() signal after calling for example back() or forward().
     9        However sometimes the call to back() may emit the signal immediately and
     10        sometimes async, causing instabilities in test runs. The call to exec()
     11        also means that if there was a bug then the rest would hang forever because
     12        exec() has no timeout.
     13
     14        This patch introduces a simple SignalBarrier class that solves both issues:
     15
     16        (1) ensureSignalEmitted() supports the immediate signal emission case as well
     17        as the async one.
     18
     19        (2) Through the use of QSignalSpy's wait() there's an actual timeout.
     20
     21        * tests/qwebhistory/tst_qwebhistory.cpp:
     22        (tst_QWebHistory::init):
     23        (tst_QWebHistory::cleanup):
     24        (tst_QWebHistory::back):
     25        (tst_QWebHistory::forward):
     26        (tst_QWebHistory::goToItem):
     27        (tst_QWebHistory::serialize_2):
     28        * tests/util.h:
     29        (waitForSignal):
     30        (SignalBarrier):
     31        (SignalBarrier::SignalBarrier):
     32        (SignalBarrier::ensureSignalEmitted):
     33
    1342013-02-01  Simon Hausmann  <simon.hausmann@digia.com>
    235
  • trunk/Source/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp

    r139878 r141598  
    2121#include <QAction>
    2222
     23#include "../util.h"
    2324#include "qwebpage.h"
    2425#include "qwebview.h"
     
    3940    {
    4041        frame->load(QUrl("qrc:/resources/page" + QString::number(nr) + ".html"));
    41         waitForLoadFinished.exec();
     42        loadFinishedBarrier->ensureSignalEmitted();
    4243    }
    4344
     
    7374    QWebFrame* frame;
    7475    QWebHistory* hist;
    75     QEventLoop waitForLoadFinished;  //operation on history are asynchronous!
     76    QScopedPointer<SignalBarrier> loadFinishedBarrier;
    7677    int histsize;
    7778};
     
    8990    page = new QWebPage(this);
    9091    frame = page->mainFrame();
    91     connect(page, SIGNAL(loadFinished(bool)), &waitForLoadFinished, SLOT(quit()), Qt::QueuedConnection);
     92    loadFinishedBarrier.reset(new SignalBarrier(frame, SIGNAL(loadFinished(bool))));
    9293
    9394    for (int i = 1;i < 6;i++) {
     
    100101void tst_QWebHistory::cleanup()
    101102{
     103    loadFinishedBarrier.reset();
    102104    delete page;
    103105}
     
    127129        QCOMPARE(page->mainFrame()->toPlainText(), QString("page") + QString::number(i));
    128130        hist->back();
    129         waitForLoadFinished.exec();
     131        loadFinishedBarrier->ensureSignalEmitted();
    130132    }
    131133    //try one more time (too many). crash test
     
    142144    while (hist->canGoBack()) {
    143145        hist->back();
    144         waitForLoadFinished.exec();
     146        loadFinishedBarrier->ensureSignalEmitted();
    145147    }
    146148
     
    148150        QCOMPARE(page->mainFrame()->toPlainText(), QString("page") + QString::number(i));
    149151        hist->forward();
    150         waitForLoadFinished.exec();
     152        loadFinishedBarrier->ensureSignalEmitted();
    151153    }
    152154    //try one more time (too many). crash test
     
    176178    QWebHistoryItem current = hist->currentItem();
    177179    hist->back();
    178     waitForLoadFinished.exec();
     180    loadFinishedBarrier->ensureSignalEmitted();
    179181    hist->back();
    180     waitForLoadFinished.exec();
     182    loadFinishedBarrier->ensureSignalEmitted();
    181183    QVERIFY(hist->currentItem().title() != current.title());
    182184    hist->goToItem(current);
    183     waitForLoadFinished.exec();
     185    loadFinishedBarrier->ensureSignalEmitted();
    184186    QCOMPARE(hist->currentItem().title(), current.title());
    185187}
     
    245247
    246248    hist->back();
     249    loadFinishedBarrier->ensureSignalEmitted();
    247250    hist->back();
    248     waitForLoadFinished.exec();
     251    loadFinishedBarrier->ensureSignalEmitted();
    249252    hist->back();
    250     waitForLoadFinished.exec();
     253    loadFinishedBarrier->ensureSignalEmitted();
    251254    //check if current index was changed (make sure that it is not last item)
    252255    QVERIFY(hist->currentItemIndex() != initialCurrentIndex);
     
    263266
    264267    hist->forward();
    265     waitForLoadFinished.exec();
     268    loadFinishedBarrier->ensureSignalEmitted();
    266269    hist->forward();
    267     waitForLoadFinished.exec();
     270    loadFinishedBarrier->ensureSignalEmitted();
    268271    hist->forward();
     272    loadFinishedBarrier->ensureSignalEmitted();
    269273    QCOMPARE(hist->currentItemIndex(), initialCurrentIndex);
    270274}
  • trunk/Source/WebKit/qt/tests/util.h

    r124879 r141598  
    3939 *         \p false on timeout
    4040 */
    41 static bool waitForSignal(QObject* obj, const char* signal, int timeout = 10000)
     41static inline bool waitForSignal(QObject* obj, const char* signal, int timeout = 10000)
    4242{
    4343    QEventLoop loop;
     
    5454}
    5555
     56/**
     57 * Just like QSignalSpy but facilitates sync and async
     58 * signal emission. For example if you want to verify that
     59 * page->foo() emitted a signal, it could be that the
     60 * implementation decides to emit the signal asynchronously
     61 * - in which case we want to spin a local event loop until
     62 * emission - or that the call to foo() emits it right away.
     63 */
     64class SignalBarrier : private QSignalSpy
     65{
     66public:
     67    SignalBarrier(const QObject* obj, const char* aSignal)
     68        : QSignalSpy(obj, aSignal)
     69    { }
     70
     71    bool ensureSignalEmitted()
     72    {
     73        bool result = count() > 0;
     74        if (!result)
     75            result = wait();
     76        clear();
     77        return result;
     78    }
     79};
     80
    5681#define W_QSKIP(a, b) QSKIP(a)
Note: See TracChangeset for help on using the changeset viewer.