diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-10-22 12:05:18 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-10-22 12:26:28 +0200 |
commit | aceb0d0cd2da89aebbf17729869b9e977290c826 (patch) | |
tree | b29e815e32277710058bc32c571281937183fd43 /tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp | |
parent | 6ecbe6441f825489b5fafde1a274952933254c7f (diff) | |
parent | 1bb9c7b517e7995201d2a31cd1e852c02ad8c1bc (diff) |
Merge remote-tracking branch 'origin/dev' into HEAD
Conflicts:
src/qml/compiler/qv4codegen.cpp
src/qml/compiler/qv4compileddata.cpp
src/qml/compiler/qv4compileddata_p.h
src/qml/compiler/qv4isel_moth_p.h
src/qml/compiler/qv4ssa.cpp
src/qml/jit/qv4assembler_p.h
src/qml/jit/qv4isel_masm_p.h
src/qml/jit/qv4regalloc.cpp
src/qml/jsruntime/qv4engine.cpp
src/qml/jsruntime/qv4qmlcontext_p.h
src/qml/jsruntime/qv4regexp.cpp
src/qml/jsruntime/qv4regexp_p.h
src/qml/jsruntime/qv4regexpobject.cpp
src/qml/jsruntime/qv4runtime.cpp
src/qml/jsruntime/qv4vme_moth.cpp
src/qml/qml/v8/qqmlbuiltinfunctions.cpp
tests/auto/qml/qml.pro
tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp
tools/qmlcachegen/qmlcachegen.cpp
Change-Id: I1577e195c736f3414089036b957a01cb91a3ca23
Diffstat (limited to 'tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp')
-rw-r--r-- | tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp | 59 |
1 files changed, 51 insertions, 8 deletions
diff --git a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp index d0a8b6401f..7e9a1524b0 100644 --- a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp +++ b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp @@ -31,6 +31,8 @@ #include <QtQml/qqml.h> #include <QtQml/QQmlEngine> #include <QtQml/QQmlComponent> +#include <private/qhashedstring_p.h> +#include <private/qqmlmetatype_p.h> //Separate test, because if engine cleanup attempts fail they can easily break unrelated tests class tst_qqmlenginecleanup : public QQmlDataTest @@ -44,41 +46,82 @@ private slots: void test_valueTypeProviderModule(); // QTBUG-43004 }; +// A wrapper around QQmlComponent to ensure the temporary reference counts +// on the type data as a result of the main thread <> loader thread communication +// are dropped. Regular Synchronous loading will leave us with an event posted +// to the gui thread and an extra refcount that will only be dropped after the +// event delivery. A plain sendPostedEvents() however is insufficient because +// we can't be sure that the event is posted after the constructor finished. +class CleanlyLoadingComponent : public QQmlComponent +{ +public: + CleanlyLoadingComponent(QQmlEngine *engine, const QUrl &url) + : QQmlComponent(engine, url, QQmlComponent::Asynchronous) + { waitForLoad(); } + CleanlyLoadingComponent(QQmlEngine *engine, const QString &fileName) + : QQmlComponent(engine, fileName, QQmlComponent::Asynchronous) + { waitForLoad(); } + + void waitForLoad() + { + QTRY_VERIFY(status() == QQmlComponent::Ready || status() == QQmlComponent::Error); + } +}; + void tst_qqmlenginecleanup::test_qmlClearTypeRegistrations() { //Test for preventing memory leaks is in tests/manual/qmltypememory QQmlEngine* engine; - QQmlComponent* component; + CleanlyLoadingComponent* component; QUrl testFile = testFileUrl("types.qml"); + const auto qmlTypeForTestType = []() { + return QQmlMetaType::qmlType(QStringLiteral("TestTypeCpp"), QStringLiteral("Test"), 2, 0); + }; + + QVERIFY(!qmlTypeForTestType().isValid()); qmlRegisterType<QObject>("Test", 2, 0, "TestTypeCpp"); + QVERIFY(qmlTypeForTestType().isValid()); + engine = new QQmlEngine; - component = new QQmlComponent(engine, testFile); + component = new CleanlyLoadingComponent(engine, testFile); QVERIFY(component->isReady()); - delete engine; delete component; - qmlClearTypeRegistrations(); + delete engine; + + { + auto cppType = qmlTypeForTestType(); + + qmlClearTypeRegistrations(); + QVERIFY(!qmlTypeForTestType().isValid()); + + // cppType should hold the last ref, qmlClearTypeRegistration should have wiped + // all internal references. + QCOMPARE(QQmlType::refCount(cppType.priv()), 1); + } //2nd run verifies that types can reload after a qmlClearTypeRegistrations qmlRegisterType<QObject>("Test", 2, 0, "TestTypeCpp"); + QVERIFY(qmlTypeForTestType().isValid()); engine = new QQmlEngine; - component = new QQmlComponent(engine, testFile); + component = new CleanlyLoadingComponent(engine, testFile); QVERIFY(component->isReady()); - delete engine; delete component; + delete engine; qmlClearTypeRegistrations(); + QVERIFY(!qmlTypeForTestType().isValid()); //3nd run verifies that TestTypeCpp is no longer registered engine = new QQmlEngine; - component = new QQmlComponent(engine, testFile); + component = new CleanlyLoadingComponent(engine, testFile); QVERIFY(component->isError()); QCOMPARE(component->errorString(), testFile.toString() +":33 module \"Test\" is not installed\n"); - delete engine; delete component; + delete engine; } static void cleanState(QQmlEngine **e) |