Branch 'kolab/integration/4.13.0' - 4 commits - akonadi/collection.cpp akonadi/collectionfetchscope.h akonadi/entitytreemodel.cpp akonadi/entitytreemodel_p.cpp akonadi/monitor.cpp akonadi/monitor_p.cpp akonadi/notificationsource.cpp akonadi/notificationsource_p.h akonadi/tests

Christian Mollekopf mollekopf at kolabsys.com
Thu Dec 11 16:49:30 CET 2014


 akonadi/collection.cpp          |    2 
 akonadi/collectionfetchscope.h  |   14 --
 akonadi/entitytreemodel.cpp     |    1 
 akonadi/entitytreemodel_p.cpp   |    2 
 akonadi/monitor.cpp             |    3 
 akonadi/monitor_p.cpp           |    3 
 akonadi/notificationsource.cpp  |    8 +
 akonadi/notificationsource_p.h  |    1 
 akonadi/tests/CMakeLists.txt    |    1 
 akonadi/tests/referencetest.cpp |  234 ++++++++++++++++++++++++++++++++++++++++
 akonadi/tests/referencetest.h   |   34 +++++
 11 files changed, 286 insertions(+), 17 deletions(-)

New commits:
commit bb94c6c0ad0eea636af3694841b0ed2d5b81de5d
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Wed Dec 10 20:31:54 2014 +0100

    Monitor: set the session.
    
    Required to properly deal with referenced collections.
    
    With this patch we set the sessionid on the serverside monitor instead
    of monitoring each collection that we referenced.
    This requires support from the akonadiserver.
    
    The approach is cleaner and keeps the client code cleaner.
    It also removes the problem that the mimetypefilter no longer works
    because explicitly monitoring collections overrides the mimetypefilter.

diff --git a/akonadi/monitor.cpp b/akonadi/monitor.cpp
index 0e2cc3c..ab57b03 100644
--- a/akonadi/monitor.cpp
+++ b/akonadi/monitor.cpp
@@ -375,6 +375,9 @@ void Monitor::setSession(Akonadi::Session *session)
 
     d->itemCache->setSession(d->session);
     d->collectionCache->setSession(d->session);
+    if (d->notificationSource) {
+        d->notificationSource->setSession(d->session->sessionId());
+    }
 }
 
 Session *Monitor::session() const
diff --git a/akonadi/monitor_p.cpp b/akonadi/monitor_p.cpp
index cd35dd6..52b9114 100644
--- a/akonadi/monitor_p.cpp
+++ b/akonadi/monitor_p.cpp
@@ -93,6 +93,8 @@ bool MonitorPrivate::connectToNotificationManager()
     QObject::connect(notificationSource, SIGNAL(notifyV3(Akonadi::NotificationMessageV3::List)),
                      q_ptr, SLOT(slotNotify(Akonadi::NotificationMessageV3::List)));
 
+    notificationSource->setSession(session->sessionId());
+
     return true;
 }
 
