Commit 9d4659c2 authored by Laurent Montel's avatar Laurent Montel 😁
Browse files

Remove autotest that we can't execute as we don't any mailtransport

akonadi
parent c52647d6
if (BUILD_TESTING)
add_subdirectory( autotests )
endif()
add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_maildispatcher_agent\")
set( maildispatcheragent_SRCS
......
include(ECMMarkAsTest)
find_package(Qt5Test CONFIG REQUIRED)
set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} )
# Stolen from kdepimlibs/akonadi/tests
macro(add_akonadi_isolated_test _source)
get_filename_component(_targetName ${_source} NAME_WE)
set(_srcList ${_source} )
add_executable(${_targetName} ${_srcList})
ecm_mark_as_test(maildispatcher-${_targetName})
target_link_libraries(${_targetName}
Qt5::Test
KF5::AkonadiCore
KF5::AkonadiMime
KF5::MailTransportAkonadi
KF5::Mime
KF5::I18n
KF5::ConfigGui
Qt5::DBus
Qt5::Widgets
)
# based on kde4_add_unit_test
if (WIN32)
get_target_property( _loc ${_targetName} LOCATION )
set(_executable ${_loc}.bat)
else ()
set(_executable ${EXECUTABLE_OUTPUT_PATH}/${_targetName})
endif ()
if (UNIX)
set(_executable ${_executable}.shell)
endif ()
find_program(_testrunner akonaditest)
if (KDEPIM_RUN_ISOLATED_TESTS)
add_test( maildispatcheragent-${_targetName} ${_testrunner} -c ${CMAKE_CURRENT_SOURCE_DIR}/unittestenv/config.xml ${_executable} )
endif ()
endmacro(add_akonadi_isolated_test)
add_akonadi_isolated_test( aborttest.cpp )
add_akonadi_isolated_test( dupetest.cpp )
* test online / offline
* figure out why ksyscoca is started (it's not the wallet apparently)
* aborttest: test aborting when there is >1 message queued
* test the various SendBehaviours and DispatchModes
* dupetest -> probably faster and more effective if I just use random intervals
of time between queuing messages
/*
Copyright 2009 Constantin Berzan <exit3219@gmail.com>
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 "aborttest.h"
#include <QDBusInterface>
#include <QDBusReply>
#include <QDebug>
#include <AkonadiCore/AgentInstance>
#include <AkonadiCore/AgentManager>
#include <AkonadiCore/collectionstatistics.h>
#include <AkonadiCore/Control>
#include <AkonadiCore/ItemDeleteJob>
#include <AkonadiCore/ItemFetchJob>
#include <AkonadiCore/ItemFetchScope>
#include <AkonadiCore/ItemModifyJob>
#include <AkonadiCore/Monitor>
#include <AkonadiCore/qtest_akonadi.h>
#include <AkonadiCore/collectionpathresolver.h>
#include <Akonadi/KMime/MessageFlags>
#include <Akonadi/KMime/SpecialMailCollections>
#include <Akonadi/KMime/SpecialMailCollectionsRequestJob>
#include <mailtransportakonadi/dispatcherinterface.h>
#include <mailtransportakonadi/errorattribute.h>
#include <mailtransportakonadi/messagequeuejob.h>
#include <mailtransport/transport.h>
#include <mailtransportakonadi/transportattribute.h>
#include <mailtransport/transportmanager.h>
#include <kmime/kmime_message.h>
#include <QSignalSpy>
#define SPAM_ADDRESS "idanoka@gmail.com"
// NOTE: This test relies on a large SMTP message taking long enough to deliver,
// for it to call abort. So we need a valid receiver and a not-too-fast connection.
#define MESSAGE_MB 1
using namespace Akonadi;
using namespace KMime;
using namespace MailTransport;
void AbortTest::initTestCase()
{
QVERIFY(Control::start());
QTest::qWait(1000);
qRegisterMetaType<Akonadi::Item>();
qRegisterMetaType<Akonadi::Collection>();
// Get the outbox and clear it.
SpecialMailCollectionsRequestJob *rjob = new SpecialMailCollectionsRequestJob(this);
rjob->requestDefaultCollection(SpecialMailCollections::Outbox);
QSignalSpy spy(rjob, SIGNAL(result(KJob*)));
spy.wait(0);
outbox = SpecialMailCollections::self()->defaultCollection(SpecialMailCollections::Outbox);
QVERIFY(outbox.isValid());
ItemDeleteJob *djob = new ItemDeleteJob(outbox);
djob->exec(); // may give error if outbox empty
// Verify transports.
akoTid = TransportManager::self()->defaultTransportId();
Transport *t = TransportManager::self()->transportById(akoTid);
QVERIFY(t);
QCOMPARE(t->type(), int(Transport::EnumType::Akonadi));
QList<int> tids = TransportManager::self()->transportIds();
tids.removeAll(akoTid);
QCOMPARE(tids.count(), 1);
smtpTid = tids.first();
t = TransportManager::self()->transportById(smtpTid);
QVERIFY(t);
QCOMPARE(t->type(), int(Transport::EnumType::SMTP));
// Set sink collection.
t = TransportManager::self()->transportById(akoTid);
const QString rid = t->host();
const AgentInstance agent = AgentManager::self()->instance(rid);
QVERIFY(agent.isValid());
CollectionPathResolver *resolver = new CollectionPathResolver(QStringLiteral("sink"), this);
QVERIFY(resolver->exec());
sink = Collection(resolver->collection());
QVERIFY(sink.isValid());
QDBusInterface conf(QLatin1String("org.freedesktop.Akonadi.Resource.") + rid,
QStringLiteral("/Settings"), QStringLiteral("org.kde.Akonadi.MailTransportDummy.Settings"));
QVERIFY(conf.isValid());
QDBusReply<void> reply = conf.call(QStringLiteral("setSink"), sink.id());
QVERIFY(reply.isValid());
agent.reconfigure();
// Watch sink collection.
monitor = new Monitor(this);
monitor->setCollectionMonitored(sink);
}
void AbortTest::testAbort()
{
// Get the MDA interface.
DispatcherInterface iface;
QVERIFY(iface.dispatcherInstance().isValid());
QVERIFY(iface.dispatcherInstance().isOnline());
// Create a large message.
qDebug() << "Building message.";
Message::Ptr msg = Message::Ptr(new Message);
QByteArray line(70, 'a');
line.append("\n");
QByteArray content("\n");
for (int i = 0; i < MESSAGE_MB * 1024 * 1024 / line.length() + 10; i++) {
content.append(line);
}
QVERIFY(content.length() > MESSAGE_MB * 1024 * 1024); // >10MiB
msg->setContent(content);
// Queue the message.
qDebug() << "Queuing message.";
MessageQueueJob *qjob = new MessageQueueJob(this);
qjob->setMessage(msg);
qjob->transportAttribute().setTransportId(smtpTid);
// default dispatch mode
// default sent-mail collection
qjob->addressAttribute().setFrom(QStringLiteral("naiba"));
qjob->addressAttribute().setTo(QStringList() << QStringLiteral(SPAM_ADDRESS));
QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Idle);
AKVERIFYEXEC(qjob);
// Wait for the MDA to begin dispatching.
for (int ds = 0; iface.dispatcherInstance().status() == AgentInstance::Idle; ds++) {
QTest::qWait(100);
if (ds % 10 == 0) {
qDebug() << "Waiting for the MDA to begin dispatching." << ds / 10 << "seconds elapsed.";
}
QVERIFY2(ds <= 100, "Timeout");
}
QTest::qWait(100);
// Tell the MDA to abort.
QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Running);
iface.dispatcherInstance().abortCurrentTask();
for (int ds = 0; iface.dispatcherInstance().status() != AgentInstance::Idle; ds++) {
QTest::qWait(100);
if (ds % 10 == 0) {
qDebug() << "Waiting for the MDA to become idle after aborting." << ds / 10 << "seconds elapsed.";
}
QVERIFY2(ds <= 100, "Timeout");
}
QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Idle);
// Verify that item has an ErrorAttribute.
ItemFetchJob *fjob = new ItemFetchJob(outbox);
fjob->fetchScope().fetchAllAttributes();
AKVERIFYEXEC(fjob);
QCOMPARE(fjob->items().count(), 1);
Item item = fjob->items().at(0);
QVERIFY(item.hasAttribute<ErrorAttribute>());
ErrorAttribute *eA = item.attribute<ErrorAttribute>();
qDebug() << "Stored error:" << eA->message();
// "Fix" the item and send again, this time with the default (Akonadi) transport.
item.removeAttribute<ErrorAttribute>();
item.clearFlag(Akonadi::MessageFlags::HasError);
item.setFlag(Akonadi::MessageFlags::Queued);
TransportAttribute *newTA = new TransportAttribute(akoTid);
item.addAttribute(newTA);
ItemModifyJob *cjob = new ItemModifyJob(item);
QSignalSpy *addSpy = new QSignalSpy(monitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)));
AKVERIFYEXEC(cjob);
// Verify that the item got sent.
for (int ds = 0; addSpy->isEmpty(); ds++) {
QTest::qWait(100);
if (ds % 10 == 0) {
qDebug() << "Waiting for an item to be sent." << ds / 10 << "seconds elapsed.";
}
QVERIFY2(ds <= 100, "Timeout");
}
QCOMPARE(addSpy->count(), 1);
QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Idle);
}
void AbortTest::testAbortWhileIdle()
{
// Get the MDA interface.
DispatcherInterface iface;
QVERIFY(iface.dispatcherInstance().isValid());
QVERIFY(iface.dispatcherInstance().isOnline());
// Abort thin air.
QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Idle);
iface.dispatcherInstance().abortCurrentTask();
QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Idle);
// Queue a message (to check that subsequent messages are being sent).
QVERIFY(monitor);
QSignalSpy *addSpy = new QSignalSpy(monitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)));
Message::Ptr msg = Message::Ptr(new Message);
msg->setContent("\ntestAbortWhileIdle");
MessageQueueJob *qjob = new MessageQueueJob(this);
qjob->setMessage(msg);
qjob->transportAttribute().setTransportId(akoTid);
// default dispatch mode
// default sent-mail collection
qjob->addressAttribute().setFrom(QStringLiteral("naiba"));
qjob->addressAttribute().setTo(QStringList() << QStringLiteral("dracu"));
QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Idle);
AKVERIFYEXEC(qjob);
// Verify that the item got sent.
for (int s = 0; addSpy->isEmpty(); s++) {
QTest::qWait(1000);
QVERIFY2(s <= 10, "Timeout");
}
QCOMPARE(addSpy->count(), 1);
QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Idle);
}
QTEST_AKONADIMAIN(AbortTest)
/*
Copyright 2009 Constantin Berzan <exit3219@gmail.com>
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 ABORTTEST_H
#define ABORTTEST_H
#include <QtCore/QObject>
#include <AkonadiCore/collection.h>
namespace Akonadi
{
class Monitor;
}
/**
This attempts to send a large message, then aborts it, then tries to send
it again and verify that it succeeds.
*/
class AbortTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void testAbort();
void testAbortWhileIdle();
private:
int akoTid;
int smtpTid;
Akonadi::Collection outbox;
Akonadi::Collection sink;
Akonadi::Monitor *monitor;
};
#endif
/*
Copyright 2009 Constantin Berzan <exit3219@gmail.com>
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 "dupetest.h"
#include <QDBusInterface>
#include <QDBusReply>
#include <QDebug>
#include <AkonadiCore/Control>
#include <AkonadiCore/AgentInstance>
#include <AkonadiCore/AgentManager>
#include <AkonadiCore/CollectionFetchJob>
#include <AkonadiCore/ItemDeleteJob>
#include <AkonadiCore/ItemFetchJob>
#include <AkonadiCore/ItemFetchScope>
#include <AkonadiCore/qtest_akonadi.h>
#include <AkonadiCore/collectionpathresolver.h>
#include <mailtransportakonadi/messagequeuejob.h>
#include <mailtransport/transport.h>
#include <mailtransport/transportmanager.h>
#include <kmime/kmime_message.h>
static const int TIMEOUT_SECONDS = 60;
static const int MAXCOUNT = 99; // must be 2-digit!
using namespace Akonadi;
using namespace KMime;
using namespace MailTransport;
void DupeTest::initTestCase()
{
QVERIFY(Control::start());
QTest::qWait(1000); // give the MDA time to start
qRegisterMetaType<Akonadi::Item>();
qRegisterMetaType<Akonadi::Collection>();
// we need a default Akonadi transport
int tid = TransportManager::self()->defaultTransportId();
Transport *t = TransportManager::self()->transportById(tid);
QVERIFY(t);
QCOMPARE(t->type(), int(Transport::EnumType::Akonadi));
// set the sink collection
const QString rid = t->host();
const AgentInstance agent = AgentManager::self()->instance(rid);
QVERIFY(agent.isValid());
CollectionPathResolver *resolver = new CollectionPathResolver(QStringLiteral("sink"), this);
QVERIFY(resolver->exec());
sink = Collection(resolver->collection());
QVERIFY(sink.isValid());
QDBusInterface conf(QLatin1String("org.freedesktop.Akonadi.Resource.") + rid,
QStringLiteral("/Settings"), QStringLiteral("org.kde.Akonadi.MailTransportDummy.Settings"));
QVERIFY(conf.isValid());
QDBusReply<void> reply = conf.call(QStringLiteral("setSink"), sink.id());
QVERIFY(reply.isValid());
agent.reconfigure();
// set up monitor
monitor = new Monitor(this);
monitor->setCollectionMonitored(sink);
monitor->itemFetchScope().fetchFullPayload();
}
void DupeTest::testDupes_data()
{
QTest::addColumn<QString>("message"); // the prefix of the message to send (-msg## is appended)
QTest::addColumn<int>("count"); // how many copies to send
QTest::addColumn<int>("delay"); // number of ms to wait before sending next copy
QTest::newRow("1-nodelay") << "\n1-nodelay" << 1 << 0;
QTest::newRow("2-nodelay") << "\n2-nodelay" << 2 << 0;
QTest::newRow("5-nodelay") << "\n5-nodelay" << 5 << 0;
QTest::newRow("10-nodelay") << "\n10-nodelay" << 10 << 0;
QTest::newRow("20-nodelay") << "\n20-nodelay" << 20 << 0;
QTest::newRow("50-nodelay") << "\n50-nodelay" << 50 << 0;
QTest::newRow("99-nodelay") << "\n99-nodelay" << 99 << 0;
QTest::newRow("2-veryshortdelay") << "\n2-veryshortdelay" << 2 << 20;
QTest::newRow("5-veryshortdelay") << "\n5-veryshortdelay" << 5 << 20;
QTest::newRow("10-veryshortdelay") << "\n10-veryshortdelay" << 10 << 20;
QTest::newRow("20-veryshortdelay") << "\n20-veryshortdelay" << 20 << 20;
QTest::newRow("50-veryshortdelay") << "\n50-veryshortdelay" << 50 << 20;
QTest::newRow("99-veryshortdelay") << "\n99-veryshortdelay" << 99 << 20;
QTest::newRow("2-shortdelay") << "\n2-shortdelay" << 2 << 100;
QTest::newRow("5-shortdelay") << "\n5-shortdelay" << 5 << 100;
QTest::newRow("10-shortdelay") << "\n10-shortdelay" << 10 << 100;
QTest::newRow("20-shortdelay") << "\n20-shortdelay" << 20 << 100;
QTest::newRow("50-shortdelay") << "\n50-shortdelay" << 50 << 100;
QTest::newRow("99-shortdelay") << "\n99-shortdelay" << 99 << 99;
QTest::newRow("2-longdelay") << "\n2-longdelay" << 2 << 1000;
QTest::newRow("5-longdelay") << "\n5-longdelay" << 5 << 1000;
QTest::newRow("5-verylongdelay") << "\n5-verylongdelay" << 5 << 4000;
Q_ASSERT(99 <= MAXCOUNT);
Q_ASSERT(MAXCOUNT < 100); // 2-digit
// TODO I'm not sure more items means a better test
// TODO test large items
// TODO test modifying items while they are being sent...
}
void DupeTest::testDupes()
{
QFETCH(QString, message);
QFETCH(int, count);
QFETCH(int, delay);
// clean sink
ItemFetchJob *fjob = new ItemFetchJob(sink, this);
AKVERIFYEXEC(fjob);
if (fjob->items().count() > 0) {
// this test is needed because ItemDeleteJob gives error if no items are found
ItemDeleteJob *djob = new ItemDeleteJob(sink, this);
AKVERIFYEXEC(djob);
}
fjob = new ItemFetchJob(sink, this);
AKVERIFYEXEC(fjob);
QCOMPARE(fjob->items().count(), 0);
// queue messages
Q_ASSERT(monitor);
QSignalSpy *addSpy = new QSignalSpy(monitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)));
qDebug() << "Queuing" << count << "messages...";
for (int i = 0; i < count; i++) {
//qDebug() << "Queuing message" << i + 1 << "of" << count;
Message::Ptr msg = Message::Ptr(new Message);
msg->setContent(QStringLiteral("%1-msg%2\n").arg(message).arg(i + 1, 2, 10, QLatin1Char('0')).toLatin1());
MessageQueueJob *job = new MessageQueueJob(this);
job->setMessage(msg);
job->transportAttribute().setTransportId(TransportManager::self()->defaultTransportId());
// default dispatch mode
// default sent-mail collection
job->addressAttribute().setFrom(QStringLiteral("naiba"));
job->addressAttribute().setTo(QStringList() << QStringLiteral("dracu"));
//AKVERIFYEXEC( job );
job->start();
QTest::qWait(delay);
}
qDebug() << "Queued" << count << "messages.";
// wait for the MDA to send them
int seconds = 0;
while (true) {
seconds++;
QTest::qWait(1000);
qDebug() << seconds << "seconds elapsed." << addSpy->count() << "messages got to sink.";
if (addSpy->count() >= count) {
break;
}
#if 0
if (seconds >= TIMEOUT_SECONDS) {
qDebug() << "Timeout, gdb master!";
QTest::qWait(1000 * 1000);
}
#endif
QVERIFY2(seconds < TIMEOUT_SECONDS, "Timeout");
}
// TODO I should verify that the MDA has actually finished its work and has an empty queue
QTest::qWait(2000);
// verify what has been sent
fjob = new ItemFetchJob(sink, this);
fjob->fetchScope().fetchFullPayload();
AKVERIFYEXEC(fjob);
const Item::List items = fjob->items();
int found[ MAXCOUNT ];
for (int i = 0; i < count; i++) {
found[i] = 0;
}
for (int i = 0; i < items.count(); i++) {
QVERIFY(items[i].hasPayload<Message::Ptr>());
Message::Ptr msg = items[i].payload<Message::Ptr>();
const QByteArray content = msg->encodedContent();
//qDebug() << "i" << i << "content" << content;
int loc = content.indexOf("-msg");
QVERIFY(loc >= 0);
bool ok;
int who = content.mid(loc + 4, 2).toInt(&ok);
QVERIFY(ok);
//qDebug() << "identified msg" << who;
QVERIFY(who > 0 && who <= count);
found[ who - 1 ]++;
}
for (int i = 0; i < count; i++) {
if (found[i] > 1) {
qDebug() << "found duplicate message" << i + 1 << "(" << found[i] << "times )";
} else if (found[i] < 1) {
qDebug() << "didn't find message" << i + 1;
}
QCOMPARE(found[i], 1);
}
QCOMPARE(addSpy->count(), count);
QCOMPARE(items.count(), count);
}
QTEST_AKONADIMAIN(DupeTest)
/*
Copyright 2009 Constantin Berzan <exit3219@gmail.com>
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