[Ktutorial-commits] SF.net SVN: ktutorial:[344] trunk/ktutorial/ktutorial-editor/tests/unit/ view/
Status: Alpha
Brought to you by:
danxuliu
From: <dan...@us...> - 2012-06-26 22:12:16
|
Revision: 344 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=344&view=rev Author: danxuliu Date: 2012-06-26 22:12:09 +0000 (Tue, 26 Jun 2012) Log Message: ----------- Change the way that actions are enqueued in RemoteObjectChooserTest to prevent the tests from failing in slow systems. Instead of queueing and executing the actions after a fixed amount of time, it is checked if the action can be performed and, if not, the action is retried again after a little amount of time. The retries continue until the timeout expires. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/tests/unit/view/RemoteObjectChooserTest.cpp Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/RemoteObjectChooserTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/RemoteObjectChooserTest.cpp 2012-06-26 21:53:28 UTC (rev 343) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/RemoteObjectChooserTest.cpp 2012-06-26 22:12:09 UTC (rev 344) @@ -78,10 +78,13 @@ QString mPath; void closeInformationMessageBox(int timeToWait); + void closeInformationMessageBoxOnceTargetApplicationEnds(int timeToWait); void closeSorryMessageBox(QWidget* widget, int timeToWait); - void killTargetApplication(int timeToWait); + void killTargetApplicationOnceMessageBoxIsShown(int timeToWait); + bool waitForSorryMessageBoxToBeClosed(QWidget* widget, int timeout); + bool waitForTargetApplicationToStart(int timeout) const; bool waitForTargetApplicationToStop(int timeout) const; @@ -135,7 +138,7 @@ dialog->show(); //Queue closing the information message box - closeInformationMessageBox(1000); + closeInformationMessageBox(10000); RemoteObjectChooser* chooser = new RemoteObjectChooser(dialog); chooser->show(); @@ -162,7 +165,7 @@ dialog->show(); //Queue closing the information message box - closeInformationMessageBox(1000); + closeInformationMessageBox(10000); RemoteObjectChooser* chooser = new RemoteObjectChooser(dialog); chooser->show(); @@ -186,12 +189,10 @@ QPointer<RemoteObjectChooser> chooser = new RemoteObjectChooser(dialog); chooser->show(); - //Queue closing the sorry message box - closeSorryMessageBox(chooser, 1000); + //The sorry message box will be shown and then closed once the target + //application fails to start + QVERIFY(waitForSorryMessageBoxToBeClosed(chooser, 10000)); - //Give the target application time to fail to start - QTest::qWait(1000); - //Process deleteLater() QCoreApplication::sendPostedEvents(chooser, QEvent::DeferredDelete); @@ -213,12 +214,10 @@ QPointer<RemoteObjectChooser> chooser = new RemoteObjectChooser(dialog); chooser->show(); - //Queue closing the sorry message box - closeSorryMessageBox(chooser, 3500); + //The sorry message box will be shown and then closed once the target + //application fails to start + QVERIFY(waitForSorryMessageBoxToBeClosed(chooser, 10000)); - //Give the target application time to fail to start - QTest::qWait(3500); - //Process deleteLater() QCoreApplication::sendPostedEvents(chooser, QEvent::DeferredDelete); @@ -236,14 +235,14 @@ dialog->show(); //Queue closing the information message box - closeInformationMessageBox(1000); + closeInformationMessageBox(10000); QPointer<RemoteObjectChooser> chooser = new RemoteObjectChooser(dialog); chooser->show(); QVERIFY(waitForTargetApplicationToStart(10000)); //Queue closing the sorry message box - closeSorryMessageBox(chooser, 1000); + closeSorryMessageBox(chooser, 10000); TargetApplication::self()->mProcess->kill(); @@ -266,27 +265,20 @@ QWidget* dialog = new QWidget(&window, Qt::Dialog); dialog->show(); + //Queue killing the target application once the message box is shown + killTargetApplicationOnceMessageBoxIsShown(10000); + + //Queue closing the information message box once the target application was + //killed + closeInformationMessageBoxOnceTargetApplicationEnds(10000); + QPointer<RemoteObjectChooser> chooser = new RemoteObjectChooser(dialog); chooser->show(); - //All the queuing has to be done before the qWait, because the killing must - //be done once the information message is already shown, and the sorry - //message appears just after the information message is closed (and it may - //appear before the wait ends, so queuing it after the wait could not work). + //The sorry message box will be shown and then closed once the information + //message box is closed + QVERIFY(waitForSorryMessageBoxToBeClosed(chooser, 10000)); - //Queue killing the target application - killTargetApplication(1000); - - //Queue closing the information message box - closeInformationMessageBox(2000); - - //Queue closing the sorry message box - closeSorryMessageBox(chooser, 3000); - - //Give the target application time to start and be killed, and to close the - //sorry message box - QTest::qWait(3000); - //Process deleteLater() QCoreApplication::sendPostedEvents(chooser, QEvent::DeferredDelete); @@ -304,7 +296,7 @@ dialog->show(); //Queue closing the information message box - closeInformationMessageBox(1000); + closeInformationMessageBox(10000); QPointer<RemoteObjectChooser> chooser = new RemoteObjectChooser(dialog); chooser->show(); @@ -325,7 +317,7 @@ QWidget window(0, Qt::Window); //Queue closing the information message box - closeInformationMessageBox(1000); + closeInformationMessageBox(10000); RemoteObjectChooser* chooser = new RemoteObjectChooser(&window); chooser->show(); @@ -350,7 +342,7 @@ QWidget window(0, Qt::Window); //Queue closing the information message box - closeInformationMessageBox(1000); + closeInformationMessageBox(10000); RemoteObjectChooser* chooser = new RemoteObjectChooser(&window); chooser->show(); @@ -378,7 +370,7 @@ QWidget window(0, Qt::Window); //Queue closing the information message box - closeInformationMessageBox(1000); + closeInformationMessageBox(10000); RemoteObjectChooser* chooser = new RemoteObjectChooser(&window); chooser->show(); @@ -414,7 +406,7 @@ QWidget window(0, Qt::Window); //Queue closing the information message box - closeInformationMessageBox(1000); + closeInformationMessageBox(10000); RemoteObjectChooser* chooser = new RemoteObjectChooser(&window); chooser->show(); @@ -461,7 +453,7 @@ dialog->show(); //Queue closing the information message box - closeInformationMessageBox(1000); + closeInformationMessageBox(10000); QPointer<RemoteObjectChooser> chooser = new RemoteObjectChooser(dialog); chooser->show(); @@ -505,7 +497,7 @@ dialog->show(); //Queue closing the information message box - closeInformationMessageBox(1000); + closeInformationMessageBox(10000); QPointer<RemoteObjectChooser> chooser = new RemoteObjectChooser(dialog); chooser->show(); @@ -537,76 +529,235 @@ //The message boxes are modal, so they won't return to the test code until they //are closed. Thus, the actions to be performed while the message boxes are //being shown (like closing the message boxes themselves) must be "queued". -class QueuedActionsHelper: public QObject { +//Instead of queueing them to be performed after some fixed amount of time, +//it is checked if the action can be performed and, if not, the action is +//retried again after a little amount of time. The retries continue until the +//timeout expires. +class QueuedAction: public QObject { Q_OBJECT public: - QueuedActionsHelper(QObject* parent = 0): QObject(parent), - mWidget(0) { + QueuedAction(int timeout, QObject* parent): QObject(parent), + mTimeout(timeout), + mFinished(false), + mActionDone(false) { } - void setWidget(QWidget* widget) { - mWidget = widget; + void run() { + mElapsedTime.start(); + mFinished = false; + + checkAction(); } + bool isFinished() const { + return mFinished; + } + + bool isActionDone() const { + return mActionDone; + } + public slots: - void closeInformation() const { + void checkAction() { + mActionDone = action(); + if (!mActionDone && mElapsedTime.elapsed() < mTimeout) { + QTimer::singleShot(100, this, SLOT(checkAction())); + } else { + mFinished = true; + } + } + +protected: + + virtual bool action() = 0; + +private: + + int mTimeout; + QTime mElapsedTime; + bool mFinished; + bool mActionDone; + +}; + +QWidget* findRemoteObjectChooser() { + foreach (QWidget* widget, QApplication::topLevelWidgets()) { + if (qobject_cast<RemoteObjectChooser*>(widget)) { + return widget; + } + } + + return 0; +} + +KDialog* findInformationMessageBox() { + QWidget* widget = findRemoteObjectChooser(); + if (!widget) { + return 0; + } + + return widget->findChild<KDialog*>("information"); +} + +class CloseInformationMessageBoxHelper: public QueuedAction { +public: + + CloseInformationMessageBoxHelper(int timeout, QObject* parent): + QueuedAction(timeout, parent) { + } + +protected: + + virtual bool action() { //The information message box is created in the constructor itself of - //RemoteObjectChooser, so the RemoteObjectChooser can not be passed as - //an argument when this helper is created. It must be got when it is + //RemoteObjectChooser, so the information message box can not be passed + //as an argument when this helper is created. It must be got when it is //going to be destroyed. - QWidget* widget = findRemoteObjectChooser(); - QVERIFY(widget); + KDialog* messageBox = findInformationMessageBox(); + if (!messageBox) { + return false; + } - KDialog* messageBox = widget->findChild<KDialog*>("information"); - QVERIFY(messageBox); delete messageBox; + + return true; } +}; - void closeSorry() const { +class CloseInformationMessageBoxOnceTargetApplicationEndsHelper: + public CloseInformationMessageBoxHelper { +public: + + CloseInformationMessageBoxOnceTargetApplicationEndsHelper(int timeout, + QObject* parent): + CloseInformationMessageBoxHelper(timeout, parent) { + } + +protected: + + virtual bool action() { + if (TargetApplication::self()->remoteEditorSupport()) { + return false; + } + + return CloseInformationMessageBoxHelper::action(); + } +}; + +class CloseSorryMessageBoxHelper: public QueuedAction { +public: + + CloseSorryMessageBoxHelper(int timeout, QObject* parent): + QueuedAction(timeout, parent), + mWidget(0) { + } + + void setWidget(QWidget* widget) { + mWidget = widget; + } + +protected: + + virtual bool action() { KDialog* messageBox = mWidget->findChild<KDialog*>("sorry"); - QVERIFY(messageBox); + if (!messageBox) { + return false; + } + delete messageBox; - } - void killTargetApplication() const { - TargetApplication::self()->mProcess->kill(); + return true; } private: QWidget* mWidget; - QWidget* findRemoteObjectChooser() const { - foreach (QWidget* widget, QApplication::topLevelWidgets()) { - if (qobject_cast<RemoteObjectChooser*>(widget)) { - return widget; - } +}; + +class KillTargetApplicationOnceMessageBoxIsShownHelper: public QueuedAction { +public: + + KillTargetApplicationOnceMessageBoxIsShownHelper(int timeout, + QObject* parent): + QueuedAction(timeout, parent) { + } + +protected: + + virtual bool action() { + //The information message box is created in the constructor itself of + //RemoteObjectChooser, so the information message box can not be passed + //as an argument when this helper is created. + KDialog* messageBox = findInformationMessageBox(); + if (!messageBox) { + return false; } - return 0; + TargetApplication::self()->mProcess->kill(); + + return true; } - }; void RemoteObjectChooserTest::closeInformationMessageBox(int timeToWait) { - QueuedActionsHelper* helper = new QueuedActionsHelper(this); - QTimer::singleShot(timeToWait, helper, SLOT(closeInformation())); + CloseInformationMessageBoxHelper* helper = + new CloseInformationMessageBoxHelper(timeToWait, this); + helper->run(); } +void RemoteObjectChooserTest:: + closeInformationMessageBoxOnceTargetApplicationEnds(int timeToWait) { + CloseInformationMessageBoxOnceTargetApplicationEndsHelper* helper = + new CloseInformationMessageBoxOnceTargetApplicationEndsHelper( + timeToWait, this); + helper->run(); +} + void RemoteObjectChooserTest::closeSorryMessageBox(QWidget* widget, int timeToWait) { - QueuedActionsHelper* helper = new QueuedActionsHelper(this); + CloseSorryMessageBoxHelper* helper = new CloseSorryMessageBoxHelper( + timeToWait, this); helper->setWidget(widget); - QTimer::singleShot(timeToWait, helper, SLOT(closeSorry())); + helper->run(); } -void RemoteObjectChooserTest::killTargetApplication(int timeToWait) { - QueuedActionsHelper* helper = new QueuedActionsHelper(this); - QTimer::singleShot(timeToWait, helper, SLOT(killTargetApplication())); +void RemoteObjectChooserTest::killTargetApplicationOnceMessageBoxIsShown( + int timeToWait) { + KillTargetApplicationOnceMessageBoxIsShownHelper* helper = + new KillTargetApplicationOnceMessageBoxIsShownHelper(timeToWait, this); + helper->run(); } +template <typename Class> +bool waitFor(Class &object, bool (Class::*condition)() const, int timeout) { + QElapsedTimer timer; + timer.start(); + do { + QTest::qWait(100); + } while (!(object.*condition)() && timer.elapsed() < timeout); + + if (timer.elapsed() >= timeout) { + return false; + } + + return true; +} + +bool RemoteObjectChooserTest::waitForSorryMessageBoxToBeClosed(QWidget* widget, + int timeout) { + CloseSorryMessageBoxHelper* helper = new CloseSorryMessageBoxHelper(timeout, + this); + helper->setWidget(widget); + helper->run(); + + waitFor<QueuedAction>(*helper, &QueuedAction::isFinished, timeout); + + return helper->isActionDone(); +} + bool waitFor(bool (*condition)(), int timeout) { QElapsedTimer timer; timer.start(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |