summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@qt.io>2020-08-06 11:19:30 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2020-08-10 11:30:24 +0000
commit0c7536902901a882fd3e58f5314d03a37a386033 (patch)
treeec22a507b9df698bac9efe3c731802a819d9a4de
parent53b71057390a31532517fead1eda1be2c503f6ef (diff)
Fix flaky autotest with a delayed event in scion
Before the historical fix for the issue (commit 3da30ee8928ab27249a74966ed4981766d62ff25) the playEvent() method submitted directly the delayed event and it tried to verify the configuration just after. It couldn't work, since the event was delayed, so the demanded configuration couldn't be reached yet - it was checked too early. After the mentioned fix, we didn't submit an event immediately, but waited demanded time (in hope, that statemachine reaches the configuration expected after a delay) to mimic the delay, and after that, we submitted a non-delayed event directly. This could also cause issues like these mentioned in task description. The reason could be a race between the point in time when statemachine issues the delayed "s" event and the point in time when we submit the "t2" event. It could happen, that we submit "t2" while still being in "b" state (so before the statemachine issues the "s" event), and in this case the "t2" event doesn't trigger any change in the statemachine, thus the configuration stay unchanged. In the current fix we go back to the original idea of submitting the delayed event directly, but we are delaying the point in time when we do check the configuration expected after the event is dispatched. So is case of delayed event we connect to the statemachine's signal emitted when the event is being dispatched. After the connection is established, we submit a delayed event and start awaiting for the right moment when we should expect the stabilized configuration. This will be signalled with a timeout of trigger timer object. When the submitted event has been dispatched (after the desired delay), we connect synchronously to state machine's reachedStableState() signal. When reachedStableState() is received, we trigger the timer to unwind from synchronously called slot and to get back to the place where we were awaiting for timer to be triggered. Now we should expect the right configuration. The above approach works nicely also in case of playing non-delayed events. Fixes: QTBUG-83420 Change-Id: Ia6ddbc6ac9282a2dd41e0c99dd1bb59610690c95 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> (cherry picked from commit 2427b675711119c6aac68b662434eb8a0910c3a3) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--tests/auto/scion/tst_scion.cpp25
1 files changed, 20 insertions, 5 deletions
diff --git a/tests/auto/scion/tst_scion.cpp b/tests/auto/scion/tst_scion.cpp
index 5473e9d..d1e4873 100644
--- a/tests/auto/scion/tst_scion.cpp
+++ b/tests/auto/scion/tst_scion.cpp
@@ -329,18 +329,33 @@ static bool playEvent(QScxmlStateMachine *stateMachine, const QJsonObject &event
e->setOrigin(origin);
e->setOriginType(origintype);
e->setInvokeId(invokeid);
- if (eventDescription.contains(QLatin1String("after")))
- QTest::qWait(eventDescription.value(QLatin1String("after")).toInt());
+ int delay = 0;
+ if (eventDescription.contains(QLatin1String("after"))) {
+ delay = eventDescription.value(QLatin1String("after")).toInt();
+ Q_ASSERT(delay > 0);
+ e->setDelay(delay);
+ }
+
+ QTimer trigger;
+ trigger.setSingleShot(true);
+ stateMachine->connectToEvent(eventName, &trigger, [&stateMachine, &trigger](const QScxmlEvent &) {
+ QObject::connect(stateMachine, &QScxmlStateMachine::reachedStableState,
+ &trigger, QOverload<>::of(&QTimer::start));
+ });
+ MySignalSpy triggerSpy(&trigger, SIGNAL(timeout()));
stateMachine->submitEvent(e);
- if (!MySignalSpy(stateMachine, SIGNAL(reachedStableState())).fastWait()) {
- qWarning() << "State machine did not reach a stable state!";
+ if (!triggerSpy.fastWait()) {
+ qWarning() << "State machine did not reach a stable state.";
} else if (verifyStates(stateMachine, eventDescription, QLatin1String("nextConfiguration"), counter)) {
return true;
}
- qWarning() << "... after sending event" << event;
+ if (delay > 0)
+ qWarning("... after sending delayed event %s with a delay of %dms.", qPrintable(eventName), delay);
+ else
+ qWarning("... after sending event %s.", qPrintable(eventName));
return false;
}