[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [KSecretService] 982ccc8: Adapt the non-blocking collection test for
From: Michael Leupold <lemma () confuego ! org>
Date: 2010-11-09 19:14:24
Message-ID: 20101109191424.7ACECA60CD () git ! kde ! org
[Download RAW message or body]
commit 982ccc8f5ec1d8d38b03964e9cf6775e96ff7338
branch master
Author: Michael Leupold <lemma@confuego.org>
Date: Fri May 7 05:02:42 2010 +0000
Adapt the non-blocking collection test for blocking collections using a prompt. \
Test dismissing and prompting prompts. Fix bugs while doing so.
CCMAIL: dario.freddi@collabora.co.uk
svn path=/trunk/playground/base/ksecretservice/; revision=1123851
diff --git a/backend/backendmaster.cpp b/backend/backendmaster.cpp
index 9eb304d..56db545 100644
--- a/backend/backendmaster.cpp
+++ b/backend/backendmaster.cpp
@@ -43,6 +43,15 @@ void BackendMaster::addManager(BackendCollectionManager *manager)
m_collectionManagers.append(manager);
}
+void BackendMaster::removeManager(BackendCollectionManager *manager)
+{
+ manager->disconnect(SIGNAL(collectionCreated(BackendCollection*)), this,
+ SLOT(slotCollectionCreated(BackendCollection*)));
+ manager->disconnect(SIGNAL(collectionDeleted(BackendCollection*)), this,
+ SLOT(slotCollectionDeleted(BackendCollection*)));
+ m_collectionManagers.removeAll(manager);
+}
+
const QList<BackendCollection*> &BackendMaster::collections() const
{
return m_collections;
@@ -51,7 +60,7 @@ const QList<BackendCollection*> &BackendMaster::collections() const
bool BackendMaster::isCallImmediate(AsyncCall::AsyncType type) const
{
switch (type) {
- case AsyncCall::AsyncCreateCollection:
+ case AsyncCall::AsyncCreateCollectionMaster:
// create collection will be immediate if the list of managers
// contains only a single manager which can process the call
// immediately. for all other cases the user needs to choose
@@ -94,7 +103,7 @@ BackendReturn<BackendCollection*> \
BackendMaster::createCollection(const QString
// call has to be queued. use an eventloop for waiting for its return.
QEventLoop loop;
AsyncCreateCollection *call = new AsyncCreateCollection(label, locked, \
manager);
- connect(call, SIGNAL(completed()), &loop, SLOT(quit()));
+ connect(call, SIGNAL(completed(AsyncCall*, bool)), &loop, SLOT(quit()));
call->enqueue();
loop.exec();
diff --git a/backend/backendmaster.h b/backend/backendmaster.h
index 3ae8dca..384d786 100644
--- a/backend/backendmaster.h
+++ b/backend/backendmaster.h
@@ -68,6 +68,13 @@ public:
void addManager(BackendCollectionManager *manager);
/**
+ * Remove a collection manager from the list of known managers.
+ *
+ * @param manager collection manager to remove
+ */
+ void removeManager(BackendCollectionManager *manager);
+
+ /**
* Get the list of known collections.
*
* @return The list of known collections
diff --git a/daemon/dbus/promptadaptor.cpp b/daemon/dbus/promptadaptor.cpp
index a01cd9e..44ddda3 100644
--- a/daemon/dbus/promptadaptor.cpp
+++ b/daemon/dbus/promptadaptor.cpp
@@ -29,7 +29,7 @@ PromptAdaptor::PromptAdaptor(PromptBase *prompt)
{
Q_ASSERT(prompt);
- connect(prompt, SIGNAL(completed(bool, QVariant)), SIGNAL(Completed(bool, \
QVariant))); + connect(prompt, SIGNAL(completed(bool, QVariant)), \
SLOT(slotCompleted(bool, QVariant))); }
void PromptAdaptor::Prompt(const QString &windowId)
@@ -42,6 +42,11 @@ void PromptAdaptor::Dismiss()
m_prompt->dismiss();
}
+void PromptAdaptor::slotCompleted(bool dismissed, const QVariant &result)
+{
+ emit Completed(dismissed, QDBusVariant(result));
+}
+
}
#include "promptadaptor.moc"
diff --git a/daemon/dbus/promptadaptor.h b/daemon/dbus/promptadaptor.h
index 12f12f9..8338eca 100644
--- a/daemon/dbus/promptadaptor.h
+++ b/daemon/dbus/promptadaptor.h
@@ -50,8 +50,11 @@ public Q_SLOTS:
void Dismiss();
Q_SIGNALS:
- void Completed(bool dismissed, QVariant result);
+ void Completed(bool dismissed, QDBusVariant result);
+private Q_SLOTS:
+ void slotCompleted(bool dismissed, const QVariant &result);
+
private:
PromptBase *m_prompt;
};
diff --git a/daemon/prompt.cpp b/daemon/prompt.cpp
index 6c2730f..9c3e21b 100644
--- a/daemon/prompt.cpp
+++ b/daemon/prompt.cpp
@@ -93,7 +93,7 @@ void PromptBase::slotCompleted(AsyncCall *call, bool dismissed)
// TODO: handle errors
if (dismissed) {
- emit completed(true, QVariant());
+ emit completed(true, QVariant(""));
} else {
emit completed(false, getResult());
}
diff --git a/daemon/tests/CMakeLists.txt b/daemon/tests/CMakeLists.txt
index 0ded7b4..a776797 100644
--- a/daemon/tests/CMakeLists.txt
+++ b/daemon/tests/CMakeLists.txt
@@ -7,7 +7,12 @@ INCLUDE_DIRECTORIES (
${CMAKE_CURRENT_BINARY_DIR}
)
-KDE4_ADD_EXECUTABLE (ksecretservice_daemon_test servicetest.cpp)
+KDE4_ADD_EXECUTABLE (ksecretservice_daemon_test
+ servicetest.cpp
+ tempblockingcollectionmanager.cpp
+ tempblockingcollection.cpp
+ tempblockingitem.cpp
+)
TARGET_LINK_LIBRARIES (ksecretservice_daemon_test
ksecretservicebackend
ksecretservicedaemon
diff --git a/daemon/tests/servicetest.cpp b/daemon/tests/servicetest.cpp
index 8e1942d..cc4b110 100644
--- a/daemon/tests/servicetest.cpp
+++ b/daemon/tests/servicetest.cpp
@@ -22,6 +22,7 @@
#include "backend/backendmaster.h"
#include "backend/temporarycollectionmanager.h"
+#include "tempblockingcollectionmanager.h"
#include "daemon/service.h"
#include "daemon/dbus/dbustypes.h"
@@ -44,7 +45,8 @@ void ServiceTest::initTestCase()
QCA::init();
m_master = new BackendMaster;
- m_master->addManager(new TemporaryCollectionManager(m_master));
+ m_tempCollMan = new TemporaryCollectionManager(m_master);
+ m_master->addManager(m_tempCollMan);
m_service = new Service(m_master);
}
@@ -213,7 +215,7 @@ void ServiceTest::nonBlockingCollection()
// make sure the CollectionChanged signal was sent
if (changedSpy.size() < 1) {
- changedSpy.waitForSignal(1);
+ changedSpy.waitForSignal(5000);
}
QCOMPARE(changedSpy.size(), 1);
QCOMPARE(changedSpy.takeFirst(), collectionPath);
@@ -418,6 +420,188 @@ void ServiceTest::nonBlockingItem()
QDBusInterface("org.freedesktop.Secret", sessionPath.path()).call("Close");
}
+void ServiceTest::reInitTestCase()
+{
+ // remove the TemporaryCollectionManager and replace it with a \
TempBlockingCollectionManager + m_master->removeManager(m_tempCollMan);
+ delete m_tempCollMan;
+ m_tempBlockCollMan = new TempBlockingCollectionManager(m_master);
+ m_master->addManager(m_tempBlockCollMan);
+}
+
+void ServiceTest::blockingCollection()
+{
+ ClientPrompt *prompt = 0;
+
+ QDBusInterface ifaceService("org.freedesktop.Secret", \
"/org/freedesktop/secrets"); + QVERIFY(ifaceService.isValid());
+
+ // create a session
+ // create a session
+ QDBusObjectPath sessionPath;
+ QList<QVariant> sessionInput;
+ sessionInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
+ QDBusMessage sessionReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession", + \
sessionInput); + sessionPath = \
sessionReply.arguments().at(1).value<QDBusObjectPath>(); +
+ // listen to CollectionCreated/CollectionDeleted/CollectionChanged signals
+ ObjectPathSignalSpy createdSpy(&ifaceService, \
SIGNAL(CollectionCreated(QDBusObjectPath))); + QVERIFY(createdSpy.isValid());
+ ObjectPathSignalSpy deletedSpy(&ifaceService, \
SIGNAL(CollectionDeleted(QDBusObjectPath))); + QVERIFY(deletedSpy.isValid());
+ ObjectPathSignalSpy changedSpy(&ifaceService, \
SIGNAL(CollectionChanged(QDBusObjectPath))); + QVERIFY(changedSpy.isValid());
+
+ // create a collection
+ QDBusObjectPath promptPath;
+ QMap<QString, QVariant> createProperties;
+ QList<QVariant> createInput;
+ createProperties["Label"] = "test";
+ createProperties["Locked"] = false; // create collection unlocked
+ createInput << QVariant::fromValue(createProperties);
+ QDBusMessage createReply = ifaceService.callWithArgumentList(QDBus::Block, \
"CreateCollection", + \
createInput); + QCOMPARE(createReply.type(), QDBusMessage::ReplyMessage);
+ QList<QVariant> createArgs = createReply.arguments();
+ QCOMPARE(createArgs.size(), 2);
+ QCOMPARE(createArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+ QCOMPARE(createArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
+ // TempBlockingCollection is blocking, so the first output (path) should be "/".
+ QCOMPARE(createArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
+ promptPath = createArgs.at(1).value<QDBusObjectPath>();
+ QVERIFY(promptPath.path().startsWith(
+ QLatin1String("/org/freedesktop/secrets/prompts/")));
+
+ // dismiss the prompt and wait for the result.
+ prompt = new ClientPrompt(promptPath);
+ prompt->dismissAndWait(5000);
+ QVERIFY(prompt->completed());
+ QVERIFY(prompt->dismissed());
+ delete prompt;
+
+ createReply = ifaceService.callWithArgumentList(QDBus::Block, "CreateCollection",
+ createInput);
+ QCOMPARE(createReply.type(), QDBusMessage::ReplyMessage);
+ createArgs = createReply.arguments();
+ QCOMPARE(createArgs.size(), 2);
+ QCOMPARE(createArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+ QCOMPARE(createArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
+ // TempBlockingCollection is blocking, so the first output (path) should be "/".
+ QCOMPARE(createArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
+ promptPath = createArgs.at(1).value<QDBusObjectPath>();
+ QVERIFY(promptPath.path().startsWith(
+ QLatin1String("/org/freedesktop/secrets/prompts/")));
+
+ // prompt and wait for the result.
+ prompt = new ClientPrompt(promptPath);
+ prompt->promptAndWait(5000);
+ QVERIFY(prompt->completed());
+ QVERIFY(!prompt->dismissed());
+ QCOMPARE(prompt->result().userType(), qMetaTypeId<QDBusObjectPath>());
+ QDBusObjectPath collectionPath = prompt->result().value<QDBusObjectPath>();
+ QVERIFY(collectionPath.path().startsWith(
+ QLatin1String("/org/freedesktop/secrets/collection/")));
+ QDBusInterface ifaceCollection("org.freedesktop.Secret", collectionPath.path(),
+ "org.freedesktop.Secret.Collection");
+ QVERIFY(ifaceCollection.isValid());
+ delete prompt;
+
+ // make sure the CollectionCreated signal was sent
+ if (createdSpy.size() < 1) {
+ createdSpy.waitForSignal(5000);
+ }
+ QCOMPARE(createdSpy.size(), 1);
+ QCOMPARE(createdSpy.takeFirst(), collectionPath);
+
+ // read collection properties
+ QVariant propItems = ifaceCollection.property("Items");
+ QVERIFY(propItems.isValid());
+ QVERIFY(propItems.canConvert<QList<QDBusObjectPath> >());
+ QList<QDBusObjectPath> propItemsList = propItems.value<QList<QDBusObjectPath> \
>(); + QVERIFY(propItemsList.isEmpty());
+ QVariant propLabel = ifaceCollection.property("Label");
+ QVERIFY(propLabel.isValid());
+ QCOMPARE(propLabel.type(), QVariant::String);
+ QCOMPARE(propLabel.value<QString>(), QString("test"));
+ QVariant propLocked = ifaceCollection.property("Locked");
+ QVERIFY(propLocked.isValid());
+ QCOMPARE(propLocked.value<bool>(), false);
+ QVariant propCreated = ifaceCollection.property("Created");
+ QVERIFY(propCreated.isValid());
+ QCOMPARE(propCreated.type(), QVariant::ULongLong);
+ qulonglong propCreatedUll = propCreated.value<qulonglong>();
+ QVERIFY(QDateTime::currentDateTime().toTime_t() - propCreatedUll < 60);
+ QVariant propModified = ifaceCollection.property("Modified");
+ QVERIFY(propModified.isValid());
+ QCOMPARE(propModified.type(), QVariant::ULongLong);
+ QCOMPARE(propModified.value<qulonglong>(), propCreatedUll);
+
+ // set the label and re-read it.
+ ifaceCollection.setProperty("Label", QString("test2"));
+ propLabel = ifaceCollection.property("Label");
+ QVERIFY(propLabel.isValid());
+ QCOMPARE(propLabel.type(), QVariant::String);
+ QCOMPARE(propLabel.value<QString>(), QString("test2"));
+
+ // make sure the CollectionChanged signal was sent
+ if (changedSpy.size() < 1) {
+ changedSpy.waitForSignal(5000);
+ }
+ QCOMPARE(changedSpy.size(), 1);
+ QCOMPARE(changedSpy.takeFirst(), collectionPath);
+
+ // delete the collection
+ QDBusMessage deleteReply = ifaceCollection.call(QDBus::Block, "Delete");
+ QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
+ QList<QVariant> deleteArgs = deleteReply.arguments();
+ QCOMPARE(deleteArgs.size(), 1);
+ QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+ // TempBlockingCollection is blocking, so the output (prompt) should be a valid \
one. + promptPath = deleteArgs.at(0).value<QDBusObjectPath>();
+ QVERIFY(promptPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/prompts/")));
+
+ // dismiss the prompt and wait for the result.
+ prompt = new ClientPrompt(promptPath);
+ prompt->dismissAndWait(5000);
+ QVERIFY(prompt->completed());
+ QVERIFY(prompt->dismissed());
+ delete prompt;
+
+ // retry and complete the prompt this time
+ deleteReply = ifaceCollection.call(QDBus::Block, "Delete");
+ QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
+ deleteArgs = deleteReply.arguments();
+ QCOMPARE(deleteArgs.size(), 1);
+ QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+ // TempBlockingCollection is blocking, so the output (prompt) should be a valid \
one. + promptPath = deleteArgs.at(0).value<QDBusObjectPath>();
+ QVERIFY(promptPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/prompts/")));
+ prompt = new ClientPrompt(promptPath);
+ prompt->promptAndWait(5000);
+ QVERIFY(prompt->completed());
+ QVERIFY(!prompt->dismissed());
+ delete prompt;
+
+ // make sure the collection is gone
+ QCOMPARE(ifaceCollection.call("Introspect").type(), QDBusMessage::ErrorMessage);
+
+ // make sure the CollectionDeleted signal was sent
+ if (deletedSpy.size() < 1) {
+ deletedSpy.waitForSignal(5000);
+ }
+ QCOMPARE(deletedSpy.size(), 1);
+ QCOMPARE(deletedSpy.takeFirst(), collectionPath);
+
+ // close the session
+ QDBusInterface("org.freedesktop.Secret", sessionPath.path()).call("Close");
+}
+
+void ServiceTest::blockingItem()
+{
+ // TODO: test
+}
+
void ServiceTest::cleanupTestCase()
{
delete m_service;
@@ -464,4 +648,43 @@ void ObjectPathSignalSpy::slotReceived(const QDBusObjectPath \
&objectPath) }
}
+ClientPrompt::ClientPrompt(QDBusObjectPath promptPath)
+ : m_completed(false), m_dismissed(false),
+ m_interface("org.freedesktop.Secret", promptPath.path())
+{
+ Q_ASSERT(m_interface.isValid());
+ connect(&m_interface, SIGNAL(Completed(bool, QDBusVariant)),
+ SLOT(slotCompleted(bool, QDBusVariant)));
+}
+
+void ClientPrompt::promptAndWait(int time)
+{
+ QDBusMessage reply = m_interface.call(QDBus::Block, "Prompt", QString(""));
+ Q_ASSERT(reply.type() == QDBusMessage::ReplyMessage);
+ justWait(time);
+}
+
+void ClientPrompt::dismissAndWait(int time)
+{
+ QDBusMessage reply = m_interface.call(QDBus::Block, "Dismiss");
+ Q_ASSERT(reply.type() == QDBusMessage::ReplyMessage);
+ justWait(time);
+}
+
+void ClientPrompt::slotCompleted(bool dismissed, const QDBusVariant &result)
+{
+ m_completed = true;
+ m_dismissed = dismissed;
+ m_result = result.variant();
+ m_loop.quit();
+}
+
+void ClientPrompt::justWait(int time)
+{
+ if (time > 0) {
+ QTimer::singleShot(time, &m_loop, SLOT(quit()));
+ }
+ m_loop.exec();
+}
+
#include "servicetest.moc"
diff --git a/daemon/tests/servicetest.h b/daemon/tests/servicetest.h
index 8320c0c..4f9dbb3 100644
--- a/daemon/tests/servicetest.h
+++ b/daemon/tests/servicetest.h
@@ -23,11 +23,16 @@
#include <QtCore/QObject>
#include <QtCore/QList>
+#include <QtCore/QVariant>
+#include <QtCore/QEventLoop>
+#include <QtDBus/QDBusVariant>
#include <QtDBus/QDBusObjectPath>
+#include <QtDBus/QDBusInterface>
class BackendMaster;
+class TemporaryCollectionManager;
+class TempBlockingCollectionManager;
class Service;
-class QDBusInterface;
class QDBusAbstractInterface;
/**
@@ -39,6 +44,8 @@ class ServiceTest : public QObject
private:
BackendMaster *m_master;
+ TemporaryCollectionManager *m_tempCollMan;
+ TempBlockingCollectionManager *m_tempBlockCollMan;
Service *m_service;
private Q_SLOTS:
@@ -57,6 +64,15 @@ private Q_SLOTS:
// create and remove items
void nonBlockingItem();
+ // change some of the parameters of the testcase needed for the tests to come
+ void reInitTestCase();
+
+ // create and remove blocking collections
+ void blockingCollection();
+
+ // create and remove blocking items
+ void blockingItem();
+
// cleanup
void cleanupTestCase();
};
@@ -95,4 +111,52 @@ private:
int m_numWaiting;
};
+/**
+ * Client mini-stub for org.freedesktop.Secret.Prompt.
+ */
+class ClientPrompt : public QObject
+{
+ Q_OBJECT
+
+public:
+ // constructor. wraps around the prompt at promptPath.
+ ClientPrompt(QDBusObjectPath promptPath);
+
+ // Call the Prompt method and wait some time for completion
+ // (sends bogus window-id)
+ void promptAndWait(int time);
+
+ // Call the Dismiss method and wait some time for completion
+ void dismissAndWait(int time);
+
+ // check if the call has been completed
+ bool completed() const {
+ return m_completed;
+ }
+
+ // check if the call was dismissed
+ bool dismissed() const {
+ return m_dismissed;
+ }
+
+ // get the call's result
+ const QVariant &result() const {
+ return m_result;
+ }
+
+private Q_SLOTS:
+ // listens for Completed signals of the D-Bus prompt.
+ void slotCompleted(bool dismissed, const QDBusVariant &result);
+
+private:
+ // just wait (called by *AndWait methods)
+ void justWait(int time);
+
+ bool m_completed;
+ bool m_dismissed;
+ QVariant m_result;
+ QDBusInterface m_interface;
+ QEventLoop m_loop;
+};
+
#endif
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic