Details
-
Bug
-
Resolution: Done
-
P2: Important
-
None
-
5.1.0
-
N/A
Description
QQuickLoader has an auto test for asynchronous loading together with an incubation controller. Due to the asynchronous nature of tst_QQuickLoader::asynchronous(), the test is almost always passing, but randomly fails when the CPU load in CI is high enough. The failure is easy to reproduce by adding QTest::qWait() after loading the source, but before starting the incubation controller:
diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp index 50ded4d..e7ab2d5 100644 --- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp +++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp @@ -920,50 +920,51 @@ void tst_QQuickLoader::asynchronous_data() void tst_QQuickLoader::asynchronous() { QFETCH(QUrl, qmlFile); QFETCH(QStringList, expectedWarnings); PeriodicIncubationController *controller = new PeriodicIncubationController; QQmlIncubationController *previous = engine.incubationController(); engine.setIncubationController(controller); delete previous; QQmlComponent component(&engine, testFileUrl("asynchronous.qml")); QQuickItem *root = qobject_cast<QQuickItem*>(component.create()); QVERIFY(root); QQuickLoader *loader = root->findChild<QQuickLoader*>("loader"); QVERIFY(loader); foreach (const QString &warning, expectedWarnings) QTest::ignoreMessage(QtWarningMsg, warning.toUtf8().constData()); QVERIFY(!loader->item()); QCOMPARE(loader->progress(), 0.0); root->setProperty("comp", qmlFile.toString()); QMetaObject::invokeMethod(root, "loadComponent"); QVERIFY(!loader->item()); + QTest::qWait(1000); if (expectedWarnings.isEmpty()) { QCOMPARE(loader->status(), QQuickLoader::Loading); controller->start(); QVERIFY(!controller->incubated); // asynchronous compilation means not immediately compiled/incubating. QTRY_VERIFY(controller->incubated); // but should start incubating once compilation is complete. QTRY_VERIFY(loader->item()); QCOMPARE(loader->progress(), 1.0); QCOMPARE(loader->status(), QQuickLoader::Ready); } else { QTRY_COMPARE(loader->progress(), 1.0); QTRY_COMPARE(loader->status(), QQuickLoader::Error); } delete root; }
As soon as the asynchronous loading of the source is finished, QQuickLoader calls QQmlComponent::create(), which in turn calls QQmlEngitePrivate::incubate(). Thus, the incubation starts regardless of an incubation controller:
#0 QQmlEnginePrivate::incubate (this=0x71c160, i=..., forContext=0x76d700) at qml/qqmlincubator.cpp:55 #1 0x00007ffff74b96ab in QQmlComponent::create (this=0x755b20, incubator=..., context=0x7695a0, forContext=0x0) at qml/qqmlcomponent.cpp:1061 #2 0x00007ffff7bfa963 in QQuickLoaderPrivate::_q_sourceLoaded (this=0x759750) at items/qquickloader.cpp:718 #3 0x00007ffff7bfb1d5 in QQuickLoader::qt_static_metacall (_o=0x7596a0, _c=QMetaObject::InvokeMetaMethod, _id=8, _a=0x7fffffffc550) at .moc/debug-shared/moc_qquickloader_p.cpp:162 #4 0x00007ffff61c7f96 in QMetaObject::activate (sender=0x755b20, signalOffset=3, local_signal_index=0, argv=0x7fffffffc550) at kernel/qobject.cpp:3479 #5 0x00007ffff61c77ea in QMetaObject::activate (sender=0x755b20, m=0x7ffff7984020 <QQmlComponent::staticMetaObject>, local_signal_index=0, argv=0x7fffffffc550) at kernel/qobject.cpp:3354 #6 0x00007ffff7665f48 in QQmlComponent::statusChanged (this=0x755b20, _t1=QQmlComponent::Ready) at .moc/debug-shared/moc_qqmlcomponent.cpp:247 #7 0x00007ffff74b74fe in QQmlComponentPrivate::typeDataReady (this=0x769210) at qml/qqmlcomponent.cpp:332 #8 0x00007ffff750ef26 in QQmlTypeData::completed (this=0x769710) at qml/qqmltypeloader.cpp:2022 #9 0x00007ffff75095cf in QQmlDataLoaderThread::callCompletedMain (this=0x71ada0, b=0x769710) at qml/qqmltypeloader.cpp:805 #10 0x00007ffff751d607 in QQmlThread::I::call (this=0x7fffe0036b70, thread=0x71ada0) at /home/jpnurmi/Projects/qt5-stable/qtbase/include/QtQml/5.1.0/QtQml/private/../../../../../../qtdeclarative/src/qml/qml/ftw/qqmlthread_p.h:295 #11 0x00007ffff759f61a in QQmlThreadPrivate::mainEvent (this=0x71b8e0) at qml/ftw/qqmlthread.cpp:162 #12 0x00007ffff759f3f0 in QQmlThreadPrivate::MainObject::event (this=0x71b938, e=0x7fffe00098b0) at qml/ftw/qqmlthread.cpp:122 #13 0x00007ffff61879b6 in QCoreApplicationPrivate::notify_helper (this=0x644180, receiver=0x71b938, event=0x7fffe00098b0) at kernel/qcoreapplication.cpp:988 #14 0x00007ffff618768c in QCoreApplication::notify (this=0x7fffffffdc80, receiver=0x71b938, event=0x7fffe00098b0) at kernel/qcoreapplication.cpp:933 #15 0x00007ffff675efb2 in QGuiApplication::notify (this=0x7fffffffdc80, object=0x71b938, event=0x7fffe00098b0) at kernel/qguiapplication.cpp:1216 #16 0x00007ffff6187594 in QCoreApplication::notifyInternal (this=0x7fffffffdc80, receiver=0x71b938, event=0x7fffe00098b0) at kernel/qcoreapplication.cpp:871 #17 0x00007ffff618b215 in QCoreApplication::sendEvent (receiver=0x71b938, event=0x7fffe00098b0) at ../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:232 #18 0x00007ffff61888de in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x6442b0) at kernel/qcoreapplication.cpp:1473 #19 0x00007ffff618827f in QCoreApplication::sendPostedEvents (receiver=0x0, event_type=0) at kernel/qcoreapplication.cpp:1333 #20 0x00007ffff61f8db3 in postEventSourceDispatch (s=0x650300) at kernel/qeventdispatcher_glib.cpp:279 #21 0x00000036fc247a55 in g_main_dispatch (context=0x64ff20) at gmain.c:2715 #22 g_main_context_dispatch (context=context@entry=0x64ff20) at gmain.c:3219 #23 0x00000036fc247d88 in g_main_context_iterate (context=context@entry=0x64ff20, block=block@entry=0, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3290 #24 0x00000036fc247e44 in g_main_context_iteration (context=0x64ff20, may_block=0) at gmain.c:3351 #25 0x00007ffff61f9589 in QEventDispatcherGlib::processEvents (this=0x647cf0, flags=...) at kernel/qeventdispatcher_glib.cpp:426 #26 0x00007fffeee995e6 in QPAEventDispatcherGlib::processEvents (this=0x647cf0, flags=...) at eventdispatchers/qeventdispatcher_glib.cpp:123 #27 0x00007ffff6187ab9 in QCoreApplication::processEvents (flags=..., maxtime=1000) at kernel/qcoreapplication.cpp:1069 #28 0x0000000000407cfa in QTest::qWait (ms=1000) at /home/jpnurmi/Projects/qt5-stable/qtbase/include/QtTest/../../src/testlib/qtestsystem.h:66