qtmobility/tests/auto/qvaluespacesubscriber/tst_qvaluespacesubscribershared.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 11 06b8e2af4411
--- a/qtmobility/tests/auto/qvaluespacesubscriber/tst_qvaluespacesubscribershared.cpp	Fri Apr 16 15:51:22 2010 +0300
+++ b/qtmobility/tests/auto/qvaluespacesubscriber/tst_qvaluespacesubscribershared.cpp	Mon May 03 13:18:40 2010 +0300
@@ -52,6 +52,7 @@
 #include <QFile>
 #include <QThread>
 #include <QTimer>
+#include <math.h>
 
 #include <QDebug>
 
@@ -62,7 +63,7 @@
 
 #define ERROR_SETVALUE_NOT_SUPPORTED 1
 
-#ifdef Q_OS_SYMBIAN
+#if defined(Q_OS_SYMBIAN)// || defined (Q_OS_LINUX)
     #define QTRY_COMPARE(a,e)                       \
         for (int _i = 0; _i < 100; _i++) {          \
             if ((a) == (e)) break;                  \
@@ -458,11 +459,7 @@
     QValueSpaceSubscriber *subscriber = qvariant_cast<QValueSpaceSubscriber*>(testItem);
     QCOMPARE(subscriber->parent(), (QObject*)this);
     QCOMPARE(subscriber->value(), value);
-    #ifdef Q_OS_SYMBIAN
-        QVERIFY(subscriber->subPaths().toSet().contains(subPaths.toSet()));
-    #else
-        QCOMPARE(subscriber->subPaths().toSet(), subPaths.toSet());
-    #endif
+    QVERIFY(subscriber->subPaths().toSet().contains(subPaths.toSet()));
     QCOMPARE(subscriber->path(), path);
     QCOMPARE(subscriber->value(relItemPath, 100).toInt(), expectedValue);
 }
@@ -529,43 +526,23 @@
                   << "double" << "float" << "QChar";
 
     QCOMPARE(subscriber.path(), QLatin1String("/"));
-    #ifdef Q_OS_SYMBIAN
-        QVERIFY(subscriber.subPaths().toSet().contains(rootPaths.toSet()));
-    #else
-        QCOMPARE(subscriber.subPaths().toSet(), rootPaths.toSet());
-    #endif
+    QVERIFY(subscriber.subPaths().toSet().contains(rootPaths.toSet()));
 
     subscriber.cd("home");
     QCOMPARE(subscriber.path(), QLatin1String("/home"));
-    #ifdef Q_OS_SYMBIAN
-        QVERIFY(subscriber.subPaths().toSet().contains(homePaths.toSet()));
-    #else
-        QCOMPARE(subscriber.subPaths().toSet(), homePaths.toSet());
-    #endif
+    QVERIFY(subscriber.subPaths().toSet().contains(homePaths.toSet()));
 
     subscriber.cd("user");
     QCOMPARE(subscriber.path(), QLatin1String("/home/user"));
-    #ifdef Q_OS_SYMBIAN
-        QVERIFY(subscriber.subPaths().toSet().contains(homeUserPaths.toSet()));
-    #else
-        QCOMPARE(subscriber.subPaths().toSet(), homeUserPaths.toSet());
-    #endif
+    QVERIFY(subscriber.subPaths().toSet().contains(homeUserPaths.toSet()));
 
     subscriber.cdUp();
     QCOMPARE(subscriber.path(), QLatin1String("/home"));
-    #ifdef Q_OS_SYMBIAN
-        QVERIFY(subscriber.subPaths().toSet().contains(homePaths.toSet()));
-    #else
-        QCOMPARE(subscriber.subPaths().toSet(), homePaths.toSet());
-    #endif
+    QVERIFY(subscriber.subPaths().toSet().contains(homePaths.toSet()));
 
     subscriber.cd("/home/user");
     QCOMPARE(subscriber.path(), QLatin1String("/home/user"));
-    #ifdef Q_OS_SYMBIAN
-        QVERIFY(subscriber.subPaths().toSet().contains(homeUserPaths.toSet()));
-    #else
-        QCOMPARE(subscriber.subPaths().toSet(), homeUserPaths.toSet());
-    #endif
+    QVERIFY(subscriber.subPaths().toSet().contains(homeUserPaths.toSet()));
 }
 
 void tst_QValueSpaceSubscriber::contentsChanged_data()
@@ -723,6 +700,14 @@
         subscriber.property("value");
     }
 
