Commit 1081b967 authored by David Faure's avatar David Faure
Browse files

autotests: add test for 404 error, make tests more robust

* Don't derive from QThread, encapsulate one instead (avoids
moveToThread(this))
* Allow client sockets to connect in any order they want.
Instead of requiring a fixed scenario order, we pick the scenario
corresponding to the first line of the client request
parent 13b36a65
......@@ -45,7 +45,6 @@ void DavCollectionsMultiFetchJobTest::runSuccessfullTest()
fakeServer.addScenarioFromFile(QLatin1String(AUTOTEST_DATA_DIR)+QStringLiteral("/dataitemmultifetchjob-carddav-collections.txt"));
fakeServer.startAndWait();
job->exec();
fakeServer.quit();
QVERIFY(fakeServer.isAllScenarioDone());
QCOMPARE(job->error(), 0);
......@@ -77,4 +76,26 @@ void DavCollectionsMultiFetchJobTest::runSuccessfullTest()
QCOMPARE(spy.at(1).at(2).toString(), url2.toString());
}
void DavCollectionsMultiFetchJobTest::shouldFailOnError()
{
FakeServer fakeServer(5990);
QUrl url(QStringLiteral("http://localhost/caldav"));
url.setPort(fakeServer.port());
KDAV::DavUrl davUrl1(url, KDAV::CalDav);
QUrl urlError(url);
urlError.setPath(QStringLiteral("/does_not_exist"));
KDAV::DavUrl davUrlError(urlError, KDAV::CalDav);
auto job = new KDAV::DavCollectionsMultiFetchJob({davUrl1, davUrlError});
fakeServer.addScenarioFromFile(QLatin1String(AUTOTEST_DATA_DIR)+QStringLiteral("/dataitemmultifetchjob-caldav.txt"));
fakeServer.addScenarioFromFile(QLatin1String(AUTOTEST_DATA_DIR)+QStringLiteral("/dataitemmultifetchjob-caldav-collections.txt"));
fakeServer.addScenarioFromFile(QLatin1String(AUTOTEST_DATA_DIR)+QStringLiteral("/dataitemmultifetchjob-error.txt"));
fakeServer.startAndWait();
job->exec();
QVERIFY(fakeServer.isAllScenarioDone());
QCOMPARE(job->error(), 300);
}
QTEST_MAIN(DavCollectionsMultiFetchJobTest)
......@@ -16,6 +16,7 @@ class DavCollectionsMultiFetchJobTest : public QObject
private Q_SLOTS:
void initTestCase();
void runSuccessfullTest();
void shouldFailOnError();
};
#endif
......@@ -33,7 +33,6 @@ void DavItemFetchJobTest::runSuccessfullTest()
fakeServer.addScenarioFromFile(QLatin1String(AUTOTEST_DATA_DIR)+QStringLiteral("/dataitemfetchjob.txt"));
fakeServer.startAndWait();
job->exec();
fakeServer.quit();
QVERIFY(fakeServer.isAllScenarioDone());
QCOMPARE(job->error(), 0);
......
......@@ -17,23 +17,26 @@
#include <QTest>
FakeServer::FakeServer(int port, QObject *parent)
: QThread(parent)
: QObject(parent)
, m_thread(new QThread)
, m_port(port)
{
moveToThread(this);
moveToThread(m_thread);
}
FakeServer::~FakeServer()
{
quit();
wait();
QMetaObject::invokeMethod(this, &FakeServer::cleanup);
m_thread->quit();
m_thread->wait();
delete m_thread;
}
void FakeServer::startAndWait()
{
start();
// this will block until the event queue starts
QMetaObject::invokeMethod(this, &FakeServer::started, Qt::BlockingQueuedConnection);
m_thread->start();
// this will block until the init code happens and the event queue starts
QMetaObject::invokeMethod(this, &FakeServer::init, Qt::BlockingQueuedConnection);
}
void FakeServer::dataAvailable()
......@@ -43,14 +46,12 @@ void FakeServer::dataAvailable()
QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
Q_ASSERT(socket != nullptr);
int scenarioNumber = m_clientSockets.indexOf(socket);
if (scenarioNumber >= m_scenarios.size()) {
qWarning() << "There is no scenario for socket" << scenarioNumber << ", we got more connections than expected";
int scenarioNumber = -1;
readClientPart(socket, &scenarioNumber);
if (scenarioNumber >= 0) {
Q_ASSERT(scenarioNumber < m_scenarios.count());
writeServerPart(socket, scenarioNumber);
}
readClientPart(scenarioNumber);
writeServerPart(scenarioNumber);
}
void FakeServer::newConnection()
......@@ -61,7 +62,7 @@ void FakeServer::newConnection()
connect(m_clientSockets.last(), &QTcpSocket::readyRead, this, &FakeServer::dataAvailable);
}
void FakeServer::run()
void FakeServer::init()
{
m_tcpServer = new QTcpServer();
......@@ -70,17 +71,12 @@ void FakeServer::run()
}
connect(m_tcpServer, &QTcpServer::newConnection, this, &FakeServer::newConnection);
exec();
qDeleteAll(m_clientSockets);
delete m_tcpServer;
}
void FakeServer::started()
void FakeServer::cleanup()
{
// do nothing: this is a dummy slot used by startAndWait()
qDeleteAll(m_clientSockets);
delete m_tcpServer;
}
void FakeServer::setScenario(const QList<QByteArray> &scenario)
......@@ -138,10 +134,9 @@ bool FakeServer::isAllScenarioDone() const
return true;
}
void FakeServer::writeServerPart(int scenarioNumber)
void FakeServer::writeServerPart(QTcpSocket *clientSocket, int scenarioNumber)
{
QList<QByteArray> scenario = m_scenarios[scenarioNumber];
QTcpSocket *clientSocket = m_clientSockets[scenarioNumber];
while (!scenario.isEmpty() &&
scenario.first().startsWith("S: ")) {
......@@ -177,12 +172,19 @@ void FakeServer::writeServerPart(int scenarioNumber)
m_scenarios[scenarioNumber] = scenario;
}
void FakeServer::readClientPart(int scenarioNumber)
void FakeServer::readClientPart(QTcpSocket *socket, int *scenarioNumber)
{
QList<QByteArray> scenario = m_scenarios[scenarioNumber];
QTcpSocket *socket = m_clientSockets[scenarioNumber];
QByteArray line = socket->readLine();
qDebug() << "Read client request" << line;
const auto it = std::find_if(m_scenarios.begin(), m_scenarios.end(), [&](const QList<QByteArray> &scenario) {
return !scenario.isEmpty() && scenario.at(0).mid(3) + "\r\n" == line;
});
if (it == m_scenarios.end()) {
qWarning() << "No server response available for" << line;
QFAIL("Unexpected request");
return;
}
QList<QByteArray> scenario = *it;
QVector<QByteArray> header;
while (line != "\r\n") {
......@@ -211,7 +213,9 @@ void FakeServer::readClientPart(int scenarioNumber)
QVERIFY(scenario.first().startsWith("S: "));
}
m_scenarios[scenarioNumber] = scenario;
*it = scenario;
*scenarioNumber = std::distance(m_scenarios.begin(), it);
QVERIFY(*scenarioNumber < m_scenarios.count());
}
int FakeServer::port() const
......
......@@ -76,7 +76,7 @@ Q_DECLARE_METATYPE(QList<QByteArray>)
* @endcode
*/
class FakeServer : public QThread
class FakeServer : public QObject
{
Q_OBJECT
......@@ -94,15 +94,6 @@ public:
*/
void startAndWait();
/**
* Starts the fake server
*
* You should not call this directly. Use start() instead.
*
* @reimp
*/
void run() override;
/**
* Removes any previously-added scenarios, and adds a new one
*
......@@ -168,16 +159,18 @@ public:
private Q_SLOTS:
void newConnection();
void dataAvailable();
void started();
void init();
void cleanup();
private:
void writeServerPart(int scenarioNumber);
void readClientPart(int scenarioNumber);
void writeServerPart(QTcpSocket *clientSocket, int scenarioNumber);
void readClientPart(QTcpSocket *socket, int *scenarioNumber);
QList< QList<QByteArray> > m_scenarios;
QTcpServer *m_tcpServer;
QTcpServer *m_tcpServer = nullptr;
mutable QMutex m_mutex;
QList<QTcpSocket *> m_clientSockets;
QThread *m_thread;
int m_port;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment