aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qmlcachegen
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2018-03-09 16:40:38 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2018-03-20 09:44:11 +0000
commit64e90f393146dadb382d154e7d67a9109ab2492a (patch)
treec1079ff6af2c9fca9357a9313fffe5590e30dfce /tests/auto/qml/qmlcachegen
parent22b13921f8067f8a93164875a4ad59bed85b0400 (diff)
Fix QML data structure version checking for ahead-of-time generated files
We must also do version checking for QML and JS files that were compiled ahead of time and are embedded in resources. If the lookup for the original source code fails, then we must generate an appropriate error message. As an upside we get better error reporting when trying to load an empty file and Qt.include() now reports the error message in the statusText field. The error reporting for imported scripts was not changed as importing an empty script is (oddly) allowed. Task-number: QTBUG-66986 Change-Id: Ie0ef81af371a51ecf8c66ae7954d43f5cc6c12de Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'tests/auto/qml/qmlcachegen')
-rw-r--r--tests/auto/qml/qmlcachegen/qmlcachegen.pro2
-rw-r--r--tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp46
-rw-r--r--tests/auto/qml/qmlcachegen/versionchecks.qml4
3 files changed, 52 insertions, 0 deletions
diff --git a/tests/auto/qml/qmlcachegen/qmlcachegen.pro b/tests/auto/qml/qmlcachegen/qmlcachegen.pro
index a8b72224ba..bad912c781 100644
--- a/tests/auto/qml/qmlcachegen/qmlcachegen.pro
+++ b/tests/auto/qml/qmlcachegen/qmlcachegen.pro
@@ -8,4 +8,6 @@ workerscripts_test.files = worker.js worker.qml
workerscripts_test.prefix = /workerscripts
RESOURCES += workerscripts_test
+RESOURCES += versionchecks.qml
+
QT += core-private qml-private testlib
diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
index e36edca699..1c05005c90 100644
--- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
+++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
@@ -33,6 +33,7 @@
#include <QProcess>
#include <QLibraryInfo>
#include <QSysInfo>
+#include <QLoggingCategory>
#include <private/qqmlcomponent_p.h>
class tst_qmlcachegen: public QObject
@@ -48,6 +49,7 @@ private slots:
void errorOnArgumentsInSignalHandler();
void aheadOfTimeCompilation();
void functionExpressions();
+ void versionChecksForAheadOfTimeUnits();
void workerScripts();
};
@@ -280,6 +282,50 @@ void tst_qmlcachegen::aheadOfTimeCompilation()
QCOMPARE(result.toInt(), 42);
}
+static QQmlPrivate::CachedQmlUnit *temporaryModifiedCachedUnit = nullptr;
+
+void tst_qmlcachegen::versionChecksForAheadOfTimeUnits()
+{
+ QVERIFY(QFile::exists(":/versionchecks.qml"));
+ QCOMPARE(QFileInfo(":/versionchecks.qml").size(), 0);
+
+ Q_ASSERT(!temporaryModifiedCachedUnit);
+ QQmlMetaType::CachedUnitLookupError error = QQmlMetaType::CachedUnitLookupError::NoError;
+ const QV4::CompiledData::Unit *originalUnit = QQmlMetaType::findCachedCompilationUnit(QUrl("qrc:/versionchecks.qml"), &error);
+ QVERIFY(originalUnit);
+ QV4::CompiledData::Unit *tweakedUnit = (QV4::CompiledData::Unit *)malloc(originalUnit->unitSize);
+ memcpy(reinterpret_cast<void *>(tweakedUnit), reinterpret_cast<const void *>(originalUnit), originalUnit->unitSize);
+ tweakedUnit->version = QV4_DATA_STRUCTURE_VERSION - 1;
+ temporaryModifiedCachedUnit = new QQmlPrivate::CachedQmlUnit{tweakedUnit, nullptr, nullptr};
+
+ auto testHandler = [](const QUrl &url) -> const QQmlPrivate::CachedQmlUnit * {
+ if (url == QUrl("qrc:/versionchecks.qml"))
+ return temporaryModifiedCachedUnit;
+ return nullptr;
+ };
+ QQmlMetaType::prependCachedUnitLookupFunction(testHandler);
+
+ {
+ QQmlMetaType::CachedUnitLookupError error = QQmlMetaType::CachedUnitLookupError::NoError;
+ QVERIFY(!QQmlMetaType::findCachedCompilationUnit(QUrl("qrc:/versionchecks.qml"), &error));
+ QCOMPARE(error, QQmlMetaType::CachedUnitLookupError::VersionMismatch);
+ }
+
+ {
+ QQmlEngine engine;
+ QQmlComponent component(&engine, QUrl("qrc:/versionchecks.qml"));
+ QCOMPARE(component.status(), QQmlComponent::Error);
+ QCOMPARE(component.errorString(), QString("qrc:/versionchecks.qml:-1 File was compiled ahead of time with an incompatible version of Qt and the original file cannot be found. Please recompile\n"));
+ }
+
+ Q_ASSERT(temporaryModifiedCachedUnit);
+ free(const_cast<QV4::CompiledData::Unit *>(temporaryModifiedCachedUnit->qmlData));
+ delete temporaryModifiedCachedUnit;
+ temporaryModifiedCachedUnit = nullptr;
+
+ QQmlMetaType::removeCachedUnitLookupFunction(testHandler);
+}
+
void tst_qmlcachegen::workerScripts()
{
QVERIFY(QFile::exists(":/workerscripts/worker.js"));
diff --git a/tests/auto/qml/qmlcachegen/versionchecks.qml b/tests/auto/qml/qmlcachegen/versionchecks.qml
new file mode 100644
index 0000000000..77d67e7da4
--- /dev/null
+++ b/tests/auto/qml/qmlcachegen/versionchecks.qml
@@ -0,0 +1,4 @@
+import QtQml 2.0
+QtObject {
+ property bool ok: true
+}