+    #ifdef Q_OS_LINUX
+        //Wait for possible asynchronously emitted signals
+        QEventLoop loop;
+        QTimer::singleShot(100, &loop, SLOT(quit()));
+        loop.exec();
+        spy->clear();
+    #endif
+
     QCOMPARE(spy->count(), 0);
 
     busy->setValue("alex/busy", new_value);
@@ -773,7 +758,7 @@
     QCOMPARE(base.value("home/user/int", 5).toInt(), 3);
     QCOMPARE(base.value("home/user/QByteArray", QByteArray("invalid")).toByteArray(),
              QByteArray("testByteArray"));
-    QCOMPARE(base.value("home/user/double", 4.0).toDouble(), double(4.56));
+    QVERIFY(fabs(base.value("home/user/double", 4.0).toDouble() - double(4.56)) < 0.01);
     //QCOMPARE(base.value("home/user/float", 4.0).toDouble(), (double)4.56);
 
     QValueSpaceSubscriber base1(layer->id(), QString("/home"));
@@ -783,7 +768,7 @@
     QCOMPARE(base1.value("user/int", 5).toInt(), 3);
     QCOMPARE(base1.value("user/QByteArray", QByteArray("invalid")).toByteArray(),
              QByteArray("testByteArray"));
-    QCOMPARE(base1.value("user/double", 4.0).toDouble(), double(4.56));
+    QVERIFY(fabs(base.value("home/user/double", 4.0).toDouble() - double(4.56)) < 0.01);
     //QCOMPARE(base1.value("user/float", 4.0).toDouble(), double(4.56));
 
     QValueSpaceSubscriber base2(layer->id(), QString("/home/user"));
@@ -793,7 +778,7 @@
     QCOMPARE(base2.value("int", 5).toInt(), 3);
     QCOMPARE(base2.value("QByteArray", QByteArray("invalid")).toByteArray(),
              QByteArray("testByteArray"));
-    QCOMPARE(base2.value("double", 4.0).toDouble(), double(4.56));
+    QVERIFY(fabs(base.value("home/user/double", 4.0).toDouble() - double(4.56)) < 0.01);
     //QCOMPARE(base2.value("float", 4.0).toDouble(), 4.56);
 }
 
@@ -828,7 +813,11 @@
 
     QProcess process;
     process.setProcessChannelMode(QProcess::ForwardedChannels);
+#ifdef Q_OS_UNIX
+    process.start("./vsiTestLackey", QStringList() << "-ipcTests" << layer->id().toString());
+#else
     process.start("vsiTestLackey", QStringList() << "-ipcTests" << layer->id().toString());
+#endif
     QVERIFY(process.waitForStarted());
 
     //lackey sets value to 100 as part of its startup
@@ -900,7 +889,11 @@
 
     QProcess process;
     process.setProcessChannelMode(QProcess::ForwardedChannels);
+#ifdef Q_OS_UNIX
+    process.start("./vsiTestLackey", QStringList() << "-ipcRemoveKey" << layer->id().toString());
+#else
     process.start("vsiTestLackey", QStringList() << "-ipcRemoveKey" << layer->id().toString());
+#endif
     QVERIFY(process.waitForStarted());
 
     // Wait for lackey to create "value".
@@ -1041,8 +1034,13 @@
 
     QProcess process;
     process.setProcessChannelMode(QProcess::ForwardedChannels);
+#ifdef Q_OS_UNIX
+    process.start("./vsiTestLackey", QStringList()
+        << "-ipcInterestNotification" << layer->id().toString());
+#else
     process.start("vsiTestLackey", QStringList()
         << "-ipcInterestNotification" << layer->id().toString());
+#endif
     QVERIFY(process.waitForStarted());
 
     // Lackey will receive interestChanged from server and set the attribute.
@@ -1080,7 +1078,7 @@
     Q_OBJECT
 
 public:
-    WriteThread();
+    WriteThread(const QUuid& layerId);
 
     void setDone();
 
@@ -1090,10 +1088,11 @@
 private:
     QValueSpacePublisher *publisher;
     bool done;
+    const QUuid& layerId;
 };
 
-WriteThread::WriteThread()
-:   publisher(0), done(false)
+WriteThread::WriteThread(const QUuid& layerId)
+:   publisher(0), done(false), layerId(layerId)
 {
 }
 
