diff options
Diffstat (limited to 'tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp')
-rw-r--r-- | tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp | 94 |
1 files changed, 60 insertions, 34 deletions
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp index 721ac27020..f4ecf5bfb3 100644 --- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp +++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp @@ -1,6 +1,6 @@ // Copyright (C) 2020 The Qt Company Ltd. // Copyright (C) 2021 Intel Corporation. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> #include <QSignalSpy> @@ -16,6 +16,8 @@ # include <QtCore/private/qmachparser_p.h> #endif +using namespace Qt::StringLiterals; + // Helper macros to let us know if some suffixes are valid #define bundle_VALID false #define dylib_VALID false @@ -128,7 +130,7 @@ static std::unique_ptr<QTemporaryFile> patchElf(const QString &source, ElfPatche const char *basename = QTest::currentDataTag(); if (!basename) basename = QTest::currentTestFunction(); - tmplib.reset(new QTemporaryFile(basename + QString(".XXXXXX" SUFFIX))); + tmplib.reset(new QTemporaryFile(QDir::currentPath() + u'/' + basename + u".XXXXXX" SUFFIX ""_s)); QVERIFY2(tmplib->open(), qPrintable(tmplib->errorString())); // sanity-check @@ -206,6 +208,7 @@ private slots: void preloadedPlugin_data(); void preloadedPlugin(); void staticPlugins(); + void reregisteredStaticPlugins(); }; Q_IMPORT_PLUGIN(StaticPlugin) @@ -277,7 +280,9 @@ void tst_QPluginLoader::errorString() QVERIFY(!unloaded); } -#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC) && !defined(Q_OS_HPUX) +// A bug in QNX causes the test to crash on exit after attempting to load +// a shared library with undefined symbols (tracked as QTBUG-114682). +#if !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN) && !defined(Q_OS_HPUX) && !defined(Q_OS_QNX) { QPluginLoader loader( sys_qualifiedLibraryName("almostplugin")); //a plugin with unresolved symbols loader.setLoadHints(QLibrary::ResolveAllSymbolsHint); @@ -337,16 +342,34 @@ void tst_QPluginLoader::loadHints() QCOMPARE(loader.loadHints(), QLibrary::PreventUnloadHint); //Do not crash loader.setLoadHints(QLibrary::ResolveAllSymbolsHint); QCOMPARE(loader.loadHints(), QLibrary::ResolveAllSymbolsHint); + // We can clear load hints when file name is not set. + loader.setLoadHints(QLibrary::LoadHints{}); + QCOMPARE(loader.loadHints(), QLibrary::LoadHints{}); + // Set the hints again + loader.setLoadHints(QLibrary::ResolveAllSymbolsHint); + QCOMPARE(loader.loadHints(), QLibrary::ResolveAllSymbolsHint); loader.setFileName( sys_qualifiedLibraryName("theplugin")); //a plugin QCOMPARE(loader.loadHints(), QLibrary::ResolveAllSymbolsHint); + QPluginLoader loader4; + QCOMPARE(loader4.loadHints(), QLibrary::PreventUnloadHint); + loader4.setLoadHints(QLibrary::LoadHints{}); + QCOMPARE(loader4.loadHints(), QLibrary::LoadHints{}); + loader4.setFileName(sys_qualifiedLibraryName("theplugin")); + // Hints are merged with hints from the previous loader. + QCOMPARE(loader4.loadHints(), QLibrary::ResolveAllSymbolsHint); + // We cannot clear load hints after associating the loader with a file. + loader.setLoadHints(QLibrary::LoadHints{}); + QCOMPARE(loader.loadHints(), QLibrary::ResolveAllSymbolsHint); + QPluginLoader loader2; QCOMPARE(loader2.loadHints(), QLibrary::PreventUnloadHint); loader2.setFileName(sys_qualifiedLibraryName("theplugin")); - QCOMPARE(loader2.loadHints(), QLibrary::PreventUnloadHint); + // Hints are merged with hints from previous loaders. + QCOMPARE(loader2.loadHints(), QLibrary::PreventUnloadHint | QLibrary::ResolveAllSymbolsHint); QPluginLoader loader3(sys_qualifiedLibraryName("theplugin")); - QCOMPARE(loader3.loadHints(), QLibrary::PreventUnloadHint); + QCOMPARE(loader3.loadHints(), QLibrary::PreventUnloadHint | QLibrary::ResolveAllSymbolsHint); } void tst_QPluginLoader::deleteinstanceOnUnload() @@ -376,14 +399,14 @@ void tst_QPluginLoader::deleteinstanceOnUnload() QVERIFY(spy2.isValid()); if (pass == 0) { QCOMPARE(loader2.unload(), false); // refcount not reached 0, not really unloaded - QCOMPARE(spy1.count(), 0); - QCOMPARE(spy2.count(), 0); + QCOMPARE(spy1.size(), 0); + QCOMPARE(spy2.size(), 0); } QCOMPARE(instance1->pluginName(), QLatin1String("Plugin ok")); QCOMPARE(instance2->pluginName(), QLatin1String("Plugin ok")); QVERIFY(loader1.unload()); // refcount reached 0, did really unload - QCOMPARE(spy1.count(), 1); - QCOMPARE(spy2.count(), 1); + QCOMPARE(spy1.size(), 1); + QCOMPARE(spy2.size(), 1); } } @@ -451,7 +474,7 @@ static void loadCorruptElfCommonRows() memcpy(h, &o, sizeof(o)); }); newRow("invalid-word-size", "file is for a different word size", [](H h) { - h->e_ident[EI_CLASS] = ELFCLASSNONE;; + h->e_ident[EI_CLASS] = ELFCLASSNONE; }); newRow("unknown-word-size", "file is for a different word size", [](H h) { h->e_ident[EI_CLASS] |= 0x40; @@ -837,26 +860,23 @@ void tst_QPluginLoader::loadMachO_data() # ifdef Q_PROCESSOR_X86_64 QTest::newRow("machtest/good.x86_64.dylib") << true; - QTest::newRow("machtest/good.i386.dylib") << false; + QTest::newRow("machtest/good.arm64.dylib") << false; QTest::newRow("machtest/good.fat.no-x86_64.dylib") << false; - QTest::newRow("machtest/good.fat.no-i386.dylib") << true; -# elif defined(Q_PROCESSOR_X86_32) - QTest::newRow("machtest/good.i386.dylib") << true; + QTest::newRow("machtest/good.fat.no-arm64.dylib") << true; +# elif defined(Q_PROCESSOR_ARM) + QTest::newRow("machtest/good.arm64.dylib") << true; QTest::newRow("machtest/good.x86_64.dylib") << false; - QTest::newRow("machtest/good.fat.no-i386.dylib") << false; + QTest::newRow("machtest/good.fat.no-arm64.dylib") << false; QTest::newRow("machtest/good.fat.no-x86_64.dylib") << true; # endif -# ifndef Q_PROCESSOR_POWER_64 - QTest::newRow("machtest/good.ppc64.dylib") << false; -# endif QTest::newRow("machtest/good.fat.all.dylib") << true; QTest::newRow("machtest/good.fat.stub-x86_64.dylib") << false; - QTest::newRow("machtest/good.fat.stub-i386.dylib") << false; + QTest::newRow("machtest/good.fat.stub-arm64.dylib") << false; QDir d(QFINDTESTDATA("machtest")); - QStringList badlist = d.entryList(QStringList() << "bad*.dylib"); - foreach (const QString &bad, badlist) + const QStringList badlist = d.entryList(QStringList() << "bad*.dylib"); + for (const QString &bad : badlist) QTest::newRow(qPrintable("machtest/" + bad)) << false; #endif } @@ -880,12 +900,7 @@ void tst_QPluginLoader::loadMachO() } QVERIFY(r.pos > 0); - QVERIFY(size_t(r.length) >= sizeof(void*)); QVERIFY(r.pos + r.length < data.size()); - QCOMPARE(r.pos & (sizeof(void*) - 1), 0UL); - - void *value = *(void**)(data.constData() + r.pos); - QCOMPARE(value, sizeof(void*) > 4 ? (void*)(0xc0ffeec0ffeeL) : (void*)0xc0ffee); // now that we know it's valid, let's try to make it invalid ulong offeredlen = r.pos; @@ -969,7 +984,7 @@ void tst_QPluginLoader::reloadPlugin() QSignalSpy spy(loader.instance(), &QObject::destroyed); QVERIFY(spy.isValid()); QVERIFY(loader.unload()); // refcount reached 0, did really unload - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); // reload plugin QVERIFY(loader.load()); @@ -1080,19 +1095,18 @@ void tst_QPluginLoader::staticPlugins() const QObjectList instances = QPluginLoader::staticInstances(); QVERIFY(instances.size()); - bool found = false; - for (QObject *obj : instances) { - found = obj->metaObject()->className() == QLatin1String("StaticPlugin"); - if (found) - break; - } - QVERIFY(found); + // ensure the our plugin only shows up once + int foundCount = std::count_if(instances.begin(), instances.end(), [](QObject *obj) { + return obj->metaObject()->className() == QLatin1String("StaticPlugin"); + }); + QCOMPARE(foundCount, 1); const auto plugins = QPluginLoader::staticPlugins(); QCOMPARE(plugins.size(), instances.size()); // find the metadata QJsonObject metaData; + bool found = false; for (const auto &p : plugins) { metaData = p.metaData(); found = metaData.value("className").toString() == QLatin1String("StaticPlugin"); @@ -1108,6 +1122,18 @@ void tst_QPluginLoader::staticPlugins() QCOMPARE(metaData.value("URI").toString(), "qt.test.pluginloader.staticplugin"); } +void tst_QPluginLoader::reregisteredStaticPlugins() +{ + // the Q_IMPORT_PLUGIN macro will have already done this + qRegisterStaticPluginFunction(qt_static_plugin_StaticPlugin()); + staticPlugins(); + if (QTest::currentTestFailed()) + return; + + qRegisterStaticPluginFunction(qt_static_plugin_StaticPlugin()); + staticPlugins(); +} + QTEST_MAIN(tst_QPluginLoader) #include "tst_qpluginloader.moc" |