@@ -101,6 +103,7 @@ void MonitorPrivate::serverStateChanged(ServerManager::State state)
     if (state == ServerManager::Running) {
         connectToNotificationManager();
         notificationSource->setAllMonitored(monitorAll);
+        notificationSource->setSession(session->sessionId());
         Q_FOREACH (const Collection &col, collections) {
             notificationSource->setMonitoredCollection(col.id(), true);
         }
diff --git a/akonadi/notificationsource.cpp b/akonadi/notificationsource.cpp
index 9946cdf..d36a599 100644
--- a/akonadi/notificationsource.cpp
+++ b/akonadi/notificationsource.cpp
@@ -113,6 +113,14 @@ void NotificationSource::setMonitoredType(NotificationMessageV2::Type type, bool
     Q_UNUSED(ok);
 }
 
+void NotificationSource::setSession(const QByteArray &session)
+{
+    const bool ok = QMetaObject::invokeMethod(parent(), "setSession",
+                                              Q_ARG(QByteArray, session));
+    Q_ASSERT(ok);
+    Q_UNUSED(ok);
+}
+
 QObject *NotificationSource::source() const
 {
     return parent();
diff --git a/akonadi/notificationsource_p.h b/akonadi/notificationsource_p.h
index 97b0935..fae97d0 100644
--- a/akonadi/notificationsource_p.h
+++ b/akonadi/notificationsource_p.h
@@ -47,6 +47,7 @@ public:
     void setMonitoredTag(Tag::Id id, bool monitored);
     void setMonitoredType(NotificationMessageV2::Type type, bool monitored);
     void setIgnoredSession(const QByteArray &session, bool monitored);
+    void setSession(const QByteArray &session);
 
     QObject *source() const;
 
diff --git a/akonadi/tests/CMakeLists.txt b/akonadi/tests/CMakeLists.txt
index d0a4ae3..dda3e31 100644
--- a/akonadi/tests/CMakeLists.txt
+++ b/akonadi/tests/CMakeLists.txt
@@ -152,6 +152,7 @@ add_akonadi_isolated_test(cachetest.cpp)
 # and the test is not very critical (we'll notice if we can't start the server), so we disable it for now.
 #add_akonadi_isolated_test(servermanagertest.cpp)
 add_akonadi_isolated_test(collectioncreator.cpp)
+add_akonadi_isolated_test(referencetest.cpp)
 
 
 # Having a benchmark is cool if you have any reference to compare against, but this
diff --git a/akonadi/tests/referencetest.cpp b/akonadi/tests/referencetest.cpp
new file mode 100644
index 0000000..8f5da85
--- /dev/null
+++ b/akonadi/tests/referencetest.cpp
@@ -0,0 +1,234 @@
+/*
+    Copyright (c) 2006 Volker Krause <vkrause at kde.org>
+
+    This library is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Library General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    This library is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+    License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to the
+    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+*/
+
+#include "referencetest.h"
+
+#include <sys/types.h>
+
+#include <qtest_akonadi.h>
+#include "test_utils.h"
+
+#include "agentmanager.h"
+#include "agentinstance.h"
+#include "cachepolicy.h"
+#include "collection.h"
+#include "collectioncreatejob.h"
+#include "collectiondeletejob.h"
+#include "collectionfetchjob.h"
+#include "collectionmodifyjob.h"
+#include "control.h"
+#include "item.h"
+#include "collectionfetchscope.h"
+#include "session.h"
+#include "monitor.h"
+
+using namespace Akonadi;
+
+QTEST_AKONADIMAIN(ReferenceTest, NoGUI)
+
+void ReferenceTest::initTestCase()
+{
+    qRegisterMetaType<Akonadi::Collection::List>();
+    AkonadiTest::checkTestIsIsolated();
+    Control::start();
+    AkonadiTest::setAllResourcesOffline();
+}
+
+static Collection::Id res1ColId = 6; // -1;
+
+void ReferenceTest::testReference()
+{
+    Akonadi::Collection baseCol;
+    {
+        baseCol.setParentCollection(Akonadi::Collection(res1ColId));
+        baseCol.setName("base");
+        Akonadi::CollectionCreateJob *create = new Akonadi::CollectionCreateJob(baseCol);
+        AKVERIFYEXEC(create);
+        baseCol = create->collection();
+    }
+
+    {
+        Akonadi::Collection col;
+        col.setParentCollection(baseCol);
+        col.setName("referenced");
+        col.setEnabled(false);
+        {
+            Akonadi::CollectionCreateJob *create = new Akonadi::CollectionCreateJob(col);
+            AKVERIFYEXEC(create);
+            CollectionFetchJob *job = new CollectionFetchJob(create->collection(), CollectionFetchJob::Base);
+            AKVERIFYEXEC(job);
+            col = job->collections().first();
+        }
+        {
+            col.setReferenced(true);
+            Akonadi::CollectionModifyJob *modify = new Akonadi::CollectionModifyJob(col);
+            AKVERIFYEXEC(modify);
+            CollectionFetchJob *job = new CollectionFetchJob(col, CollectionFetchJob::Base);
+            AKVERIFYEXEC(job);
+            Akonadi::Collection result = job->collections().first();
+            QCOMPARE(result.enabled(), false);
+            QCOMPARE(result.referenced(), true);
+        }
+        {
+            col.setReferenced(false);
+            Akonadi::CollectionModifyJob *modify = new Akonadi::CollectionModifyJob(col);
+            AKVERIFYEXEC(modify);
+            CollectionFetchJob *job = new CollectionFetchJob(col, CollectionFetchJob::Base);
+            AKVERIFYEXEC(job);
+            Akonadi::Collection result = job->collections().first();
+            QCOMPARE(result.enabled(), false);
+            QCOMPARE(result.referenced(), false);
+        }
+    }
+
+    //Cleanup
+    CollectionDeleteJob *deleteJob = new CollectionDeleteJob(baseCol);
+    AKVERIFYEXEC(deleteJob);
+}
+
+void ReferenceTest::testReferenceFromMultiSession()
+{
+    Akonadi::Collection baseCol;
+    {
+        baseCol.setParentCollection(Akonadi::Collection(res1ColId));
+        baseCol.setName("base");
+        baseCol.setEnabled(false);
+        Akonadi::CollectionCreateJob *create = new Akonadi::CollectionCreateJob(baseCol);
+        AKVERIFYEXEC(create);
+        baseCol = create->collection();
+    }
+
+    {
+        Akonadi::Collection col;
+        col.setParentCollection(baseCol);
+        col.setName("referenced");
+        col.setEnabled(false);
+        {
+        Akonadi::CollectionCreateJob *create = new Akonadi::CollectionCreateJob(col);
+        AKVERIFYEXEC(create);
+        CollectionFetchJob *job = new CollectionFetchJob(create->collection(), CollectionFetchJob::Base);
+        AKVERIFYEXEC(job);
+        col = job->collections().first();
+        }
+
+        Akonadi::Session *session1 = new Akonadi::Session("session1");
+        Akonadi::Monitor *monitor1 = new Akonadi::Monitor();
+        monitor1->setSession(session1);
+        monitor1->setCollectionMonitored(Collection::root());
+
+        Akonadi::Session *session2 = new Akonadi::Session("session2");
+        Akonadi::Monitor *monitor2 = new Akonadi::Monitor();
+        monitor2->setSession(session2);
+        monitor2->setCollectionMonitored(Collection::root());
+
+        //Reference in first session and ensure second session is not affected
+        {
+            QSignalSpy cmodspy1(monitor1, SIGNAL(collectionChanged(Akonadi::Collection,QSet<QByteArray>)));
+            QSignalSpy cmodspy2(monitor2, SIGNAL(collectionChanged(Akonadi::Collection,QSet<QByteArray>)));
+
+            col.setReferenced(true);
+            Akonadi::CollectionModifyJob *modify = new Akonadi::CollectionModifyJob(col, session1);
+            AKVERIFYEXEC(modify);
+
+            //We want a signal only in the session that referenced the collection
+            QVERIFY(QTest::kWaitForSignal(monitor1, SIGNAL(collectionChanged(Akonadi::Collection)), 1000));
+            QTest::qWait(100);
+            QCOMPARE(cmodspy1.count(), 1);
+            QCOMPARE(cmodspy2.count(), 0);
+
+            {
+                CollectionFetchJob *job = new CollectionFetchJob(baseCol, CollectionFetchJob::Recursive, session1);
+                job->fetchScope().setListFilter(CollectionFetchScope::Display);
+                AKVERIFYEXEC(job);
+                QCOMPARE(job->collections().size(), 1);
+            }
+
+            {
+                CollectionFetchJob *job = new CollectionFetchJob(baseCol, CollectionFetchJob::Recursive, session2);
+                job->fetchScope().setListFilter(CollectionFetchScope::Display);
+                AKVERIFYEXEC(job);
+                QCOMPARE(job->collections().size(), 0);
+            }
+        }
+        //Reference in second session and ensure first session is not affected
+        {
+            QSignalSpy cmodspy1(monitor1, SIGNAL(collectionChanged(Akonadi::Collection,QSet<QByteArray>)));
+            QSignalSpy cmodspy2(monitor2, SIGNAL(collectionChanged(Akonadi::Collection,QSet<QByteArray>)));
+
+            col.setReferenced(true);
+            Akonadi::CollectionModifyJob *modify = new Akonadi::CollectionModifyJob(col, session2);
+            AKVERIFYEXEC(modify);
+
+            //We want a signal only in the session that referenced the collection
+            QVERIFY(QTest::kWaitForSignal(monitor2, SIGNAL(collectionChanged(Akonadi::Collection)), 1000));
+            QTest::qWait(100);
+            //FIXME The first session still gets the notification since it has the session referenced
+            QCOMPARE(cmodspy1.count(), 1);
+            QCOMPARE(cmodspy2.count(), 1);
+
+            {
+                CollectionFetchJob *job = new CollectionFetchJob(baseCol, CollectionFetchJob::Recursive, session1);
+                job->fetchScope().setListFilter(CollectionFetchScope::Display);
+                AKVERIFYEXEC(job);
+                QCOMPARE(job->collections().size(), 1);
+            }
+
+            {
+                CollectionFetchJob *job = new CollectionFetchJob(baseCol, CollectionFetchJob::Recursive, session2);
+                job->fetchScope().setListFilter(CollectionFetchScope::Display);
+                AKVERIFYEXEC(job);
+                QCOMPARE(job->collections().size(), 1);
+            }
+        }
+        {
+            QSignalSpy cmodspy1(monitor1, SIGNAL(collectionChanged(Akonadi::Collection,QSet<QByteArray>)));
+            QSignalSpy cmodspy2(monitor2, SIGNAL(collectionChanged(Akonadi::Collection,QSet<QByteArray>)));
+            col.setReferenced(false);
+            Akonadi::CollectionModifyJob *modify = new Akonadi::CollectionModifyJob(col, session1);
+            AKVERIFYEXEC(modify);
+
+            //We want a signal only in the session that referenced the collection
+            QVERIFY(QTest::kWaitForSignal(monitor1, SIGNAL(collectionChanged(Akonadi::Collection)), 1000));
+            QTest::qWait(100);
+            QCOMPARE(cmodspy1.count(), 1);
+            //FIXME here we still get a notification for dereferenced because we don't filter correctly
+            QCOMPARE(cmodspy2.count(), 1);
+
+            {
+                CollectionFetchJob *job = new CollectionFetchJob(baseCol, CollectionFetchJob::Recursive, session1);
+                job->fetchScope().setListFilter(CollectionFetchScope::Display);
+                AKVERIFYEXEC(job);
+                QCOMPARE(job->collections().size(), 0);
+            }
+
+            {
+                CollectionFetchJob *job = new CollectionFetchJob(baseCol, CollectionFetchJob::Recursive, session2);
+                job->fetchScope().setListFilter(CollectionFetchScope::Display);
+                AKVERIFYEXEC(job);
+                QCOMPARE(job->collections().size(), 1);
+            }
+        }
+    }
+
+    //Cleanup
+    CollectionDeleteJob *deleteJob = new CollectionDeleteJob(baseCol);
+    AKVERIFYEXEC(deleteJob);
+}
+
+#include "referencetest.moc"
diff --git a/akonadi/tests/referencetest.h b/akonadi/tests/referencetest.h
new file mode 100644
index 0000000..95e0d44
--- /dev/null
+++ b/akonadi/tests/referencetest.h
@@ -0,0 +1,34 @@
+/*
+    Copyright (c) 2006 Volker Krause <vkrause at kde.org>
+
+    This library is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Library General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    This library is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+    License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to the
+    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+*/
+
+#ifndef REFERENCETEST_H
+#define REFERENCETEST_H
+
+#include <QtCore/QObject>
+
+class ReferenceTest : public QObject
+{
+  Q_OBJECT
+  private Q_SLOTS:
+    void initTestCase();
+    void testReference();
+    void testReferenceFromMultiSession();
+};
+
+#endif


commit 1bd3f51d45079265cfb43d0873be1ab0f2fc89b6
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Wed Dec 10 20:31:12 2014 +0100

    ETM: stop monitoring and take referenced into account

diff --git a/akonadi/entitytreemodel.cpp b/akonadi/entitytreemodel.cpp
index 5cc824f..58f18d8 100644
--- a/akonadi/entitytreemodel.cpp
+++ b/akonadi/entitytreemodel.cpp
@@ -133,7 +133,6 @@ void EntityTreeModel::setCollectionMonitored(const Collection &col, bool monitor
 void EntityTreeModel::setCollectionReferenced(const Akonadi::Collection &col, bool referenced)
 {
     Q_D(EntityTreeModel);
-    d->m_monitor->setCollectionMonitored(col, referenced);
     Akonadi::Collection referencedCollection = col;
     referencedCollection.setReferenced(referenced);
     //We have to use the same session as the monitor, so the monitor can fetch the collection afterwards
diff --git a/akonadi/entitytreemodel_p.cpp b/akonadi/entitytreemodel_p.cpp
index 1f480ab..74ca0a7 100644
--- a/akonadi/entitytreemodel_p.cpp
+++ b/akonadi/entitytreemodel_p.cpp
@@ -787,7 +787,7 @@ bool EntityTreeModelPrivate::shouldBePartOfModel(const Collection &collection) c
     }
 
     if (m_listFilter == CollectionFetchScope::Enabled) {
-        if (!collection.enabled()) {
+        if (!collection.enabled() && !collection.referenced()) {
             return false;
         }
     } else if (m_listFilter == CollectionFetchScope::Display) {


commit d30711f80beead00115be4fc0b7bf78219f1174f
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Wed Dec 10 20:30:17 2014 +0100

    Collection: take referenced into account for shouldList

diff --git a/akonadi/collection.cpp b/akonadi/collection.cpp
index 3dc5203..59f7c7c 100644
--- a/akonadi/collection.cpp
+++ b/akonadi/collection.cpp
@@ -321,7 +321,7 @@ Collection::ListPreference Collection::localListPreference(Collection::ListPurpo
 bool Collection::shouldList(Collection::ListPurpose purpose) const
 {
     if (localListPreference(purpose) == ListDefault) {
-        return enabled();
+        return enabled() || referenced();
     }
     return (localListPreference(purpose) == ListEnabled);
 }


commit 74b3e13acbda2615cb52908658e7d6adc3cfb8f9
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Wed Dec 10 10:30:17 2014 +0100

    Removed unimplemented interface.

diff --git a/akonadi/collectionfetchscope.h b/akonadi/collectionfetchscope.h
index 8fb443f..3d714e0 100644
--- a/akonadi/collectionfetchscope.h
+++ b/akonadi/collectionfetchscope.h
@@ -235,20 +235,6 @@ public:
     CollectionFetchScope &ancestorFetchScope();
 
     /**
-     * Sets wether all attributes should be retrieved (true by default).
-     * 
-     * This is currently only supported for ancestors.
-     */
-    void setFetchAllAttribute(bool fetchAll = true);
-
-    /**
-     * Returns wether all attributes should be retrieved (true by default).
-     * 
-     * This is currently only supported for ancestors.
-     */
-    bool fetchAllAttributes() const;
-
-    /**
      * Returns all explicitly fetched attributes.
      *
      * Undefined if fetchAllAttributes() returns true.




More information about the commits mailing list