Skip to content

Commit

Permalink
Wip: Implement test for connection validator
Browse files Browse the repository at this point in the history
  • Loading branch information
TheOneRing committed Jan 11, 2024
1 parent 8d088ee commit 4c90270
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 2 deletions.
7 changes: 5 additions & 2 deletions src/gui/connectionvalidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ Q_LOGGING_CATEGORY(lcConnectionValidator, "sync.connectionvalidator", QtInfoMsg)
// Make sure the timeout for this job is less than how often we get called
// This makes sure we get tried often enough without "ConnectionValidator already running"
namespace {
const auto timeoutToUse = ConnectionValidator::DefaultCallingInterval - 5s;
auto timeoutToUse()
{
return std::min(ConnectionValidator::DefaultCallingInterval - 5s, AbstractNetworkJob::httpTimeout);
};
}

ConnectionValidator::ConnectionValidator(AccountPtr account, QObject *parent)
Expand Down Expand Up @@ -194,7 +197,7 @@ void ConnectionValidator::checkAuthentication()
// we explicitly use a legacy dav path here
auto *job = new PropfindJob(_account, _account->url(), Theme::instance()->webDavPath(), PropfindJob::Depth::Zero, this);
job->setAuthenticationJob(true); // don't retry
job->setTimeout(timeoutToUse);
job->setTimeout(timeoutToUse());
job->setProperties({ QByteArrayLiteral("getlastmodified") });
connect(job, &PropfindJob::finishedWithoutError, this, &ConnectionValidator::slotAuthSuccess);
connect(job, &PropfindJob::finishedWithError, this, &ConnectionValidator::slotAuthFailed);
Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ owncloud_add_test(SyncFileItem)
owncloud_add_test(ConcatUrl)
owncloud_add_test(XmlParse)
owncloud_add_test(ChecksumValidator)
owncloud_add_test(ConnectionValidator)


# TODO: we need keychain access for this test
Expand Down
11 changes: 11 additions & 0 deletions test/testconnectionvalidator/status.php.json.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"installed": true,
"maintenance": @{maintenance},
"needsDbUpgrade": false,
"version": "10.11.0.0",
"versionstring": "10.11.0",
"edition": "Community",
"productname": "Infinite Scale",
"product": "Infinite Scale",
"productversion": "4.0.5"
}
89 changes: 89 additions & 0 deletions test/testconnectionvalidator/testconnectionvalidator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright (C) by Hannah von Reth <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License
* for more details.
*/

#include <QtTest>

#include "gui/connectionvalidator.h"
#include "libsync/abstractnetworkjob.h"

#include "testutils/syncenginetestutils.h"
#include "testutils/testutils.h"

using namespace std::chrono_literals;

using namespace OCC;

class TestConnectionValidator : public QObject
{
Q_OBJECT

// we can't use QMap direclty with QFETCH
using Values = QMap<QString, QString>;
auto getPayload(const QString &payloadName)
{
QFile f(QStringLiteral(SOURCEDIR "/test/testconnectionvalidator/%1").arg(payloadName));
Q_ASSERT(f.open(QIODevice::ReadOnly));
return f.readAll();
}

auto getPayloadTemplated(const QString &payloadName, const QMap<QString, QString> &values)
{
return Utility::renderTemplate(QString::fromUtf8(getPayload(payloadName)), values).toUtf8();
}

private Q_SLOTS:


void initTestCase() { AbstractNetworkJob::httpTimeout = 1s; }

void testStatusPhp_data()
{
QTest::addColumn<Values>("values");
QTest::addColumn<ConnectionValidator::Status>("status");
QTest::addColumn<std::chrono::seconds>("delay");

QTest::newRow("success") << Values{{QStringLiteral("maintenance"), QStringLiteral("false")}} << ConnectionValidator::Connected << 0s;
QTest::newRow("maintenance") << Values{{QStringLiteral("maintenance"), QStringLiteral("true")}} << ConnectionValidator::MaintenanceMode << 0s;
QTest::newRow("timeout") << Values{{QStringLiteral("maintenance"), QStringLiteral("false")}} << ConnectionValidator::Timeout << 60s;
}

void testStatusPhp()
{
QFETCH(Values, values);
QFETCH(ConnectionValidator::Status, status);
QFETCH(std::chrono::seconds, delay);

FakeFolder fakeFolder({});

fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *) -> QNetworkReply * {
const auto path = request.url().path();
if (op == QNetworkAccessManager::GetOperation) {
if (path.endsWith(QLatin1String("status.php"))) {
return new DelayedReply<FakePayloadReply>(delay, op, request, getPayloadTemplated(QStringLiteral("status.php.json.in"), values), this);
}
}
return nullptr;
});

ConnectionValidator val(fakeFolder.account());
val.checkServer(ConnectionValidator::ValidationMode::ValidateServer);

QSignalSpy spy(&val, &ConnectionValidator::connectionResult);
QVERIFY(spy.wait(60s));
QCOMPARE(spy.first().first().value<ConnectionValidator::Status>(), status);
}
};

QTEST_MAIN(TestConnectionValidator)
#include "testconnectionvalidator.moc"

0 comments on commit 4c90270

Please sign in to comment.