summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ivicore/qiviservicemanager.cpp26
-rw-r--r--src/ivicore/qiviservicemanager_p.h2
-rw-r--r--src/tools/ivigenerator/templates/test/tst_test.cpp.tpl1
-rw-r--r--tests/auto/core/servicemanagertest/tst_servicemanagertest.cpp97
4 files changed, 85 insertions, 41 deletions
diff --git a/src/ivicore/qiviservicemanager.cpp b/src/ivicore/qiviservicemanager.cpp
index c1193a8..0eb16d8 100644
--- a/src/ivicore/qiviservicemanager.cpp
+++ b/src/ivicore/qiviservicemanager.cpp
@@ -97,7 +97,10 @@ namespace qtivi_helper {
using namespace qtivi_helper;
-QIviServiceManagerPrivate::QIviServiceManagerPrivate(QIviServiceManager *parent) : QObject(parent), q_ptr(parent)
+QIviServiceManagerPrivate::QIviServiceManagerPrivate(QIviServiceManager *parent)
+ : QObject(parent)
+ , m_staticLoaded(false)
+ , q_ptr(parent)
{
}
@@ -161,8 +164,13 @@ QList<QIviServiceObject *> QIviServiceManagerPrivate::findServiceByInterface(con
void QIviServiceManagerPrivate::searchPlugins()
{
bool found = false;
+
const auto pluginDirs = QCoreApplication::libraryPaths();
for (const QString &pluginDir : pluginDirs) {
+ // Already loaded, skip it...
+ if (m_loadedPaths.contains(pluginDir))
+ continue;
+ m_loadedPaths << pluginDir;
QString path = pluginDir + QDir::separator() + QLatin1String(QIVI_PLUGIN_DIRECTORY);
QDir dir(path);
@@ -183,11 +191,16 @@ void QIviServiceManagerPrivate::searchPlugins()
found = true;
}
}
- const auto staticPlugins = QPluginLoader::staticPlugins();
- for (const QStaticPlugin &plugin : staticPlugins)
- registerStaticBackend(plugin);
- if (Q_UNLIKELY(!found))
+ // Only load the static plugins once
+ if (!m_staticLoaded) {
+ m_staticLoaded = true;
+ const auto staticPlugins = QPluginLoader::staticPlugins();
+ for (const QStaticPlugin &plugin : staticPlugins)
+ registerStaticBackend(plugin);
+ }
+
+ if (Q_UNLIKELY(!found && m_backends.count() == 0))
qWarning() << "No plugins found in search path: " << QCoreApplication::libraryPaths().join(QLatin1String(":"));
}
@@ -294,6 +307,8 @@ void QIviServiceManagerPrivate::unloadAllBackends()
q->endResetModel();
m_interfaceNames.clear();
+ m_loadedPaths.clear();
+ m_staticLoaded = false;
}
void QIviServiceManagerPrivate::addBackend(Backend *backend)
@@ -535,6 +550,7 @@ QIviServiceManager *QIviServiceManager::instance()
QList<QIviServiceObject *> QIviServiceManager::findServiceByInterface(const QString &interface, SearchFlags searchFlags)
{
Q_D(QIviServiceManager);
+ d->searchPlugins();
return d->findServiceByInterface(interface, searchFlags);
}
diff --git a/src/ivicore/qiviservicemanager_p.h b/src/ivicore/qiviservicemanager_p.h
index 71c56ed..02533d0 100644
--- a/src/ivicore/qiviservicemanager_p.h
+++ b/src/ivicore/qiviservicemanager_p.h
@@ -108,6 +108,8 @@ public:
QList<Backend*> m_backends;
QSet<QString> m_interfaceNames;
+ QStringList m_loadedPaths;
+ bool m_staticLoaded;
QIviServiceManager * const q_ptr;
Q_DECLARE_PUBLIC(QIviServiceManager)
diff --git a/src/tools/ivigenerator/templates/test/tst_test.cpp.tpl b/src/tools/ivigenerator/templates/test/tst_test.cpp.tpl
index d8bd0ee..d725b8b 100644
--- a/src/tools/ivigenerator/templates/test/tst_test.cpp.tpl
+++ b/src/tools/ivigenerator/templates/test/tst_test.cpp.tpl
@@ -259,6 +259,7 @@ private:
{{interface}}Test::{{interface}}Test()
: QObject()
{
+ QCoreApplication::setLibraryPaths(QStringList());
{{module.module_name|upperfirst}}Module::registerTypes();
manager = QIviServiceManager::instance();
}
diff --git a/tests/auto/core/servicemanagertest/tst_servicemanagertest.cpp b/tests/auto/core/servicemanagertest/tst_servicemanagertest.cpp
index 1923ee6..5c0ba96 100644
--- a/tests/auto/core/servicemanagertest/tst_servicemanagertest.cpp
+++ b/tests/auto/core/servicemanagertest/tst_servicemanagertest.cpp
@@ -87,6 +87,9 @@ class ServiceManagerTest : public QObject
public:
ServiceManagerTest();
+ void ignoreStaticPluginWarnings();
+ void ignoreDynamicPluginWarnings();
+
private Q_SLOTS:
void initTestCase();
void cleanup();
@@ -110,35 +113,63 @@ ServiceManagerTest::ServiceManagerTest()
{
}
+void ServiceManagerTest::ignoreStaticPluginWarnings()
+{
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("PluginManager - Malformed metaData in static plugin '.*'. MetaData must contain a list of interfaces"));
+}
+
+void ServiceManagerTest::ignoreDynamicPluginWarnings()
+{
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("PluginManager - Malformed metaData in '.*'. MetaData must contain a list of interfaces"));
+#ifdef DEBUG_AND_RELEASE
+# ifndef Q_OS_WIN
+ // Because the plugin is build in both configurations, the error is also emitted twice
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("PluginManager - Malformed metaData in '.*'. MetaData must contain a list of interfaces"));
+# endif
+
+ QTest::ignoreMessage(QtInfoMsg, QRegularExpression("Found the same plugin in two configurations. Using the '.*' configuration: .*"));
+#endif
+}
+
void ServiceManagerTest::initTestCase()
{
- QStringList origList = QCoreApplication::libraryPaths();
+ // Make sure the dynamic plugins can't be found in the beginning
QCoreApplication::setLibraryPaths(QStringList());
- QTest::ignoreMessage(QtWarningMsg, QRegularExpression("PluginManager - Malformed metaData in static plugin '.*'. MetaData must contain a list of interfaces"));
- QTest::ignoreMessage(QtWarningMsg, "No plugins found in search path: \"\"");
+ ignoreStaticPluginWarnings();
manager = QIviServiceManager::instance();
QList<QIviServiceObject *> services = manager->findServiceByInterface("simple_plugin");
QCOMPARE(services.count(), 0);
- QTest::ignoreMessage(QtWarningMsg, QRegularExpression("PluginManager - Malformed metaData in static plugin '.*'. MetaData must contain a list of interfaces"));
- QTest::ignoreMessage(QtWarningMsg, QRegularExpression("PluginManager - Malformed metaData in '.*'. MetaData must contain a list of interfaces"));
-#ifdef DEBUG_AND_RELEASE
- QTest::ignoreMessage(QtInfoMsg, QRegularExpression("Found the same plugin in two configurations. Using the '.*' configuration: .*"));
-#endif
- //Reset original setting
- QCoreApplication::setLibraryPaths(origList);
- QIviServiceManagerPrivate::get(manager)->searchPlugins();
+ // Unload all plugins and don't search for the static plugins to trigger the 'no plugins found' warning
+ manager->unloadAllBackends();
+ QIviServiceManagerPrivate::get(manager)->m_staticLoaded = true;
+
+ QTest::ignoreMessage(QtWarningMsg, "No plugins found in search path: \"\"");
+ services = manager->findServiceByInterface("simple_plugin_static");
+ QCOMPARE(services.count(), 0);
+
+ // Change the library path to the current directory to be able to test loading dynamic plugins
+ QCoreApplication::setLibraryPaths({QDir::currentPath()});
+ ignoreDynamicPluginWarnings();
- //Save the id of the service object. This needed in the pluginLoaderTest
+ // This needs to trigger a search for new plugins in the library path, as it is supposed to
+ // reevaluate QCoreApplication::libraryPaths();
services = manager->findServiceByInterface("simple_plugin");
QCOMPARE(services.count(), 1);
+ // Save the id of the service object. This needed in the pluginLoaderTest
m_simplePluginID = services.at(0)->id();
}
void ServiceManagerTest::cleanup()
{
manager->unloadAllBackends();
+
+ // Make sure to search for all plugins here explicitly to catch all expected warning messages
+ // Otherwise a findServiceByInterface call will implictly trigger it.
+ ignoreStaticPluginWarnings();
+ ignoreDynamicPluginWarnings();
+ QIviServiceManagerPrivate::get(manager)->searchPlugins();
}
void ServiceManagerTest::testRetakeSingleton()
@@ -251,10 +282,14 @@ void ServiceManagerTest::testRegisterNonServiceBackendInterfaceObject()
*/
void ServiceManagerTest::testManagerListModel()
{
+ // Because of the plugin loading test and the static plugins, we always have some backends already
+ // in the list
+ const int backendCount = manager->rowCount();
+
QSignalSpy managerModelSpy(manager, SIGNAL(rowsInserted(QModelIndex,int,int)));
// Sanity check
- QCOMPARE(manager->rowCount(), 0);
+ QCOMPARE(manager->rowCount(), backendCount);
QCOMPARE(managerModelSpy.count(), 0);
QCOMPARE(manager->data(QModelIndex(), QIviServiceManager::NameRole), QVariant());
QCOMPARE(manager->data(QModelIndex(), QIviServiceManager::ServiceObjectRole), QVariant());
@@ -264,11 +299,11 @@ void ServiceManagerTest::testManagerListModel()
MockServiceBackend *backend0 = new MockServiceBackend(manager);
bool regResult = manager->registerService(backend0, QStringList() << "Interface0");
QCOMPARE(regResult, true);
- QCOMPARE(manager->rowCount(), 1);
+ QCOMPARE(manager->rowCount(), backendCount + 1);
//QCOMPARE(manager->data(manager->index(0), Qt::DisplayRole).value<QIviServiceInterface*>(), backend0);
- QCOMPARE(manager->data(manager->index(0), QIviServiceManager::NameRole).toString(), QStringLiteral("MockServiceBackend"));
- QCOMPARE(manager->data(manager->index(0), QIviServiceManager::ServiceObjectRole).value<QIviProxyServiceObject*>()->d_ptr->m_serviceInterface, backend0);
- QCOMPARE(manager->data(manager->index(0), QIviServiceManager::InterfacesRole).toStringList(), QStringList() << "Interface0");
+ QCOMPARE(manager->data(manager->index(backendCount), QIviServiceManager::NameRole).toString(), QStringLiteral("MockServiceBackend"));
+ QCOMPARE(manager->data(manager->index(backendCount), QIviServiceManager::ServiceObjectRole).value<QIviProxyServiceObject*>()->d_ptr->m_serviceInterface, backend0);
+ QCOMPARE(manager->data(manager->index(backendCount), QIviServiceManager::InterfacesRole).toStringList(), QStringList() << "Interface0");
QCOMPARE(managerModelSpy.count(), 1);
// Extendend sanity check
QCOMPARE(manager->data(manager->index(0,0), Qt::UserRole + 200), QVariant());
@@ -277,32 +312,25 @@ void ServiceManagerTest::testManagerListModel()
MockServiceBackend *backend1 = new MockServiceBackend(manager);
regResult = manager->registerService(backend1, QStringList() << "Interface1" << "Interface2");
QCOMPARE(regResult, true);
- QCOMPARE(manager->rowCount(), 2);
- QCOMPARE(manager->data(manager->index(0), QIviServiceManager::NameRole).toString(), QStringLiteral("MockServiceBackend"));
- QCOMPARE(manager->data(manager->index(0), QIviServiceManager::ServiceObjectRole).value<QIviProxyServiceObject*>()->d_ptr->m_serviceInterface, backend0);
- QCOMPARE(manager->data(manager->index(0), QIviServiceManager::InterfacesRole).toStringList(), QStringList() << "Interface0");
- QCOMPARE(manager->data(manager->index(1), QIviServiceManager::NameRole).toString(), QStringLiteral("MockServiceBackend"));
- QCOMPARE(manager->data(manager->index(1), QIviServiceManager::ServiceObjectRole).value<QIviProxyServiceObject*>()->d_ptr->m_serviceInterface, backend1);
- QCOMPARE(manager->data(manager->index(1), QIviServiceManager::InterfacesRole).toStringList(), QStringList() << "Interface1" << "Interface2");
+ QCOMPARE(manager->rowCount(), backendCount + 2);
+ QCOMPARE(manager->data(manager->index(backendCount), QIviServiceManager::NameRole).toString(), QStringLiteral("MockServiceBackend"));
+ QCOMPARE(manager->data(manager->index(backendCount), QIviServiceManager::ServiceObjectRole).value<QIviProxyServiceObject*>()->d_ptr->m_serviceInterface, backend0);
+ QCOMPARE(manager->data(manager->index(backendCount), QIviServiceManager::InterfacesRole).toStringList(), QStringList() << "Interface0");
+ QCOMPARE(manager->data(manager->index(backendCount + 1), QIviServiceManager::NameRole).toString(), QStringLiteral("MockServiceBackend"));
+ QCOMPARE(manager->data(manager->index(backendCount + 1), QIviServiceManager::ServiceObjectRole).value<QIviProxyServiceObject*>()->d_ptr->m_serviceInterface, backend1);
+ QCOMPARE(manager->data(manager->index(backendCount + 1), QIviServiceManager::InterfacesRole).toStringList(), QStringList() << "Interface1" << "Interface2");
QCOMPARE(managerModelSpy.count(), 2);
// Register backend-2 with 'Interface1' and 'Interface2'. Should not result in any model changes
MockServiceBackend *backend2 = new MockServiceBackend(manager);
regResult = manager->registerService(backend2, QStringList() << "Interface1" << "Interface2");
QCOMPARE(regResult, true);
- QCOMPARE(manager->rowCount(), 3);
+ QCOMPARE(manager->rowCount(), backendCount + 3);
QCOMPARE(managerModelSpy.count(), 3);
}
void ServiceManagerTest::pluginLoaderTest()
{
- //Test the error message for plugins with invalid metadata
- QTest::ignoreMessage(QtWarningMsg, QRegularExpression("PluginManager - Malformed metaData in '(.*)wrongmetadata_plugin(.*)'. MetaData must contain a list of interfaces"));
- QTest::ignoreMessage(QtWarningMsg, QRegularExpression("PluginManager - Malformed metaData in static plugin 'WrongMetadataStaticPlugin'. MetaData must contain a list of interfaces"));
-#ifdef DEBUG_AND_RELEASE
- QTest::ignoreMessage(QtInfoMsg, QRegularExpression("Found the same plugin in two configurations. Using the '.*' configuration: .*"));
-#endif
- QIviServiceManagerPrivate::get(manager)->searchPlugins();
QVERIFY(manager->hasInterface("simple_plugin"));
QList<QIviServiceObject *> services = manager->findServiceByInterface("simple_plugin", QIviServiceManager::IncludeProductionBackends);
QCOMPARE(services.count(), 1);
@@ -320,10 +348,7 @@ void ServiceManagerTest::pluginLoaderTest()
//Test that the plugin is unloaded (or at least removed from the registry)
manager->unloadAllBackends();
- services = manager->findServiceByInterface("simple_plugin");
- QCOMPARE(services.count(), 0);
- services = manager->findServiceByInterface("simple_plugin_static");
- QCOMPARE(services.count(), 0);
+ QCOMPARE(manager->rowCount(), 0);
}
Q_IMPORT_PLUGIN(SimpleStaticPlugin)