@@ -1106,7 +1105,7 @@
 {
     QTest::qWait(100);  // give some ReadThreads some time to start.
 
-    QValueSpacePublisher publisher("/threads");
+    QValueSpacePublisher publisher(layerId, "/threads");
 
     uint value = 0;
     while (!done) {
@@ -1122,7 +1121,7 @@
     Q_OBJECT
 
 public:
-    ReadThread(QValueSpaceSubscriber *subscriber, bool sync);
+    ReadThread(QValueSpaceSubscriber *subscriber, bool sync, const QUuid& layerId);
 
 protected:
     void run();
@@ -1131,18 +1130,18 @@
     QValueSpaceSubscriber *masterSubscriber;
     int iterations;
     bool synchronised;
+    const QUuid& layerId;
 };
 
-ReadThread::ReadThread(QValueSpaceSubscriber *subscriber, bool sync)
-:   masterSubscriber(subscriber), iterations(0), synchronised(sync)
+ReadThread::ReadThread(QValueSpaceSubscriber *subscriber, bool sync, const QUuid& layerId)
+:   masterSubscriber(subscriber), iterations(0), synchronised(sync), layerId(layerId)
 {
 }
 
 void ReadThread::run()
 {
     while (true) {
-        QValueSpaceSubscriber subscriber;
-        subscriber.setPath(masterSubscriber);
+        QValueSpaceSubscriber subscriber(layerId, masterSubscriber->path());
 
         if (synchronised) {
             QEventLoop loop;
@@ -1163,39 +1162,60 @@
 {
     QTest::addColumn<unsigned int>("threads");
     QTest::addColumn<bool>("synchronised");
+    QTest::addColumn<QUuid>("layerId");
 
-    QTest::newRow("1 thread") << uint(1) << true;
-    QTest::newRow("2 threads") << uint(2) << true;
+    QList<QAbstractValueSpaceLayer *> layers = QValueSpaceManager::instance()->getLayers();
+
+    int foundLayers = 0;
+    for (int i = 0; i < layers.count(); ++i) {
+        QAbstractValueSpaceLayer *layer = layers.at(i);
+
+        //GConfLayer can't provide thread-safety because it eventually depends on
+        //DBus which isn't fully thread-safe
+        if (layer->id() == QVALUESPACE_GCONF_LAYER) {
+            continue;
+        }
+
+        const QUuid id = layer->id();
+
+        QTest::newRow("1 thread") << uint(1) << true << id;
+        QTest::newRow("2 threads") << uint(2) << true << id;
 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
-    QTest::newRow("10 threads") << uint(10) << true;
+        QTest::newRow("10 threads") << uint(10) << true << id;
 #else
-    QTest::newRow("100 threads") << uint(100) << true;
+        QTest::newRow("100 threads") << uint(100) << true << id;
 #endif
-    QTest::newRow("1 thread, unsynchronised") << uint(1) << false;
-    QTest::newRow("2 threads, unsynchronised") << uint(2) << false;
+        QTest::newRow("1 thread, unsynchronised") << uint(1) << false << id;
+        QTest::newRow("2 threads, unsynchronised") << uint(2) << false << id;
 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
-    QTest::newRow("10 threads") << uint(10) << false;
+        QTest::newRow("10 threads") << uint(10) << false  << id;
 #else
-    QTest::newRow("100 threads, unsynchronised") << uint(100) << false;
+        QTest::newRow("100 threads, unsynchronised") << uint(100) << false << id;
 #endif
+        foundLayers++;
+    }
+
+    if (foundLayers == 0)
+        QSKIP("No layers providing thread-safety found", SkipAll);
 }
 
 void tst_QValueSpaceSubscriber::threads()
 {
     QFETCH(unsigned int, threads);
     QFETCH(bool, synchronised);
+    QFETCH(QUuid, layerId);
 
     QEventLoop writeLoop;
-    WriteThread *writeThread = new WriteThread;
+    WriteThread *writeThread = new WriteThread(layerId);
     connect(writeThread, SIGNAL(finished()), &writeLoop, SLOT(quit()));
     writeThread->start();
 
-    QValueSpaceSubscriber masterSubscriber("/threads/value");
+    QValueSpaceSubscriber masterSubscriber(layerId, "/threads/value");
 
     QVector<ReadThread *> readThreads(threads);
 
     for (unsigned int i = 0; i < threads; ++i) {
-        readThreads[i] = new ReadThread(&masterSubscriber, synchronised);
+        readThreads[i] = new ReadThread(&masterSubscriber, synchronised, layerId);
         readThreads[i]->start();
     }
 
@@ -1214,10 +1234,10 @@
         writeLoop.exec();
 
     delete writeThread;
-    #ifdef Q_OS_SYMBIAN
-        QValueSpacePublisher resetPublisher("/threads");
-        resetPublisher.resetValue("value");
-    #endif
+#ifdef Q_OS_SYMBIAN
+    QValueSpacePublisher resetPublisher(layerId, "/threads");
+    resetPublisher.resetValue("value");
+#endif
 
 }