tests/auto/qservicemanager/tst_qservicemanager.cpp
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 #include <qservicemanager.h>
       
    42 #include <qservicecontext.h>
       
    43 #include <qabstractsecuritysession.h>
       
    44 #include <qserviceinterfacedescriptor_p.h>
       
    45 #include "../../sampleserviceplugin/sampleserviceplugin.h"
       
    46 #include "../qsfwtestutil.h"
       
    47 
       
    48 #include <QtTest/QtTest>
       
    49 #include <QtCore>
       
    50 #include <QSettings>
       
    51 #include <QFileInfo>
       
    52 #include <QDir>
       
    53 #include <QPair>
       
    54 
       
    55 #define QTRY_COMPARE(a,e)                       \
       
    56     for (int _i = 0; _i < 5000; _i += 100) {    \
       
    57         if ((a) == (e)) break;                  \
       
    58         QTest::qWait(100);                      \
       
    59     }                                           \
       
    60     QCOMPARE(a, e)
       
    61 
       
    62 #define QTRY_VERIFY(a)                       \
       
    63     for (int _i = 0; _i < 5000; _i += 100) {    \
       
    64         if (a) break;                  \
       
    65         QTest::qWait(100);                      \
       
    66     }                                           \
       
    67     QVERIFY(a)
       
    68 
       
    69 #define PRINT_ERR(a) qPrintable(QString("error = %1").arg(a.error()))
       
    70 
       
    71 typedef QList<QtMobility::QServiceInterfaceDescriptor> ServiceInterfaceDescriptorList;
       
    72 Q_DECLARE_METATYPE(QtMobility::QServiceFilter)
       
    73 Q_DECLARE_METATYPE(QtMobility::QServiceInterfaceDescriptor)
       
    74 Q_DECLARE_METATYPE(ServiceInterfaceDescriptorList)
       
    75 
       
    76 Q_DECLARE_METATYPE(QSet<QString>)
       
    77 Q_DECLARE_METATYPE(QList<QByteArray>)
       
    78 Q_DECLARE_METATYPE(QtMobility::QService::Scope)
       
    79 
       
    80 QTM_BEGIN_NAMESPACE
       
    81 typedef QHash<QtMobility::QServiceInterfaceDescriptor::Attribute, QVariant> DescriptorAttributes;
       
    82 
       
    83 inline uint qHash(const QtMobility::QServiceInterfaceDescriptor &desc)
       
    84 {
       
    85     return qHash(desc.serviceName()) + qHash(desc.interfaceName()) + desc.majorVersion() * 7 + desc.minorVersion() * 7;
       
    86 }
       
    87 QTM_END_NAMESPACE
       
    88 
       
    89 QTM_USE_NAMESPACE
       
    90 static DescriptorAttributes defaultDescriptorAttributes()
       
    91 {
       
    92     DescriptorAttributes props;
       
    93     //props[QServiceInterfaceDescriptor::Capabilities] = QStringList();
       
    94     props[QServiceInterfaceDescriptor::Location] = "";
       
    95     props[QServiceInterfaceDescriptor::ServiceDescription] = "";
       
    96     props[QServiceInterfaceDescriptor::InterfaceDescription] = "";
       
    97     return props;
       
    98 }
       
    99 static const DescriptorAttributes DEFAULT_DESCRIPTOR_PROPERTIES = defaultDescriptorAttributes();
       
   100 
       
   101 static QStringList validPluginFiles()
       
   102 {
       
   103     // these are the plugins under tests/ which point to real service plugins
       
   104     // that can be used for testing (i.e. plugins that can be loaded, invoked)
       
   105     QStringList files;
       
   106     files << "plugins/tst_sfw_sampleserviceplugin" << "plugins/tst_sfw_sampleserviceplugin2";
       
   107     return files;
       
   108 }
       
   109 static const QStringList VALID_PLUGIN_FILES = validPluginFiles();
       
   110 
       
   111 // Helper function for debugging. Useful e.g. for checking what is difference between
       
   112 // two descriptors (in addition to attributes printed below, the \
       
   113 // QServiceInterfaceDescriptor::== operator also compares
       
   114 // attributes.
       
   115 static void printDescriptor (QServiceInterfaceDescriptor &desc) {
       
   116     qDebug("***QServiceInterfaceDescriptor printed:");
       
   117     qDebug() << "***majorVersion:" << desc.majorVersion();
       
   118     qDebug() << "***minorVersion:" << desc.minorVersion();
       
   119     qDebug() << "***interfaceName:" << desc.interfaceName();
       
   120     qDebug() << "***serviceName:" << desc.serviceName();
       
   121     qDebug() << "***customAttributes:" << desc.customAttributes();
       
   122     qDebug() << "***isValid(): " << desc.isValid();
       
   123     qDebug() << "***scope (user:0, system:1): " << desc.scope();
       
   124 }
       
   125 
       
   126 class MySecuritySession : public QAbstractSecuritySession
       
   127 {
       
   128 public:
       
   129     MySecuritySession() {}
       
   130     virtual ~MySecuritySession() {}
       
   131 
       
   132     virtual bool isAllowed(const QStringList&) { return true; }
       
   133 };
       
   134 
       
   135 class MyServiceContext : public QServiceContext
       
   136 {
       
   137 public:
       
   138     MyServiceContext() {}
       
   139     ~MyServiceContext() {}
       
   140 
       
   141     virtual void notify(ContextType, const QVariant&) {}
       
   142 };
       
   143 
       
   144 
       
   145 class ServicesListener : public QObject
       
   146 {
       
   147     Q_OBJECT
       
   148 public slots:
       
   149     void serviceAdded(const QString &name , QService::Scope scope) {
       
   150         params.append(qMakePair(name, scope));
       
   151     }
       
   152     void serviceRemoved(const QString &name, QService::Scope scope) {
       
   153         params.append(qMakePair(name, scope));
       
   154     }
       
   155 public:
       
   156     QList<QPair<QString, QService::Scope> > params;
       
   157 };
       
   158 
       
   159 
       
   160 class tst_QServiceManager: public QObject
       
   161 {
       
   162     Q_OBJECT
       
   163 
       
   164 private:
       
   165     QString xmlTestDataPath(const QString &xmlFileName)
       
   166     {
       
   167         // On Symbian applicationDirPath returns application's private directory
       
   168         return QCoreApplication::applicationDirPath() + "/plugins/xmldata/" + xmlFileName;
       
   169     }
       
   170 
       
   171     QByteArray createServiceXml(const QString &serviceName, const QByteArray &interfaceXml, const QString &path, const QString &description = QString()) const
       
   172     {
       
   173         QString xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
       
   174         xml += "<service>\n";
       
   175         xml += "<name>" + serviceName + "</name>\n";
       
   176         xml += "<filepath>" + path + "</filepath>\n";
       
   177         xml += "<description>" + description + "</description>\n";
       
   178         xml += interfaceXml;
       
   179         xml += "</service>\n";
       
   180         return xml.toLatin1();
       
   181     }
       
   182 
       
   183     QByteArray createServiceXml(const QString &serviceName, const QList<QServiceInterfaceDescriptor> &descriptors) const
       
   184     {
       
   185         Q_ASSERT(descriptors.count() > 0);
       
   186         return createServiceXml(serviceName, createInterfaceXml(descriptors),
       
   187                 descriptors[0].attribute(QServiceInterfaceDescriptor::Location).toString(),
       
   188                 descriptors[0].attribute(QServiceInterfaceDescriptor::ServiceDescription).toString());
       
   189     }
       
   190 
       
   191     QByteArray createInterfaceXml(const QList<QServiceInterfaceDescriptor> &descriptors) const
       
   192     {
       
   193         QByteArray interfacesXml;
       
   194         foreach (const QServiceInterfaceDescriptor &desc, descriptors) {
       
   195             QString version = QString("%1.%2").arg(desc.majorVersion()).arg(desc.minorVersion());
       
   196             interfacesXml += createInterfaceXml(desc.interfaceName(), version,
       
   197                     desc.attribute(QServiceInterfaceDescriptor::InterfaceDescription).toString());
       
   198         }
       
   199         return interfacesXml;
       
   200     }
       
   201 
       
   202     QByteArray createInterfaceXml(const QString &name, const QString &version = "1.0", const QString &description = QString()) const
       
   203     {
       
   204        QString xml = "<interface>\n";
       
   205         xml += "<name>" + name + "</name>\n";
       
   206         xml += "<version>" + version + "</version>\n";
       
   207         xml += " <description>" + description + "</description>\n";
       
   208         xml += "</interface>\n";
       
   209         return xml.toLatin1();
       
   210 
       
   211     }
       
   212 
       
   213     QServiceInterfaceDescriptor createDescriptor(const QString &interfaceName, int major, int minor, const QString &serviceName, const DescriptorAttributes &attributes = DescriptorAttributes(), QService::Scope scope = QService::UserScope) const
       
   214     {
       
   215         QString version = QString("%1.%2").arg(major).arg(minor);
       
   216 
       
   217         QServiceInterfaceDescriptorPrivate *priv = new QServiceInterfaceDescriptorPrivate;
       
   218         priv->serviceName = serviceName;
       
   219         priv->interfaceName = interfaceName;
       
   220         priv->major = major;
       
   221         priv->minor = minor;
       
   222         priv->scope = scope;
       
   223 
       
   224         priv->attributes = attributes;
       
   225         foreach (QServiceInterfaceDescriptor::Attribute key, DEFAULT_DESCRIPTOR_PROPERTIES.keys()) {
       
   226             if (!priv->attributes.contains(key))
       
   227                 priv->attributes[key] = DEFAULT_DESCRIPTOR_PROPERTIES[key];
       
   228         }
       
   229 
       
   230         QServiceInterfaceDescriptor desc;
       
   231         QServiceInterfaceDescriptorPrivate::setPrivate(&desc, priv);
       
   232         return desc;
       
   233     }
       
   234 
       
   235     void deleteTestDatabasesAndWaitUntilDone()
       
   236     {
       
   237         QSfwTestUtil::removeTempUserDb();
       
   238         QSfwTestUtil::removeTempSystemDb();
       
   239 
       
   240         QTRY_VERIFY(!QFile::exists(QSfwTestUtil::tempUserDbDir()));
       
   241         QTRY_VERIFY(!QFile::exists(QSfwTestUtil::tempSystemDbDir()));
       
   242     }
       
   243 
       
   244 private slots:
       
   245     void initTestCase();
       
   246     void cleanupTestCase();
       
   247     void init();
       
   248 
       
   249     void constructor();
       
   250     void constructor_scope();
       
   251     void constructor_scope_data();
       
   252 
       
   253     void findServices();
       
   254     void findServices_data();
       
   255 
       
   256     void findServices_scope();
       
   257     void findServices_scope_data();
       
   258 
       
   259     void findInterfaces_filter();
       
   260     void findInterfaces_filter_data();
       
   261 
       
   262     void findInterfaces_scope();
       
   263     void findInterfaces_scope_data();
       
   264 
       
   265     void loadInterface_string();
       
   266 
       
   267     void loadInterface_descriptor();
       
   268     void loadInterface_descriptor_data();
       
   269 
       
   270     void loadInterface_testLoadedObjectAttributes();
       
   271 
       
   272     void loadLocalTypedInterface();
       
   273 
       
   274     void addService();
       
   275     void addService_data();
       
   276 
       
   277     void addService_testInvalidServiceXml();
       
   278     void addService_testPluginLoading();
       
   279     void addService_testPluginLoading_data();
       
   280     void addService_testInstallService();
       
   281 
       
   282     void removeService();
       
   283 
       
   284     void setInterfaceDefault_strings();
       
   285     void setInterfaceDefault_strings_multipleInterfaces();
       
   286 
       
   287     void setInterfaceDefault_descriptor();
       
   288     void setInterfaceDefault_descriptor_data();
       
   289 
       
   290     void interfaceDefault();
       
   291 
       
   292     void serviceAdded();
       
   293     void serviceAdded_data();
       
   294 
       
   295     void serviceRemoved();
       
   296     void serviceRemoved_data();
       
   297 };
       
   298 
       
   299 void tst_QServiceManager::initTestCase()
       
   300 {
       
   301     qRegisterMetaType<QService::Scope>("QService::Scope");
       
   302 
       
   303     QSfwTestUtil::setupTempUserDb();
       
   304     QSfwTestUtil::setupTempSystemDb();
       
   305 #if defined(Q_OS_SYMBIAN)
       
   306     QSfwTestUtil::removeDatabases_symbian();
       
   307 #endif
       
   308 }
       
   309 
       
   310 void tst_QServiceManager::init()
       
   311 {
       
   312 #if defined(Q_OS_SYMBIAN)
       
   313     // Wait a millisecond so that QServiceManagers are destroyed and release
       
   314     // the database file (otherwise QFile::remove will get a permission denied -->
       
   315     // in next case, the isEmpty() check fails).
       
   316     QTest::qWait(1);
       
   317 #endif
       
   318     QSfwTestUtil::removeTempUserDb();
       
   319     QSfwTestUtil::removeTempSystemDb();
       
   320 #if defined(Q_OS_SYMBIAN)
       
   321     QSfwTestUtil::removeDatabases_symbian();
       
   322 #endif
       
   323     QSettings settings("com.nokia.qt.serviceframework.tests", "SampleServicePlugin");
       
   324     settings.setValue("installed", false);
       
   325 }
       
   326 
       
   327 void tst_QServiceManager::cleanupTestCase()
       
   328 {
       
   329     QSfwTestUtil::removeTempUserDb();
       
   330     QSfwTestUtil::removeTempSystemDb();
       
   331 #if defined(Q_OS_SYMBIAN)
       
   332     QSfwTestUtil::removeDatabases_symbian();
       
   333 #endif
       
   334     //use QEventLopp::DeferredDeletion
       
   335     //QServiceManager::loadInterface makes use of deleteLater() when
       
   336     //cleaning up service objects and their respective QPluginLoader
       
   337     //we want to force the testcase to run the cleanup code
       
   338     QCoreApplication::processEvents(QEventLoop::AllEvents|QEventLoop::DeferredDeletion);
       
   339 }
       
   340 
       
   341 void tst_QServiceManager::constructor()
       
   342 {
       
   343     QObject o;
       
   344     QServiceManager mgr(&o);
       
   345     QCOMPARE(mgr.scope(), QService::UserScope);
       
   346     QCOMPARE(mgr.parent(), &o);
       
   347 }
       
   348 
       
   349 void tst_QServiceManager::constructor_scope()
       
   350 {
       
   351     QFETCH(QService::Scope, scope);
       
   352 
       
   353     QObject o;
       
   354     QServiceManager mgr(scope, &o);
       
   355     QCOMPARE(mgr.scope(), scope);
       
   356     QCOMPARE(mgr.parent(), &o);
       
   357 }
       
   358 
       
   359 void tst_QServiceManager::constructor_scope_data()
       
   360 {
       
   361     QTest::addColumn<QService::Scope>("scope");
       
   362 
       
   363     QTest::newRow("user") << QService::UserScope;
       
   364     QTest::newRow("system") << QService::SystemScope;
       
   365 }
       
   366 
       
   367 void tst_QServiceManager::findServices()
       
   368 {
       
   369     QFETCH(QList<QByteArray>, xmlBlocks);
       
   370     QFETCH(QStringList, interfaceNames);
       
   371     QFETCH(QSet<QString>, searchByInterfaceResult);
       
   372     QFETCH(QSet<QString>, searchAllResult);
       
   373 
       
   374     QServiceManager mgr;
       
   375     QServiceFilter wildcardFilter;
       
   376 
       
   377     // Check that nothing is found neither with default search or interface-search
       
   378     QVERIFY(mgr.findServices().isEmpty());
       
   379     foreach (const QString &interface, interfaceNames)
       
   380         QVERIFY(mgr.findServices(interface).isEmpty());
       
   381     QCOMPARE(mgr.findInterfaces(wildcardFilter).count(), 0);
       
   382 
       
   383     // Add all services from the xmlBlocks list
       
   384     foreach (const QByteArray &xml, xmlBlocks) {
       
   385         QBuffer buffer;
       
   386         buffer.setData(xml);
       
   387         QVERIFY2(mgr.addService(&buffer), PRINT_ERR(mgr));
       
   388     }
       
   389     // Check that all services are found with default search
       
   390     QCOMPARE(mgr.findServices().toSet(), searchAllResult);
       
   391     // Check that all services are found based on interface search
       
   392     foreach (const QString &interface, interfaceNames)
       
   393         QCOMPARE(mgr.findServices(interface).toSet(), searchByInterfaceResult);
       
   394 
       
   395     // Check that nothing is found with empty interface
       
   396     QCOMPARE(mgr.findServices("com.invalid.interface") , QStringList());
       
   397 }
       
   398 
       
   399 void tst_QServiceManager::findServices_data()
       
   400 {
       
   401     QTest::addColumn< QList<QByteArray> >("xmlBlocks");
       
   402     QTest::addColumn<QStringList>("interfaceNames");
       
   403     QTest::addColumn< QSet<QString> >("searchByInterfaceResult");
       
   404     QTest::addColumn< QSet<QString> >("searchAllResult");
       
   405 
       
   406     QStringList interfaces;
       
   407     interfaces << "com.nokia.qt.TestInterfaceA";
       
   408     interfaces << "com.nokia.qt.TestInterfaceB";
       
   409     QByteArray interfacesXml;
       
   410     for (int i=0; i<interfaces.count(); i++)
       
   411         interfacesXml += "\n" + createInterfaceXml(interfaces[i]);
       
   412 
       
   413     QTest::newRow("one service")
       
   414             << (QList<QByteArray>() << createServiceXml("SomeTestService", interfacesXml, VALID_PLUGIN_FILES.first()))
       
   415             << interfaces
       
   416             << (QSet<QString>() << "SomeTestService")
       
   417             << (QSet<QString>() << "SomeTestService");
       
   418 
       
   419     QTest::newRow("multiple services with same interfaces")
       
   420             << (QList<QByteArray>() << createServiceXml("SomeTestService", interfacesXml, VALID_PLUGIN_FILES[0])
       
   421                                     << createServiceXml("SomeSimilarTestService", interfacesXml, VALID_PLUGIN_FILES[1]))
       
   422             << interfaces
       
   423             << (QSet<QString>() << "SomeTestService" << "SomeSimilarTestService")
       
   424             << (QSet<QString>() << "SomeTestService" << "SomeSimilarTestService");
       
   425 
       
   426     QStringList interfaces2;
       
   427     interfaces2 << "com.nokia.qt.TestInterfaceY";
       
   428     interfaces2 << "com.nokia.qt.TestInterfaceZ";
       
   429     QByteArray interfacesXml2;
       
   430     for (int i=0; i<interfaces2.count(); i++)
       
   431         interfacesXml2 += "\n" + createInterfaceXml(interfaces2[i]);
       
   432     QTest::newRow("multiple services with different interfaces")
       
   433             << (QList<QByteArray>() << createServiceXml("SomeTestService", interfacesXml, VALID_PLUGIN_FILES[0])
       
   434                                     << createServiceXml("TestServiceWithOtherInterfaces", interfacesXml2, VALID_PLUGIN_FILES[1]))
       
   435             << interfaces2
       
   436             << (QSet<QString>() << "TestServiceWithOtherInterfaces")
       
   437             << (QSet<QString>() << "SomeTestService" << "TestServiceWithOtherInterfaces");
       
   438 }
       
   439 
       
   440 void tst_QServiceManager::findServices_scope()
       
   441 {
       
   442 #if defined(Q_OS_SYMBIAN)
       
   443     QSKIP("There is no difference between user and system scope in symbian", SkipAll);
       
   444 #endif
       
   445     QFETCH(QService::Scope, scope_add);
       
   446     QFETCH(QService::Scope, scope_find);
       
   447     QFETCH(bool, expectFound);
       
   448 
       
   449     QByteArray xml = createServiceXml("SomeTestService",
       
   450             createInterfaceXml("com.nokia.qt.TestInterface"), VALID_PLUGIN_FILES[0]);
       
   451     QBuffer buffer(&xml);
       
   452 
       
   453     QServiceManager mgrUser(QService::UserScope);
       
   454     QServiceManager mgrSystem(QService::SystemScope);
       
   455 
       
   456     QServiceManager &mgrAdd = scope_add == QService::UserScope ? mgrUser : mgrSystem;
       
   457     QServiceManager &mgrFind = scope_find == QService::UserScope ? mgrUser : mgrSystem;
       
   458 
       
   459     QVERIFY2(mgrAdd.addService(&buffer), PRINT_ERR(mgrAdd));
       
   460     QStringList result = mgrFind.findServices();
       
   461     QCOMPARE(!result.isEmpty(), expectFound);
       
   462 }
       
   463 
       
   464 void tst_QServiceManager::findServices_scope_data()
       
   465 {
       
   466     QTest::addColumn<QService::Scope>("scope_add");
       
   467     QTest::addColumn<QService::Scope>("scope_find");
       
   468     QTest::addColumn<bool>("expectFound");
       
   469 
       
   470     QTest::newRow("user scope")
       
   471             << QService::UserScope << QService::UserScope << true;
       
   472     QTest::newRow("system scope")
       
   473             << QService::SystemScope << QService::SystemScope << true;
       
   474 
       
   475     QTest::newRow("user scope - add, system scope - find")
       
   476             << QService::UserScope << QService::SystemScope << false;
       
   477     QTest::newRow("system scope - add, user scope - find")
       
   478             << QService::SystemScope << QService::UserScope << true;
       
   479 }
       
   480 
       
   481 void tst_QServiceManager::findInterfaces_filter()
       
   482 {
       
   483     QFETCH(QByteArray, xml);
       
   484     QFETCH(QServiceFilter, filter);
       
   485     QFETCH(QList<QServiceInterfaceDescriptor>, expectedInterfaces);
       
   486 
       
   487     QServiceManager mgr;
       
   488 
       
   489     QBuffer buffer(&xml);
       
   490     QVERIFY2(mgr.addService(&buffer), PRINT_ERR(mgr));
       
   491 
       
   492     QList<QServiceInterfaceDescriptor> result = mgr.findInterfaces(filter);
       
   493     QCOMPARE(result.toSet(), expectedInterfaces.toSet());
       
   494 }
       
   495 
       
   496 void tst_QServiceManager::findInterfaces_filter_data()
       
   497 {
       
   498     QTest::addColumn<QByteArray>("xml");
       
   499     QTest::addColumn<QServiceFilter>("filter");
       
   500     QTest::addColumn<ServiceInterfaceDescriptorList>("expectedInterfaces");
       
   501 
       
   502     QString serviceName = "SomeTestService";
       
   503     DescriptorAttributes attributes;
       
   504     attributes[QServiceInterfaceDescriptor::Location] = VALID_PLUGIN_FILES.first();
       
   505 
       
   506     QList<QServiceInterfaceDescriptor> descriptors;
       
   507     descriptors << createDescriptor("com.nokia.qt.TestInterfaceA", 1, 0, serviceName, attributes);
       
   508     descriptors << createDescriptor("com.nokia.qt.TestInterfaceB", 1, 0, serviceName, attributes);
       
   509     descriptors << createDescriptor("com.nokia.qt.TestInterfaceB", 2, 0, serviceName, attributes);
       
   510     descriptors << createDescriptor("com.nokia.qt.TestInterfaceB", 2, 3, serviceName, attributes);
       
   511 
       
   512     QByteArray serviceXml = createServiceXml(serviceName, descriptors);
       
   513     QServiceFilter filter;
       
   514 
       
   515     QTest::newRow("empty/wildcard filter")
       
   516             << serviceXml
       
   517             << QServiceFilter()
       
   518             << descriptors;
       
   519 
       
   520     filter = QServiceFilter();
       
   521     filter.setInterface("com.nokia.qt.TestInterfaceA");
       
   522     QTest::newRow("by interface name (A)")
       
   523             << serviceXml
       
   524             << filter
       
   525             << descriptors.mid(0, 1);
       
   526 
       
   527     filter = QServiceFilter();
       
   528     filter.setInterface("com.nokia.qt.TestInterfaceB");
       
   529     QTest::newRow("by interface name (B)")
       
   530             << serviceXml
       
   531             << filter
       
   532             << descriptors.mid(1);
       
   533 
       
   534     filter = QServiceFilter();
       
   535     filter.setServiceName(serviceName);
       
   536     QTest::newRow("by service name, should find all")
       
   537             << serviceXml
       
   538             << filter
       
   539             << descriptors;
       
   540 
       
   541     filter = QServiceFilter();
       
   542     filter.setInterface("com.invalid.interface");
       
   543     QTest::newRow("by non-existing interface name")
       
   544             << serviceXml
       
   545             << filter
       
   546             << ServiceInterfaceDescriptorList();
       
   547 
       
   548     filter = QServiceFilter();
       
   549     filter.setServiceName("InvalidServiceName");
       
   550     QTest::newRow("by non-existing service name")
       
   551             << serviceXml
       
   552             << filter
       
   553             << ServiceInterfaceDescriptorList();
       
   554 
       
   555     //version lookup testing for existing interface
       
   556     //valid from first version onwards
       
   557     filter = QServiceFilter();
       
   558     filter.setInterface("com.nokia.qt.TestInterfaceB", "1.0");
       
   559     QTest::newRow("by version name 1.0 DefaultMatch, should find all B interfaces")
       
   560             << serviceXml
       
   561             << filter
       
   562             << descriptors.mid(1);
       
   563 
       
   564     filter = QServiceFilter();
       
   565     filter.setInterface("com.nokia.qt.TestInterfaceB", "1.0", QServiceFilter::MinimumVersionMatch);
       
   566     QTest::newRow("by version name 1.0 MinimumMatch, should find all B interfaces")
       
   567             << serviceXml
       
   568             << filter
       
   569             << descriptors.mid(1);
       
   570 
       
   571     filter = QServiceFilter();
       
   572     filter.setInterface("com.nokia.qt.TestInterfaceB", "1.0", QServiceFilter::ExactVersionMatch);
       
   573     QTest::newRow("by version name 1.0 ExactMatch, find B 1.0 only")
       
   574             << serviceXml
       
   575             << filter
       
   576             << descriptors.mid(1, 1);
       
   577 
       
   578     //valid with exact version match
       
   579     filter = QServiceFilter();
       
   580     filter.setInterface("com.nokia.qt.TestInterfaceB", "2.0");
       
   581     QTest::newRow("by version name 2.0 DefaultMatch, find B 2.0+")
       
   582             << serviceXml
       
   583             << filter
       
   584             << descriptors.mid(2);
       
   585 
       
   586     filter = QServiceFilter();
       
   587     filter.setInterface("com.nokia.qt.TestInterfaceB", "2.0", QServiceFilter::MinimumVersionMatch);
       
   588     QTest::newRow("by version name 2.0 MinimumMatch, find B 2.0+")
       
   589             << serviceXml
       
   590             << filter
       
   591             << descriptors.mid(2);
       
   592 
       
   593     filter = QServiceFilter();
       
   594     filter.setInterface("com.nokia.qt.TestInterfaceB", "2.0", QServiceFilter::ExactVersionMatch);
       
   595     QTest::newRow("by version name 2.0 ExactMatch, find B 2.0")
       
   596             << serviceXml
       
   597             << filter
       
   598             << descriptors.mid(2, 1);
       
   599 
       
   600     //valid but not exact version match
       
   601     filter = QServiceFilter();
       
   602     filter.setInterface("com.nokia.qt.TestInterfaceB", "1.9");
       
   603     QTest::newRow("by version name 1.9 DefaultMatch, find B 1.9+")
       
   604             << serviceXml
       
   605             << filter
       
   606             << descriptors.mid(2);
       
   607 
       
   608     filter = QServiceFilter();
       
   609     filter.setInterface("com.nokia.qt.TestInterfaceB", "1.9", QServiceFilter::MinimumVersionMatch);
       
   610     QTest::newRow("by version name 1.9 MinimumMatch, find B 1.9+")
       
   611             << serviceXml
       
   612             << filter
       
   613             << descriptors.mid(2);
       
   614 
       
   615     filter = QServiceFilter();
       
   616     filter.setInterface("com.nokia.qt.TestInterfaceB", "1.9", QServiceFilter::ExactVersionMatch);
       
   617     QTest::newRow("by version name 1.9 ExactMatch")
       
   618             << serviceXml
       
   619             << filter
       
   620             << ServiceInterfaceDescriptorList();
       
   621 
       
   622     //version doesn't exist yet
       
   623     filter = QServiceFilter();
       
   624     filter.setInterface("com.nokia.qt.TestInterfaceB", "3.9");
       
   625     QTest::newRow("by version name 3.9 DefaultMatch")
       
   626             << serviceXml
       
   627             << filter
       
   628             << ServiceInterfaceDescriptorList();
       
   629 
       
   630     filter = QServiceFilter();
       
   631     filter.setInterface("com.nokia.qt.TestInterfaceB", "3.9", QServiceFilter::MinimumVersionMatch);
       
   632     QTest::newRow("by version name 3.9 MinimumMatch")
       
   633             << serviceXml
       
   634             << filter
       
   635             << ServiceInterfaceDescriptorList();
       
   636 
       
   637     filter = QServiceFilter();
       
   638     filter.setInterface("com.nokia.qt.TestInterfaceB", "3.9", QServiceFilter::ExactVersionMatch);
       
   639     QTest::newRow("by version name 3.9 ExactMatch")
       
   640             << serviceXml
       
   641             << filter
       
   642             << ServiceInterfaceDescriptorList();
       
   643 
       
   644     //invalid version tag 1 -> match anything
       
   645     filter = QServiceFilter();
       
   646     filter.setInterface("com.nokia.qt.TestInterfaceB", "x3.9");
       
   647     QTest::newRow("by version name x3.9 DefaultMatch")
       
   648             << serviceXml<< filter
       
   649             << descriptors;
       
   650 
       
   651     filter = QServiceFilter();
       
   652     filter.setInterface("com.nokia.qt.TestInterfaceB", "x3.9", QServiceFilter::MinimumVersionMatch);
       
   653     QTest::newRow("by version name x3.9 MinimumMatch")
       
   654             << serviceXml
       
   655             << filter
       
   656             << descriptors;
       
   657 
       
   658     filter = QServiceFilter();
       
   659     filter.setInterface("com.nokia.qt.TestInterfaceB", "x3.9", QServiceFilter::ExactVersionMatch);
       
   660     QTest::newRow("by version name x3.9 ExactMatch")
       
   661             << serviceXml
       
   662             << filter
       
   663             << descriptors;
       
   664 
       
   665     //envalid/empty version tag
       
   666     filter = QServiceFilter();
       
   667     filter.setInterface("com.nokia.qt.TestInterfaceB", "");
       
   668     QTest::newRow("by empty version string DefaultMatch")
       
   669             << serviceXml
       
   670             << filter
       
   671             << descriptors.mid(1);
       
   672 
       
   673     filter = QServiceFilter();
       
   674     filter.setInterface("com.nokia.qt.TestInterfaceB", "", QServiceFilter::MinimumVersionMatch);
       
   675     QTest::newRow("by empty version string MinimumMatch")
       
   676             << serviceXml
       
   677             << filter
       
   678             << descriptors.mid(1);
       
   679 
       
   680     filter = QServiceFilter();
       
   681     filter.setInterface("com.nokia.qt.TestInterfaceB", "", QServiceFilter::ExactVersionMatch); //what's the result of this?
       
   682     QTest::newRow("by empty version string ExactMatch")
       
   683             << serviceXml
       
   684             << filter
       
   685             << descriptors.mid(1);
       
   686 
       
   687     //invalid version tag 2
       
   688     filter = QServiceFilter();
       
   689     filter.setInterface("com.nokia.qt.TestInterfaceB", "abc");
       
   690     QTest::newRow("by version name abc DefaultMatch")
       
   691             << serviceXml<< filter
       
   692             << descriptors;
       
   693 
       
   694     filter = QServiceFilter();
       
   695     filter.setInterface("com.nokia.qt.TestInterfaceB", "abc", QServiceFilter::MinimumVersionMatch);
       
   696     QTest::newRow("by version name abc MinimumMatch")
       
   697             << serviceXml<< filter
       
   698             << descriptors;
       
   699 
       
   700     filter = QServiceFilter();
       
   701     filter.setInterface("com.nokia.qt.TestInterfaceB", "abc", QServiceFilter::ExactVersionMatch);
       
   702     QTest::newRow("by version name abc ExactMatch")
       
   703             << serviceXml
       
   704             << filter
       
   705             << descriptors;
       
   706 }
       
   707 
       
   708 void tst_QServiceManager::findInterfaces_scope()
       
   709 {
       
   710 #if defined(Q_OS_SYMBIAN)
       
   711     QSKIP("There is no difference between user and system scope in symbian", SkipAll);
       
   712 #endif
       
   713     QFETCH(QService::Scope, scope_add);
       
   714     QFETCH(QService::Scope, scope_find);
       
   715     QFETCH(bool, expectFound);
       
   716 
       
   717     QByteArray xml = createServiceXml("SomeTestService",
       
   718             createInterfaceXml("com.nokia.qt.TestInterface"), VALID_PLUGIN_FILES[0]);
       
   719     QBuffer buffer(&xml);
       
   720 
       
   721     QServiceManager mgrUser(QService::UserScope);
       
   722     QServiceManager mgrSystem(QService::SystemScope);
       
   723 
       
   724     QServiceManager &mgrAdd = scope_add == QService::UserScope ? mgrUser : mgrSystem;
       
   725     QServiceManager &mgrFind = scope_find == QService::UserScope ? mgrUser : mgrSystem;
       
   726 
       
   727     QList<QServiceInterfaceDescriptor> result = mgrFind.findInterfaces(QString());
       
   728     QVERIFY(result.isEmpty());
       
   729 
       
   730     QVERIFY2(mgrAdd.addService(&buffer), PRINT_ERR(mgrAdd));
       
   731     result = mgrFind.findInterfaces("SomeTestService");
       
   732     QCOMPARE(!result.isEmpty(), expectFound);
       
   733 
       
   734     result = mgrFind.findInterfaces(QString());
       
   735     if (expectFound)
       
   736         QVERIFY(result.count() == 1);
       
   737     else
       
   738         QVERIFY(result.isEmpty());
       
   739 
       
   740     result = mgrFind.findInterfaces("NonExistingService");
       
   741     QVERIFY(result.isEmpty());
       
   742 }
       
   743 
       
   744 void tst_QServiceManager::findInterfaces_scope_data()
       
   745 {
       
   746     findServices_scope_data();
       
   747 }
       
   748 
       
   749 
       
   750 void tst_QServiceManager::loadInterface_string()
       
   751 {
       
   752     // The sampleservice.xml and sampleservice2.xml services in
       
   753     // tests/sampleserviceplugin and tests/sampleserviceplugin2 implement a
       
   754     // common interface, "com.nokia.qt.TestInterfaceA". If both are
       
   755     // registered, loadInterface(QString) should return the correct one
       
   756     // depending on which is set as the default.
       
   757 
       
   758     // Real servicenames and classnames
       
   759     QString serviceA = "SampleService";
       
   760     QString serviceAClassName = "SampleServicePluginClass";
       
   761     QString serviceB = "SampleService2";
       
   762     QString serviceBClassName = "SampleServicePluginClass2";
       
   763 
       
   764     QObject *obj = 0;
       
   765     QServiceManager mgr;
       
   766     QString commonInterface = "com.nokia.qt.TestInterfaceA";
       
   767 
       
   768     // Add first service. Adds the service described in
       
   769     // c/Private/<uid3 of this executable>/plugins/xmldata/sampleservice.xml
       
   770     QVERIFY2(mgr.addService(xmlTestDataPath("sampleservice.xml")), PRINT_ERR(mgr));
       
   771     obj = mgr.loadInterface(commonInterface, 0, 0);
       
   772     QVERIFY(obj != 0);
       
   773     QCOMPARE(QString(obj->metaObject()->className()), serviceAClassName);
       
   774     delete obj;
       
   775     QCoreApplication::processEvents(QEventLoop::AllEvents|QEventLoop::DeferredDeletion);
       
   776 
       
   777     // Add first service. Adds the service described in
       
   778     // c/Private/<uid3 of this executable>/plugins/xmldata/sampleservice2.xml
       
   779     QVERIFY2(mgr.addService(xmlTestDataPath("sampleservice2.xml")), PRINT_ERR(mgr));
       
   780 
       
   781     // if first service is set as default, it should be returned
       
   782     QVERIFY(mgr.setInterfaceDefault(serviceA, commonInterface));
       
   783     obj = mgr.loadInterface(commonInterface, 0, 0);
       
   784     QVERIFY(obj != 0);
       
   785     QCOMPARE(QString(obj->metaObject()->className()), serviceAClassName);
       
   786     delete obj;
       
   787     QCoreApplication::processEvents(QEventLoop::AllEvents|QEventLoop::DeferredDeletion);
       
   788 
       
   789     // if second service is set as default, it should be returned
       
   790     QVERIFY(mgr.setInterfaceDefault(serviceB, commonInterface));
       
   791     obj = mgr.loadInterface(commonInterface, 0, 0);
       
   792     QVERIFY(obj != 0);
       
   793     QCOMPARE(QString(obj->metaObject()->className()), serviceBClassName);
       
   794     delete obj;
       
   795     QCoreApplication::processEvents(QEventLoop::AllEvents|QEventLoop::DeferredDeletion);
       
   796 }
       
   797 
       
   798 void tst_QServiceManager::loadInterface_descriptor()
       
   799 {
       
   800     QFETCH(QServiceInterfaceDescriptor, descriptor);
       
   801     QFETCH(QString, className);
       
   802 
       
   803     QObject* obj;
       
   804     {
       
   805         QServiceManager mgr;
       
   806         MySecuritySession session;
       
   807         MyServiceContext context;
       
   808         obj = mgr.loadInterface(descriptor, &context, &session);
       
   809         QVERIFY(obj != 0);
       
   810         QCOMPARE(className, QString(obj->metaObject()->className()));
       
   811     }
       
   812 
       
   813     QVERIFY(obj != 0);
       
   814 
       
   815     delete obj;
       
   816     QCoreApplication::processEvents(QEventLoop::AllEvents|QEventLoop::DeferredDeletion);
       
   817 }
       
   818 
       
   819 void tst_QServiceManager::loadInterface_descriptor_data()
       
   820 {
       
   821     QTest::addColumn<QServiceInterfaceDescriptor>("descriptor");
       
   822     QTest::addColumn<QString>("className");
       
   823 
       
   824     QLibrary lib;
       
   825     QServiceInterfaceDescriptor descriptor;
       
   826     QServiceInterfaceDescriptorPrivate *priv = new QServiceInterfaceDescriptorPrivate;
       
   827     priv->interfaceName = "com.nokia.qt.TestInterfaceA";    // needed by service plugin implementation
       
   828 
       
   829     lib.setFileName(QCoreApplication::applicationDirPath() + "/plugins/tst_sfw_sampleserviceplugin");
       
   830     QVERIFY(lib.load());
       
   831     QVERIFY(lib.unload());
       
   832 #if defined (Q_OS_SYMBIAN)
       
   833     priv->attributes[QServiceInterfaceDescriptor::Location] = "plugins/" + lib.fileName();
       
   834 #else
       
   835     priv->attributes[QServiceInterfaceDescriptor::Location] =  lib.fileName();
       
   836 #endif
       
   837     QServiceInterfaceDescriptorPrivate::setPrivate(&descriptor, priv);
       
   838     QTest::newRow("tst_sfw_sampleserviceplugin")
       
   839             << descriptor
       
   840             << "SampleServicePluginClass";
       
   841 
       
   842     lib.setFileName(QCoreApplication::applicationDirPath() + "/plugins/tst_sfw_testservice2plugin");
       
   843     QVERIFY(lib.load());
       
   844     QVERIFY(lib.unload());
       
   845 
       
   846 #if defined(Q_OS_SYMBIAN)
       
   847     priv->attributes[QServiceInterfaceDescriptor::Location] =  "plugins/" + lib.fileName();
       
   848 #else
       
   849     priv->attributes[QServiceInterfaceDescriptor::Location] =  lib.fileName();
       
   850 #endif
       
   851     QServiceInterfaceDescriptorPrivate::setPrivate(&descriptor, priv);
       
   852     QTest::newRow("tst_sfw_sampleserviceplugin2")
       
   853             << descriptor
       
   854             << "TestService";
       
   855 }
       
   856 
       
   857 void tst_QServiceManager::loadInterface_testLoadedObjectAttributes()
       
   858 {
       
   859     QLibrary lib(QCoreApplication::applicationDirPath() + "/plugins/tst_sfw_testservice2plugin");
       
   860     QVERIFY(lib.load());
       
   861     QVERIFY(lib.unload());
       
   862 
       
   863     QServiceInterfaceDescriptor descriptor;
       
   864     QServiceInterfaceDescriptorPrivate *priv = new QServiceInterfaceDescriptorPrivate;
       
   865     priv->interfaceName = "com.nokia.qt.TestInterfaceA";    // needed by service plugin implementation
       
   866 #if defined(Q_OS_SYMBIAN)
       
   867     priv->attributes[QServiceInterfaceDescriptor::Location] =  "plugins/" + lib.fileName();
       
   868 #else
       
   869     priv->attributes[QServiceInterfaceDescriptor::Location] =  lib.fileName();
       
   870 #endif
       
   871     QServiceInterfaceDescriptorPrivate::setPrivate(&descriptor, priv);
       
   872 
       
   873     QServiceManager mgr;
       
   874     MySecuritySession session;
       
   875     MyServiceContext context;
       
   876     QObject *obj = mgr.loadInterface(descriptor, &context, &session);
       
   877     QVERIFY(obj != 0);
       
   878 
       
   879     bool invokeOk = false;
       
   880     QString name;
       
   881 
       
   882     // check attributes
       
   883     QMetaProperty nameProperty = obj->metaObject()->property(obj->metaObject()->indexOfProperty("name"));
       
   884     QVERIFY(nameProperty.isValid());
       
   885     QVERIFY(nameProperty.write(obj, "A service name"));
       
   886     QCOMPARE(nameProperty.read(obj), QVariant("A service name"));
       
   887 
       
   888     // check signals
       
   889     QVERIFY(obj->metaObject()->indexOfSignal("someSignal()") >= 0);
       
   890     QSignalSpy spy(obj, SIGNAL(someSignal()));
       
   891     invokeOk = QMetaObject::invokeMethod(obj, "someSignal");
       
   892     QVERIFY(invokeOk);
       
   893     QVERIFY(spy.count() == 1);
       
   894 
       
   895     // check slots
       
   896     invokeOk = QMetaObject::invokeMethod(obj, "callSlot");
       
   897     QVERIFY(invokeOk);
       
   898     invokeOk = QMetaObject::invokeMethod(obj, "callSlotAndSetName", Q_ARG(QString, "test string"));
       
   899     QVERIFY(invokeOk);
       
   900     invokeOk = QMetaObject::invokeMethod(obj, "callSlotAndReturnName", Q_RETURN_ARG(QString, name));
       
   901     QVERIFY(invokeOk);
       
   902     QCOMPARE(name, QString("test string"));
       
   903 
       
   904     // check invokables
       
   905     invokeOk = QMetaObject::invokeMethod(obj, "callInvokable");
       
   906     QVERIFY(invokeOk);
       
   907 
       
   908     // call method on a returned object
       
   909     QObject *embeddedObj = 0;
       
   910     int value = 0;
       
   911     invokeOk = QMetaObject::invokeMethod(obj, "embeddedTestService", Q_RETURN_ARG(QObject*, embeddedObj));
       
   912     QVERIFY(invokeOk);
       
   913     invokeOk = QMetaObject::invokeMethod(embeddedObj, "callWithInt", Q_RETURN_ARG(int, value), Q_ARG(int, 10));
       
   914     QVERIFY(invokeOk);
       
   915     QCOMPARE(value, 10);
       
   916 
       
   917     // call a method that is not invokable via meta system
       
   918     invokeOk = QMetaObject::invokeMethod(embeddedObj, "callNormalMethod");
       
   919     QVERIFY(!invokeOk);
       
   920 
       
   921     delete obj;
       
   922     QCoreApplication::processEvents(QEventLoop::AllEvents|QEventLoop::DeferredDeletion);
       
   923 }
       
   924 
       
   925 void tst_QServiceManager::loadLocalTypedInterface()
       
   926 {
       
   927     //ensure the plugin exists 
       
   928     QLibrary lib(QCoreApplication::applicationDirPath() + "/plugins/tst_sfw_sampleserviceplugin");
       
   929     QCOMPARE(lib.load(), true);
       
   930     lib.unload();
       
   931 
       
   932     QServiceManager mgr;
       
   933     MySecuritySession session;
       
   934     MyServiceContext context;
       
   935 
       
   936     QServiceInterfaceDescriptor descriptor;
       
   937     QServiceInterfaceDescriptorPrivate *priv = new QServiceInterfaceDescriptorPrivate;
       
   938     priv->interfaceName = "com.nokia.qt.TestInterfaceA";    // needed by service plugin implementation
       
   939 #if defined(Q_OS_SYMBIAN)
       
   940     priv->attributes[QServiceInterfaceDescriptor::Location] =  "plugins/" + lib.fileName();
       
   941 #else
       
   942     priv->attributes[QServiceInterfaceDescriptor::Location] =  lib.fileName();
       
   943 #endif
       
   944     QServiceInterfaceDescriptorPrivate::setPrivate(&descriptor, priv);
       
   945 
       
   946     //use manual descriptor -> avoid database involvement
       
   947     SampleServicePluginClass *plugin = 0;
       
   948     plugin = mgr.loadLocalTypedInterface<SampleServicePluginClass>(descriptor, &context, &session);
       
   949 
       
   950     QVERIFY(plugin != 0);
       
   951     QCOMPARE(plugin->context(), (QServiceContext *)&context);
       
   952     QCOMPARE(plugin->securitySession(), (QAbstractSecuritySession *)&session);
       
   953 
       
   954     delete plugin;
       
   955     plugin = 0;
       
   956     QCoreApplication::processEvents(QEventLoop::AllEvents|QEventLoop::DeferredDeletion);
       
   957 
       
   958     //use database descriptor
       
   959     QFile file1(xmlTestDataPath("sampleservice.xml"));
       
   960     QVERIFY(file1.exists());
       
   961     QVERIFY2(mgr.addService(&file1), PRINT_ERR(mgr));
       
   962 
       
   963     QCOMPARE(mgr.findServices("com.nokia.qt.TestInterfaceA"), QStringList("SampleService"));
       
   964     QCOMPARE(mgr.findServices("com.nokia.qt.TestInterfaceB"), QStringList("SampleService"));
       
   965     QCOMPARE(mgr.findServices("com.nokia.qt.TestInterfaceC"), QStringList("SampleService"));
       
   966     QList<QServiceInterfaceDescriptor> ifaces = mgr.findInterfaces("SampleService");
       
   967     QList<SampleServicePluginClass*> serviceObjects;
       
   968     QVERIFY(ifaces.count() == 3);
       
   969     for (int i = 0; i<ifaces.count(); i++) {
       
   970         plugin = mgr.loadLocalTypedInterface<SampleServicePluginClass>(ifaces.at(i), &context, &session);
       
   971 
       
   972         if (ifaces.at(i).interfaceName() == "com.nokia.qt.TestInterfaceC") {
       
   973             QVERIFY(plugin == 0);
       
   974         } else {
       
   975             QVERIFY(plugin != 0);
       
   976             QCOMPARE(plugin->context(), (QServiceContext *)&context);
       
   977             QCOMPARE(plugin->securitySession(), (QAbstractSecuritySession *)&session);
       
   978             plugin->testSlotOne();
       
   979             serviceObjects.append(plugin);
       
   980         }
       
   981     }
       
   982 
       
   983     //test for a bug where two service instances from same plugin
       
   984     //caused a crash when the first instance was deleted and 
       
   985     //the second instance called
       
   986     QVERIFY(serviceObjects.count() == 2);
       
   987     delete serviceObjects.takeFirst();
       
   988     QCoreApplication::processEvents(QEventLoop::AllEvents|QEventLoop::DeferredDeletion);
       
   989 
       
   990     plugin = serviceObjects.takeFirst();
       
   991     plugin->testSlotOne();
       
   992     delete plugin;
       
   993     QCoreApplication::processEvents(QEventLoop::AllEvents|QEventLoop::DeferredDeletion);
       
   994 
       
   995 
       
   996     //use default lookup
       
   997     plugin = mgr.loadLocalTypedInterface<SampleServicePluginClass>("com.nokia.qt.TestInterfaceA", &context, &session);
       
   998     QVERIFY(plugin != 0);
       
   999     QCOMPARE(plugin->context(), (QServiceContext *)&context);
       
  1000     QCOMPARE(plugin->securitySession(), (QAbstractSecuritySession *)&session);
       
  1001 
       
  1002     delete plugin;
       
  1003     QCoreApplication::processEvents(QEventLoop::AllEvents|QEventLoop::DeferredDeletion);
       
  1004     plugin = 0;
       
  1005 
       
  1006     //use totally wrong but QObject based template class type
       
  1007     QFile *w = mgr.loadLocalTypedInterface<QFile>("com.nokia.qt.TestInterfaceA", &context, &session);
       
  1008     QVERIFY(!w);
       
  1009 
       
  1010     //use non QObject based template class type
       
  1011     //doesn't compile and should never compile
       
  1012     //QString* s = mgr.loadLocalTypedInterface<QString>("com.nokia.qt.TestInterfaceA", &context, &session);
       
  1013     //QVERIFY(!s);
       
  1014 }
       
  1015 
       
  1016 #define TST_QSERVICEMANAGER_ADD_SERVICE(paramType, file) { \
       
  1017     if (paramType == "QString") \
       
  1018         QVERIFY2(mgr.addService(file->fileName()), PRINT_ERR(mgr)); \
       
  1019     else if (paramType == "QIODevice") \
       
  1020         QVERIFY2(mgr.addService(file), PRINT_ERR(mgr)); \
       
  1021     else \
       
  1022         QFAIL("tst_QServiceManager::addService(): Bad test parameter"); \
       
  1023 }
       
  1024 
       
  1025 void tst_QServiceManager::addService()
       
  1026 {
       
  1027     QFETCH(QString, paramType);
       
  1028 
       
  1029     QServiceManager mgr;
       
  1030 
       
  1031     QString commonInterface = "com.qt.serviceframework.tests.CommonInterface";
       
  1032     QByteArray xmlA = createServiceXml("ServiceA", createInterfaceXml(commonInterface), VALID_PLUGIN_FILES[0]);
       
  1033     QByteArray xmlB = createServiceXml("ServiceB", createInterfaceXml(commonInterface), VALID_PLUGIN_FILES[1]);
       
  1034 
       
  1035     QTemporaryFile *tempFileA = new QTemporaryFile(this);
       
  1036     QVERIFY2(tempFileA->open(), "Can't open temp file A");
       
  1037     tempFileA->write(xmlA);
       
  1038     tempFileA->seek(0);
       
  1039     QTemporaryFile *tempFileB = new QTemporaryFile(this);
       
  1040     QVERIFY2(tempFileB->open(), "Can't open temp file B");
       
  1041     tempFileB->write(xmlB);
       
  1042     tempFileB->seek(0);
       
  1043 
       
  1044     TST_QSERVICEMANAGER_ADD_SERVICE(paramType, tempFileA);
       
  1045     QCOMPARE(mgr.findServices(), QStringList("ServiceA"));
       
  1046 
       
  1047     // the service should be automatically set as the default for its
       
  1048     // implemented interfaces since it was the first service added for them
       
  1049     QCOMPARE(mgr.interfaceDefault(commonInterface).serviceName(), QString("ServiceA"));
       
  1050     QCOMPARE(mgr.interfaceDefault(commonInterface).serviceName(), QString("ServiceA"));
       
  1051 
       
  1052     // add second service
       
  1053     TST_QSERVICEMANAGER_ADD_SERVICE(paramType, tempFileB);
       
  1054     QStringList result = mgr.findServices();
       
  1055     QCOMPARE(result.count(), 2);
       
  1056     QVERIFY(result.contains("ServiceA"));
       
  1057     QVERIFY(result.contains("ServiceB"));
       
  1058 
       
  1059     // the default does not change once ServiceB is added
       
  1060     QCOMPARE(mgr.interfaceDefault(commonInterface).serviceName(), QString("ServiceA"));
       
  1061     QCOMPARE(mgr.interfaceDefault(commonInterface).serviceName(), QString("ServiceA"));
       
  1062 
       
  1063     delete tempFileA;
       
  1064     delete tempFileB;
       
  1065 }
       
  1066 
       
  1067 void tst_QServiceManager::addService_data()
       
  1068 {
       
  1069     QTest::addColumn<QString>("paramType");
       
  1070 
       
  1071     QTest::newRow("string") << "QString";
       
  1072     QTest::newRow("iodevice") << "QIODevice";
       
  1073 }
       
  1074 
       
  1075 void tst_QServiceManager::addService_testInvalidServiceXml()
       
  1076 {
       
  1077     QBuffer buffer;
       
  1078     QServiceManager mgr;
       
  1079 
       
  1080     QVERIFY2(!mgr.addService(&buffer), PRINT_ERR(mgr));
       
  1081 
       
  1082     // a service with no interfaces
       
  1083     QString xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
       
  1084     xml += "<service><name>SomeService</name><filepath>" + VALID_PLUGIN_FILES.first() + "</filepath>\n";
       
  1085     xml += "</service>\n";
       
  1086     buffer.close();
       
  1087     buffer.setData(xml.toLatin1());
       
  1088     QVERIFY(!mgr.addService(&buffer));
       
  1089 
       
  1090     QVERIFY2(mgr.findServices().isEmpty(), PRINT_ERR(mgr));
       
  1091 }
       
  1092 
       
  1093 void tst_QServiceManager::addService_testPluginLoading()
       
  1094 {
       
  1095     QFETCH(QString, pluginPath);
       
  1096     QFETCH(bool, isAdded);
       
  1097 
       
  1098     QServiceManager mgr;
       
  1099 
       
  1100     QByteArray xml = createServiceXml("SomeService", createInterfaceXml("com.qt.serviceframework.Interface"), pluginPath);
       
  1101     QBuffer buffer(&xml);
       
  1102     QVERIFY2(mgr.addService(&buffer) == isAdded, PRINT_ERR(mgr));
       
  1103 
       
  1104     // the service should not be added if the service plugin cannot be loaded
       
  1105     if (!isAdded)
       
  1106         QVERIFY(mgr.findServices().isEmpty());
       
  1107 }
       
  1108 
       
  1109 void tst_QServiceManager::addService_testPluginLoading_data()
       
  1110 {
       
  1111     QTest::addColumn<QString>("pluginPath");
       
  1112     QTest::addColumn<bool>("isAdded");
       
  1113 
       
  1114     QTest::newRow("valid path") << VALID_PLUGIN_FILES.first() << true;
       
  1115     QTest::newRow("invalid path") << "no_such_plugin" << false;
       
  1116 }
       
  1117 
       
  1118 void tst_QServiceManager::addService_testInstallService()
       
  1119 {
       
  1120     QSettings settings("com.nokia.qt.serviceframework.tests", "SampleServicePlugin");
       
  1121     QCOMPARE(settings.value("installed").toBool(), false);
       
  1122 
       
  1123     QServiceManager mgr;
       
  1124     QVERIFY2(mgr.addService(xmlTestDataPath("sampleservice.xml")), PRINT_ERR(mgr));
       
  1125     QCOMPARE(mgr.findServices(), QStringList("SampleService"));
       
  1126 
       
  1127     // test installService() was called on the plugin
       
  1128     QCOMPARE(settings.value("installed").toBool(), true);
       
  1129 }
       
  1130 
       
  1131 void tst_QServiceManager::removeService()
       
  1132 {
       
  1133     QServiceManager mgr;
       
  1134 
       
  1135     QVERIFY(!mgr.removeService("NonExistentService"));
       
  1136 
       
  1137     QSettings settings("com.nokia.qt.serviceframework.tests", "SampleServicePlugin");
       
  1138     QCOMPARE(settings.value("installed").toBool(), false);
       
  1139 
       
  1140     QVERIFY2(mgr.addService(xmlTestDataPath("sampleservice.xml")), PRINT_ERR(mgr));
       
  1141     QCOMPARE(mgr.findServices("com.nokia.qt.TestInterfaceA"), QStringList("SampleService"));
       
  1142     QCOMPARE(settings.value("installed").toBool(), true);
       
  1143 
       
  1144     QVERIFY(mgr.removeService("SampleService"));
       
  1145     QVERIFY(mgr.findServices().isEmpty());
       
  1146     QCOMPARE(mgr.findServices("com.nokia.qt.TestInterfaceA"), QStringList());
       
  1147     QCOMPARE(settings.value("installed").toBool(), false);
       
  1148 
       
  1149     // add it again, should still work
       
  1150     QVERIFY2(mgr.addService(xmlTestDataPath("sampleservice.xml")), PRINT_ERR(mgr));
       
  1151     QCOMPARE(mgr.findServices("com.nokia.qt.TestInterfaceA"), QStringList("SampleService"));
       
  1152     QCOMPARE(settings.value("installed").toBool(), true);
       
  1153 }
       
  1154 
       
  1155 void tst_QServiceManager::setInterfaceDefault_strings()
       
  1156 {
       
  1157     QServiceManager mgr;
       
  1158     QString interfaceName = "com.nokia.qt.serviceframework.tests.AnInterface";
       
  1159     DescriptorAttributes attributes;
       
  1160     QServiceInterfaceDescriptor descriptor;
       
  1161     QByteArray xml;
       
  1162 
       
  1163     attributes[QServiceInterfaceDescriptor::Location] = VALID_PLUGIN_FILES[0];
       
  1164     descriptor = createDescriptor(interfaceName, 1, 0, "ServiceA", attributes);
       
  1165     xml = createServiceXml("ServiceA",
       
  1166             createInterfaceXml(QList<QServiceInterfaceDescriptor>() << descriptor),
       
  1167             attributes[QServiceInterfaceDescriptor::Location].toString());
       
  1168     QBuffer buffer(&xml);
       
  1169 
       
  1170     // fails if the specified interface hasn't been registered
       
  1171     QCOMPARE(mgr.setInterfaceDefault("ServiceA", interfaceName), false);
       
  1172 
       
  1173     // now it works
       
  1174     QVERIFY2(mgr.addService(&buffer), PRINT_ERR(mgr));
       
  1175     QCOMPARE(mgr.setInterfaceDefault("ServiceA", interfaceName), true);
       
  1176     QCOMPARE(mgr.interfaceDefault(interfaceName), descriptor);
       
  1177 
       
  1178     // replace the default with another service
       
  1179     attributes[QServiceInterfaceDescriptor::Location] = VALID_PLUGIN_FILES[1];
       
  1180     descriptor = createDescriptor(interfaceName, 1, 0, "ServiceB", attributes);
       
  1181     xml = createServiceXml("ServiceB",
       
  1182             createInterfaceXml(QList<QServiceInterfaceDescriptor>() << descriptor),
       
  1183             attributes[QServiceInterfaceDescriptor::Location].toString());
       
  1184     buffer.close();
       
  1185     buffer.setData(xml);
       
  1186     QVERIFY2(mgr.addService(&buffer), PRINT_ERR(mgr));
       
  1187     QCOMPARE(mgr.setInterfaceDefault("ServiceB", interfaceName), true);
       
  1188     QCOMPARE(mgr.interfaceDefault(interfaceName), descriptor);
       
  1189 
       
  1190     // bad arguments
       
  1191     QCOMPARE(mgr.setInterfaceDefault("", ""), false);
       
  1192     QCOMPARE(mgr.setInterfaceDefault("blah", "blah"), false);
       
  1193     QCOMPARE(mgr.setInterfaceDefault("SampleService", ""), false);
       
  1194 }
       
  1195 
       
  1196 void tst_QServiceManager::setInterfaceDefault_strings_multipleInterfaces()
       
  1197 {
       
  1198     QServiceManager mgr;
       
  1199     QString interfaceName = "com.nokia.qt.serviceframework.tests.AnInterface";
       
  1200     DescriptorAttributes attributes;
       
  1201     QServiceInterfaceDescriptor descriptor;
       
  1202     QByteArray xml;
       
  1203 
       
  1204     // if there are multiple interfaces, the default should be the latest version
       
  1205     attributes[QServiceInterfaceDescriptor::Location] = VALID_PLUGIN_FILES[0];
       
  1206     QList<QServiceInterfaceDescriptor> descriptorList;
       
  1207     descriptorList << createDescriptor(interfaceName, 1, 0, "ServiceC", attributes)
       
  1208                    << createDescriptor(interfaceName, 1, 8, "ServiceC", attributes)
       
  1209                    << createDescriptor(interfaceName, 1, 3, "ServiceC", attributes);
       
  1210     xml = createServiceXml("ServiceC", createInterfaceXml(descriptorList),
       
  1211             attributes[QServiceInterfaceDescriptor::Location].toString());
       
  1212     QBuffer buffer(&xml);
       
  1213     QVERIFY2(mgr.addService(&buffer), PRINT_ERR(mgr));
       
  1214     QCOMPARE(mgr.setInterfaceDefault("ServiceC", interfaceName), true);
       
  1215     QCOMPARE(mgr.interfaceDefault(interfaceName), descriptorList[1]);
       
  1216 }
       
  1217 
       
  1218 void tst_QServiceManager::setInterfaceDefault_descriptor()
       
  1219 {
       
  1220     QFETCH(QService::Scope, scope_add);
       
  1221     QFETCH(QService::Scope, scope_find);
       
  1222     QFETCH(bool, expectFound);
       
  1223 
       
  1224     QServiceManager mgr(scope_add);
       
  1225     QServiceInterfaceDescriptor desc;
       
  1226 
       
  1227     QString interfaceName = "com.nokia.qt.serviceframework.TestInterface";
       
  1228     DescriptorAttributes attributes;
       
  1229     attributes[QServiceInterfaceDescriptor::Location] = VALID_PLUGIN_FILES.first();
       
  1230 
       
  1231     QCOMPARE(mgr.setInterfaceDefault(desc), false);
       
  1232 
       
  1233     desc = createDescriptor(interfaceName, 1, 0, "SomeService", attributes,
       
  1234             scope_add);
       
  1235 
       
  1236     // fails if the specified interface hasn't been registered
       
  1237     QCOMPARE(mgr.setInterfaceDefault(desc), false);
       
  1238 
       
  1239     // now it works
       
  1240     QByteArray xml = createServiceXml("SomeService",
       
  1241             createInterfaceXml(QList<QServiceInterfaceDescriptor>() << desc), VALID_PLUGIN_FILES.first());
       
  1242     QBuffer buffer(&xml);
       
  1243     QVERIFY2(mgr.addService(&buffer), PRINT_ERR(mgr));
       
  1244     QCOMPARE(mgr.setInterfaceDefault(desc), true);
       
  1245 
       
  1246     QCOMPARE(mgr.interfaceDefault(interfaceName), desc);
       
  1247 
       
  1248 #if defined(Q_OS_SYMBIAN)
       
  1249     QCOMPARE(mgr.interfaceDefault(interfaceName).isValid(), expectFound);
       
  1250 #else
       
  1251     QServiceManager mgrWithOtherScope(scope_find);
       
  1252     QCOMPARE(mgrWithOtherScope.interfaceDefault(interfaceName).isValid(), expectFound);
       
  1253 #endif
       
  1254 }
       
  1255 
       
  1256 void tst_QServiceManager::setInterfaceDefault_descriptor_data()
       
  1257 {
       
  1258     QTest::addColumn<QService::Scope>("scope_add");
       
  1259     QTest::addColumn<QService::Scope>("scope_find");
       
  1260     QTest::addColumn<bool>("expectFound");
       
  1261 
       
  1262 #if defined(Q_OS_SYMBIAN)
       
  1263     // Symbian implementation hard-codes user-scope for everything, do not test any system scope-stuff
       
  1264     // because returned service interface descriptor is always in user-scope
       
  1265     QTest::newRow("user scope")
       
  1266                 << QService::UserScope << QService::UserScope << true;
       
  1267 #else
       
  1268     QTest::newRow("user scope")
       
  1269             << QService::UserScope << QService::UserScope << true;
       
  1270     QTest::newRow("system scope")
       
  1271             << QService::SystemScope << QService::SystemScope << true;
       
  1272 
       
  1273     QTest::newRow("user scope - add, system scope - find")
       
  1274             << QService::UserScope << QService::SystemScope << false;
       
  1275     QTest::newRow("system scope - add, user scope - find")
       
  1276             << QService::SystemScope << QService::UserScope << true;
       
  1277 #endif /* Q_OS_SYMBIAN */
       
  1278 }
       
  1279 
       
  1280 void tst_QServiceManager::interfaceDefault()
       
  1281 {
       
  1282     QServiceManager mgr;
       
  1283     QVERIFY(!mgr.interfaceDefault("").isValid());
       
  1284 }
       
  1285 
       
  1286 void tst_QServiceManager::serviceAdded()
       
  1287 {
       
  1288     QFETCH(QByteArray, xml);
       
  1289     QFETCH(QString, serviceName);
       
  1290     QFETCH(QService::Scope, scope_modify);
       
  1291     QFETCH(QService::Scope, scope_listen);
       
  1292     QFETCH(bool, expectSignal);
       
  1293 
       
  1294     QBuffer buffer;
       
  1295     buffer.setData(xml);
       
  1296     QServiceManager mgr_modify(scope_modify);
       
  1297     QServiceManager mgr_listen(scope_listen);
       
  1298     
       
  1299     // ensure mgr.connectNotify() is called
       
  1300     ServicesListener *listener = new ServicesListener;
       
  1301     connect(&mgr_listen, SIGNAL(serviceAdded(QString,QService::Scope)),
       
  1302             listener, SLOT(serviceAdded(QString,QService::Scope)));
       
  1303 
       
  1304     QSignalSpy spyAdd(&mgr_listen, SIGNAL(serviceAdded(QString,QService::Scope)));
       
  1305     QVERIFY2(mgr_modify.addService(&buffer), PRINT_ERR(mgr_modify));
       
  1306 
       
  1307     if (!expectSignal) {
       
  1308         QTest::qWait(2000);
       
  1309         QCOMPARE(spyAdd.count(), 0);
       
  1310     } else {
       
  1311         QTRY_COMPARE(spyAdd.count(), 1);
       
  1312     }
       
  1313 
       
  1314     if (expectSignal) {
       
  1315         QCOMPARE(spyAdd.at(0).at(0).toString(), serviceName);
       
  1316         QCOMPARE( listener->params.at(0).second , scope_modify);
       
  1317     }
       
  1318     listener->params.clear();
       
  1319 
       
  1320     // Pause between file changes so they are detected separately
       
  1321     QTest::qWait(2000);
       
  1322 
       
  1323     QSignalSpy spyRemove(&mgr_listen, SIGNAL(serviceRemoved(QString,QService::Scope)));
       
  1324     QVERIFY(mgr_modify.removeService(serviceName));
       
  1325     
       
  1326     if (!expectSignal) {
       
  1327         QTest::qWait(2000);
       
  1328         QCOMPARE(spyRemove.count(), 0);
       
  1329     } else {
       
  1330         QTRY_COMPARE(spyRemove.count(), 1);
       
  1331     }
       
  1332 
       
  1333 #if !defined (Q_OS_WIN) && !defined (Q_OS_SYMBIAN)
       
  1334     // on win and symbian, cannot delete the database while it is in use
       
  1335     // try it again after deleting the database
       
  1336     deleteTestDatabasesAndWaitUntilDone();
       
  1337 #else
       
  1338     // Pause between file changes so they are detected separately
       
  1339     QTest::qWait(2000);
       
  1340 #endif
       
  1341 
       
  1342     spyAdd.clear();
       
  1343     buffer.seek(0);
       
  1344     QVERIFY2(mgr_modify.addService(&buffer), PRINT_ERR(mgr_modify));
       
  1345     if (!expectSignal) {
       
  1346         QTest::qWait(2000);
       
  1347         QCOMPARE(spyAdd.count(), 0);
       
  1348     } else {
       
  1349         QTRY_COMPARE(spyAdd.count(), 1);
       
  1350     }
       
  1351     if (expectSignal) {
       
  1352         QCOMPARE(spyAdd.at(0).at(0).toString(), serviceName);
       
  1353         QCOMPARE(listener->params.at(0).second, scope_modify);
       
  1354     }
       
  1355 
       
  1356     // ensure mgr.disconnectNotify() is called
       
  1357     disconnect(&mgr_listen, SIGNAL(serviceRemoved(QString,QService::Scope)),
       
  1358             listener, SLOT(serviceRemoved(QString,QService::Scope)));
       
  1359 
       
  1360     delete listener;
       
  1361 }
       
  1362 
       
  1363 void tst_QServiceManager::serviceAdded_data()
       
  1364 {   
       
  1365     QTest::addColumn<QByteArray>("xml");
       
  1366     QTest::addColumn<QString>("serviceName");
       
  1367     QTest::addColumn<QService::Scope>("scope_modify");
       
  1368     QTest::addColumn<QService::Scope>("scope_listen");
       
  1369     QTest::addColumn<bool>("expectSignal");
       
  1370 
       
  1371     QFile file1(xmlTestDataPath("sampleservice.xml"));
       
  1372     QVERIFY(file1.open(QIODevice::ReadOnly));
       
  1373     QFile file2(xmlTestDataPath("testserviceplugin.xml"));
       
  1374     QVERIFY(file2.open(QIODevice::ReadOnly));
       
  1375 
       
  1376     QByteArray file1Data = file1.readAll();
       
  1377 
       
  1378 #if defined (Q_OS_SYMBIAN)
       
  1379     // Symbian implementation hard-codes (ignores) scopes for everything, do not test mixed-scope stuff
       
  1380     QTest::newRow("SampleService, user scope") << file1Data << "SampleService"
       
  1381             << QService::SystemScope << QService::SystemScope << true;
       
  1382     QTest::newRow("TestService, user scope") << file2.readAll() << "TestService"
       
  1383             << QService::SystemScope << QService::SystemScope << true;
       
  1384 #else
       
  1385     QTest::newRow("SampleService, user scope") << file1Data << "SampleService"
       
  1386             << QService::UserScope << QService::UserScope << true;
       
  1387     QTest::newRow("TestService, user scope") << file2.readAll() << "TestService"
       
  1388             << QService::UserScope << QService::UserScope << true;
       
  1389 
       
  1390     QTest::newRow("system scope") << file1Data << "SampleService"
       
  1391             << QService::SystemScope << QService::SystemScope << true;
       
  1392     QTest::newRow("modify as user, listen in system") << file1Data << "SampleService"
       
  1393             << QService::UserScope << QService::SystemScope << false;
       
  1394     QTest::newRow("modify as system, listen in user") << file1Data << "SampleService"
       
  1395             << QService::SystemScope << QService::UserScope << true;
       
  1396 #endif /* Q_OS_SYMBIAN */
       
  1397 }
       
  1398 
       
  1399 void tst_QServiceManager::serviceRemoved()
       
  1400 {
       
  1401     QFETCH(QByteArray, xml);
       
  1402     QFETCH(QString, serviceName);
       
  1403     QFETCH(QService::Scope, scope_modify);
       
  1404     QFETCH(QService::Scope, scope_listen);
       
  1405     QFETCH(bool, expectSignal);
       
  1406 
       
  1407     QBuffer buffer;
       
  1408     buffer.setData(xml);
       
  1409     QServiceManager mgr_modify(scope_modify);
       
  1410     QServiceManager mgr_listen(scope_listen);
       
  1411 
       
  1412     // ensure mgr.connectNotify() is called
       
  1413     ServicesListener *listener = new ServicesListener;
       
  1414     connect(&mgr_listen, SIGNAL(serviceRemoved(QString,QService::Scope)),
       
  1415             listener, SLOT(serviceRemoved(QString,QService::Scope)));
       
  1416 
       
  1417     QSignalSpy spyAdd(&mgr_listen, SIGNAL(serviceAdded(QString,QService::Scope)));
       
  1418     QVERIFY2(mgr_modify.addService(&buffer), PRINT_ERR(mgr_modify));
       
  1419 
       
  1420     if (!expectSignal) {
       
  1421         QTest::qWait(2000);
       
  1422         QCOMPARE(spyAdd.count(), 0);
       
  1423     } else {
       
  1424         QTRY_COMPARE(spyAdd.count(), 1);
       
  1425     }
       
  1426 
       
  1427     // Pause between file changes so they are detected separately
       
  1428     QTest::qWait(2000);
       
  1429 
       
  1430 
       
  1431     QSignalSpy spyRemove(&mgr_listen, SIGNAL(serviceRemoved(QString,QService::Scope)));
       
  1432     QVERIFY(mgr_modify.removeService(serviceName));
       
  1433 
       
  1434     if (!expectSignal) {
       
  1435         QTest::qWait(2000);
       
  1436         QCOMPARE(spyRemove.count(), 0);
       
  1437     } else {
       
  1438         QTRY_COMPARE(spyRemove.count(), 1);
       
  1439     }
       
  1440     if (expectSignal) {
       
  1441         QCOMPARE(spyRemove.at(0).at(0).toString(), serviceName);
       
  1442         QCOMPARE(listener->params.at(0).second , scope_modify);
       
  1443     }
       
  1444     listener->params.clear();
       
  1445 
       
  1446 #if !defined (Q_OS_WIN) && !defined (Q_OS_SYMBIAN)
       
  1447     // on win and symbian, cannot delete the database while it is in use
       
  1448     // try it again after deleting the database
       
  1449     deleteTestDatabasesAndWaitUntilDone();
       
  1450 #else
       
  1451     // Pause between file changes so they are detected separately
       
  1452     QTest::qWait(2000);
       
  1453 #endif
       
  1454     spyAdd.clear();
       
  1455     buffer.seek(0);
       
  1456     QVERIFY2(mgr_modify.addService(&buffer), PRINT_ERR(mgr_modify));
       
  1457     if (!expectSignal) {
       
  1458         QTest::qWait(2000);
       
  1459         QCOMPARE(spyAdd.count(), 0);
       
  1460     } else {
       
  1461         QTRY_COMPARE(spyAdd.count(), 1);
       
  1462     }
       
  1463 
       
  1464     spyRemove.clear();
       
  1465 
       
  1466     // Pause between file changes so they are detected separately
       
  1467     QTest::qWait(2000);
       
  1468 
       
  1469     QVERIFY(mgr_modify.removeService(serviceName));
       
  1470     if (!expectSignal) {
       
  1471         QTest::qWait(2000);
       
  1472         QCOMPARE(spyRemove.count(), 0);
       
  1473     } else {
       
  1474         QTRY_COMPARE(spyRemove.count(), 1);
       
  1475     }
       
  1476     if (expectSignal) {
       
  1477         QCOMPARE(spyRemove.at(0).at(0).toString(), serviceName);
       
  1478         QCOMPARE(listener->params.at(0).second , scope_modify);
       
  1479     }
       
  1480 
       
  1481     // ensure mgr.disconnectNotify() is called
       
  1482     disconnect(&mgr_listen, SIGNAL(serviceRemoved(QString,QService::Scope)),
       
  1483             listener, SLOT(serviceRemoved(QString,QService::Scope)));
       
  1484 
       
  1485     delete listener;
       
  1486 }
       
  1487 
       
  1488 void tst_QServiceManager::serviceRemoved_data()
       
  1489 {
       
  1490     serviceAdded_data();
       
  1491 }
       
  1492 
       
  1493 QTEST_MAIN(tst_QServiceManager)
       
  1494 
       
  1495 #include "tst_qservicemanager.moc"