Extend tests of connector library

This commit is contained in:
Martchus 2017-03-09 23:06:03 +01:00
parent a3887749a5
commit 0868f2cf6a
9 changed files with 408 additions and 183 deletions

View File

@ -9,7 +9,7 @@ set(META_APP_DESCRIPTION "Tray application for Syncthing")
set(META_APP_CATEGORIES "System;Utility;Network;FileTransfer")
set(META_VERSION_MAJOR 0)
set(META_VERSION_MINOR 5)
set(META_VERSION_PATCH 0)
set(META_VERSION_PATCH 1)
set(META_VERSION_EXACT_SONAME ON)
project(${META_PROJECT_NAME})

View File

@ -31,10 +31,12 @@ set(SRC_FILES
)
set(TEST_HEADER_FILES
tests/helper.h
)
set(TEST_SRC_FILES
tests/cppunit.cpp
tests/connectiontests.cpp
tests/misctests.cpp
)
set(TS_FILES

View File

@ -105,10 +105,14 @@ QString SyncthingConnection::statusText() const
return tr("reconnecting");
case SyncthingStatus::Idle:
return tr("connected");
case SyncthingStatus::Scanning:
return tr("connected, scanning");
case SyncthingStatus::Paused:
return tr("connected, paused");
case SyncthingStatus::Synchronizing:
return tr("connected, synchronizing");
case SyncthingStatus::OutOfSync:
return tr("connected, out of sync");
default:
return tr("unknown");
}

View File

@ -1,7 +1,7 @@
<configuration version="18">
<folder id="test1" label="" path="/tmp/some/path/1" type="readwrite" rescanIntervalS="7200" ignorePerms="false" autoNormalize="true">
<device id="6EIS2PN-J2IHWGS-AXS3YUL-HC5FT3K-77ZXTLL-AKQLJ4C-7SWVPUS-AZW4RQ4" introducedBy=""></device>
<configuration version="19">
<folder id="test1" label="" path="/tmp/some/path/1/" type="readwrite" rescanIntervalS="7200" ignorePerms="false" autoNormalize="true">
<device id="MMGUI6U-WUEZQCP-XZZ6VYB-LCT4TVC-ER2HAVX-QYT6X7D-S6ZSG2B-323KLQ7" introducedBy=""></device>
<device id="6EIS2PN-J2IHWGS-AXS3YUL-HC5FT3K-77ZXTLL-AKQLJ4C-7SWVPUS-AZW4RQ4" introducedBy=""></device>
<minDiskFreePct>1</minDiskFreePct>
<versioning></versioning>
<copiers>1</copiers>
@ -19,7 +19,7 @@
<paused>false</paused>
<weakHashThresholdPct>25</weakHashThresholdPct>
</folder>
<folder id="test2" label="Test dir 2" path="/tmp/some/path/2" type="readwrite" rescanIntervalS="31536000" ignorePerms="false" autoNormalize="true">
<folder id="test2" label="Test dir 2" path="/tmp/some/path/2/" type="readwrite" rescanIntervalS="31536000" ignorePerms="false" autoNormalize="true">
<device id="MMGUI6U-WUEZQCP-XZZ6VYB-LCT4TVC-ER2HAVX-QYT6X7D-S6ZSG2B-323KLQ7" introducedBy=""></device>
<minDiskFreePct>1</minDiskFreePct>
<versioning></versioning>
@ -38,14 +38,14 @@
<paused>true</paused>
<weakHashThresholdPct>25</weakHashThresholdPct>
</folder>
<device id="6EIS2PN-J2IHWGS-AXS3YUL-HC5FT3K-77ZXTLL-AKQLJ4C-7SWVPUS-AZW4RQ4" name="Test dev 1" compression="metadata" introducer="false" skipIntroductionRemovals="false" introducedBy="">
<address>dynamic</address>
<paused>false</paused>
</device>
<device id="MMGUI6U-WUEZQCP-XZZ6VYB-LCT4TVC-ER2HAVX-QYT6X7D-S6ZSG2B-323KLQ7" name="Test dev 2" compression="metadata" introducer="false" skipIntroductionRemovals="false" introducedBy="">
<address>tcp://192.168.2.2:22000</address>
<paused>true</paused>
</device>
<device id="6EIS2PN-J2IHWGS-AXS3YUL-HC5FT3K-77ZXTLL-AKQLJ4C-7SWVPUS-AZW4RQ4" name="Test dev 1" compression="metadata" introducer="true" skipIntroductionRemovals="false" introducedBy="">
<address>dynamic</address>
<paused>false</paused>
</device>
<gui enabled="true" tls="false" debugging="false">
<address>127.0.0.1:4001</address>
<apikey>syncthingconnectortest</apikey>
@ -79,7 +79,6 @@
<keepTemporariesH>24</keepTemporariesH>
<cacheIgnoredFiles>false</cacheIgnoredFiles>
<progressUpdateIntervalS>5</progressUpdateIntervalS>
<symlinksEnabled>true</symlinksEnabled>
<limitBandwidthInLan>false</limitBandwidthInLan>
<minHomeDiskFreePct>1</minHomeDiskFreePct>
<releasesURL>https://upgrades.syncthing.net/meta.json</releasesURL>

View File

@ -1,21 +1,19 @@
#include "./syncthingconnection.h"
#include "./helper.h"
#include "../syncthingconnection.h"
#include <c++utilities/tests/testutils.h>
#include <c++utilities/conversion/stringbuilder.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestFixture.h>
#include <QCoreApplication>
#include <QProcess>
#include <QFileInfo>
#include <QDir>
#include <QMetaMethod>
#include <QStringBuilder>
using namespace std;
using namespace Data;
using namespace TestUtilities;
using namespace ConversionUtilities;
using namespace CPPUNIT_NS;
@ -38,9 +36,9 @@ public:
private:
template<typename Signal, typename Action, typename Handler = function<void(void)> >
void waitForConnection(Signal signal, Action action, int timeout = 2500, Handler handler = nullptr);
template<typename Signal, typename Handler = function<void(void)> >
void waitForConnection(Signal signal, int timeout = 2500, Handler handler = nullptr);
void waitForConnection(Signal signal, Action action, Handler handler = nullptr, bool *ok = nullptr, int timeout = 1000);
template<typename Signal, typename Action, typename Handler = function<void(void)> >
void waitForConnectionAnyAction(Signal signal, Action action, Handler handler = nullptr, bool *ok = nullptr, int timeout = 1000);
QString m_apiKey;
QCoreApplication m_app;
@ -50,8 +48,8 @@ private:
CPPUNIT_TEST_SUITE_REGISTRATION(ConnectionTests);
int dummy1 = 0;
char *dummy2;
static int dummy1 = 0;
static char *dummy2;
ConnectionTests::ConnectionTests() :
m_apiKey(QStringLiteral("syncthingconnectortest")),
@ -133,102 +131,22 @@ void ConnectionTests::tearDown()
// test helper
//
/*!
* \brief Prints a QString; required to use QString with CPPUNIT_ASSERT_EQUAL_MESSAGE.
*/
std::ostream &operator <<(std::ostream &o, const QString &qstring)
{
o << qstring.toLocal8Bit().data();
return o;
}
/*!
* \brief Waits for the in ms specified \a duration keeping the event loop running.
*/
void wait(int duration)
{
QEventLoop loop;
QTimer::singleShot(duration, &loop, &QEventLoop::quit);
loop.exec();
}
void noop()
{}
/*!
* \brief Waits until the \a signal is emitted by \a sender when performing \a action and connects \a signal with \a handler if specified.
* \throws Fails if \a signal is not emitted in at least \a timeout milliseconds or when at least one of the required
* connections can not be established.
*/
template<typename Signal, typename Action, typename Handler = std::function<void(void)> >
void waitForSignal(typename QtPrivate::FunctionPointer<Signal>::Object *sender, Signal signal, Action action, int timeout = 2500, Handler handler = nullptr)
{
// determine name of the signal for error messages
const QByteArray signalName(QMetaMethod::fromSignal(signal).name());
// create loop and connect the signal to its quit slot
QEventLoop loop;
if(!QObject::connect(sender, signal, &loop, &QEventLoop::quit, Qt::DirectConnection)) {
CPPUNIT_FAIL(argsToString("Unable to connect signal ", signalName.data(), " for waiting"));
}
// if specified, also connect handler to signal
if(handler) {
if(!QObject::connect(sender, signal, sender, handler, Qt::DirectConnection)) {
CPPUNIT_FAIL(argsToString("Unable to connect signal ", signalName.data(), " to handler"));
}
}
// handle case when signal is directly emitted
bool signalDirectlyEmitted = false;
if(!QObject::connect(sender, signal, sender, [&signalDirectlyEmitted] {
signalDirectlyEmitted = true;
}, Qt::DirectConnection)) {
CPPUNIT_FAIL(argsToString("Unable to connect signal ", signalName.data(), " to check for direct emmitation"));
}
// perform specified action
action();
// no reason to enter event loop when signal has been emitted directly
if(signalDirectlyEmitted) {
return;
}
// also connect and start a timer if a timeout has been specified
QTimer timer;
if(timeout) {
QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit, Qt::DirectConnection);
timer.setSingleShot(true);
timer.setInterval(timeout);
timer.start();
}
// enter event loop
loop.exec();
// check whether a timeout occured
if(timeout && !timer.isActive()) {
CPPUNIT_FAIL(argsToString("Signal ", signalName.data(), " has not emmitted within at least ", timeout, " ms."));
}
}
/*!
* \brief Variant of waitForSignal() where sender is the connection and the action is a method of the connection.
*/
template<typename Signal, typename Action, typename Handler>
void ConnectionTests::waitForConnection(Signal signal, Action action, int timeout, Handler handler)
void ConnectionTests::waitForConnection(Signal signal, Action action, Handler handler, bool *ok, int timeout)
{
waitForSignal(&m_connection, signal, bind(action, &m_connection), timeout, handler);
}
/*!
* \brief Variant of waitForSignal() where sender is the connection and the action is a method of the connection.
* \brief Variant of waitForSignal() where sender is the connection.
*/
template<typename Signal, typename Handler>
void ConnectionTests::waitForConnection(Signal signal, int timeout, Handler handler)
template<typename Signal, typename Action, typename Handler>
void ConnectionTests::waitForConnectionAnyAction(Signal signal, Action action, Handler handler, bool *ok, int timeout)
{
waitForSignal(&m_connection, signal, noop, timeout, handler);
waitForSignal(&m_connection, signal, action, timeout, handler);
}
//
@ -242,41 +160,110 @@ void ConnectionTests::testConnection()
{
cerr << "\n - Connecting initially ..." << endl;
// error in case of wrong API key
m_connection.setAutoReconnectInterval(200);
// error in case of inavailability and wrong API key
m_connection.setApiKey(QByteArray("wrong API key"));
waitForConnection(&SyncthingConnection::error, static_cast<void(SyncthingConnection::*)(void)>(&SyncthingConnection::connect), 10000, [] (const QString &errorMessage) {
if(errorMessage != QStringLiteral("Unable to request Syncthing config: Connection refused")
&& errorMessage != QStringLiteral("Unable to request Syncthing status: Connection refused")) {
CPPUNIT_FAIL(argsToString("wrong error message in case of wrong API key: ", errorMessage.toLocal8Bit().data()));
}
});
bool syncthingAvailable = false;
const function<void(const QString &errorMessage)> errorHandler = [this, &syncthingAvailable] (const QString &errorMessage) {
if(errorMessage == QStringLiteral("Unable to request Syncthing config: Connection refused")
|| errorMessage == QStringLiteral("Unable to request Syncthing status: Connection refused")) {
return; // Syncthing not ready yet
}
syncthingAvailable = true;
if(errorMessage != QStringLiteral("Unable to request Syncthing config: Error transferring ") % m_connection.syncthingUrl() % QStringLiteral("/rest/system/config - server replied: Forbidden")
&& errorMessage != QStringLiteral("Unable to request Syncthing status: Error transferring ") % m_connection.syncthingUrl() % QStringLiteral("/rest/system/status - server replied: Forbidden")) {
CPPUNIT_FAIL(argsToString("wrong error message in case of wrong API key: ", errorMessage.toLocal8Bit().data()));
}
};
while(!syncthingAvailable) {
waitForConnection(&SyncthingConnection::error, static_cast<void(SyncthingConnection::*)(void)>(&SyncthingConnection::connect), errorHandler);
}
// initial connection
m_connection.setApiKey(m_apiKey.toUtf8());
waitForConnection(&SyncthingConnection::statusChanged, static_cast<void(SyncthingConnection::*)(void)>(&SyncthingConnection::connect), 10000);
waitForConnection(&SyncthingConnection::statusChanged, static_cast<void(SyncthingConnection::*)(void)>(&SyncthingConnection::connect));
CPPUNIT_ASSERT_EQUAL_MESSAGE("connected and paused (one dev is initially paused)", QStringLiteral("connected, paused"), m_connection.statusText());
// dirs present
const auto &dirInfo = m_connection.dirInfo();
CPPUNIT_ASSERT_EQUAL_MESSAGE("2 dirs present", 2ul, dirInfo.size());
CPPUNIT_ASSERT_EQUAL(QStringLiteral("test1"), dirInfo.front().id);
CPPUNIT_ASSERT_EQUAL(QStringLiteral("test2"), dirInfo.back().id);
// devs present
const auto &devInfo = m_connection.devInfo();
CPPUNIT_ASSERT_EQUAL_MESSAGE("3 devs present", 3ul, devInfo.size());
QString ownDevId;
for(const SyncthingDev &dev : devInfo) {
if(dev.id != QStringLiteral("MMGUI6U-WUEZQCP-XZZ6VYB-LCT4TVC-ER2HAVX-QYT6X7D-S6ZSG2B-323KLQ7") && dev.id != QStringLiteral("6EIS2PN-J2IHWGS-AXS3YUL-HC5FT3K-77ZXTLL-AKQLJ4C-7SWVPUS-AZW4RQ4")) {
CPPUNIT_ASSERT_EQUAL_MESSAGE("own device", QStringLiteral("own device"), dev.statusString());
ownDevId = dev.id;
}
}
for(const SyncthingDev &dev : devInfo) {
if(dev.id == QStringLiteral("MMGUI6U-WUEZQCP-XZZ6VYB-LCT4TVC-ER2HAVX-QYT6X7D-S6ZSG2B-323KLQ7")) {
CPPUNIT_ASSERT_EQUAL_MESSAGE("paused device", QStringLiteral("paused"), dev.statusString());
CPPUNIT_ASSERT_EQUAL_MESSAGE("name", QStringLiteral("Test dev 2"), dev.name);
CPPUNIT_ASSERT_MESSAGE("no introducer", !dev.introducer);
CPPUNIT_ASSERT_EQUAL(1, dev.addresses.size());
CPPUNIT_ASSERT_EQUAL(QStringLiteral("tcp://192.168.2.2:22000"), dev.addresses.front());
} else if(dev.id == QStringLiteral("6EIS2PN-J2IHWGS-AXS3YUL-HC5FT3K-77ZXTLL-AKQLJ4C-7SWVPUS-AZW4RQ4")) {
CPPUNIT_ASSERT_EQUAL_MESSAGE("disconnected device", QStringLiteral("disconnected"), dev.statusString());
CPPUNIT_ASSERT_EQUAL_MESSAGE("name", QStringLiteral("Test dev 1"), dev.name);
CPPUNIT_ASSERT_MESSAGE("introducer", dev.introducer);
CPPUNIT_ASSERT_EQUAL(1, dev.addresses.size());
CPPUNIT_ASSERT_EQUAL(QStringLiteral("dynamic"), dev.addresses.front());
}
}
// dirs present
const auto &dirInfo = m_connection.dirInfo();
CPPUNIT_ASSERT_EQUAL_MESSAGE("2 dirs present", 2ul, dirInfo.size());
const SyncthingDir &dir1 = dirInfo.front();
CPPUNIT_ASSERT_EQUAL(QStringLiteral("test1"), dir1.id);
CPPUNIT_ASSERT_EQUAL(QStringLiteral(""), dir1.label);
CPPUNIT_ASSERT_EQUAL(QStringLiteral("test1"), dir1.displayName());
CPPUNIT_ASSERT_EQUAL(QStringLiteral("/tmp/some/path/1/"), dir1.path);
CPPUNIT_ASSERT(!dir1.readOnly);
CPPUNIT_ASSERT(!dir1.paused);
CPPUNIT_ASSERT_EQUAL(dir1.devices, QStringList({QStringLiteral("MMGUI6U-WUEZQCP-XZZ6VYB-LCT4TVC-ER2HAVX-QYT6X7D-S6ZSG2B-323KLQ7"),
QStringLiteral("6EIS2PN-J2IHWGS-AXS3YUL-HC5FT3K-77ZXTLL-AKQLJ4C-7SWVPUS-AZW4RQ4"),
ownDevId}));
const SyncthingDir &dir2 = dirInfo.back();
CPPUNIT_ASSERT_EQUAL(QStringLiteral("test2"), dir2.id);
CPPUNIT_ASSERT_EQUAL(QStringLiteral("Test dir 2"), dir2.label);
CPPUNIT_ASSERT_EQUAL(QStringLiteral("Test dir 2"), dir2.displayName());
CPPUNIT_ASSERT_EQUAL(QStringLiteral("/tmp/some/path/2/"), dir2.path);
CPPUNIT_ASSERT(!dir2.readOnly);
CPPUNIT_ASSERT(dir2.paused);
CPPUNIT_ASSERT_EQUAL(dir2.devices, QStringList({QStringLiteral("MMGUI6U-WUEZQCP-XZZ6VYB-LCT4TVC-ER2HAVX-QYT6X7D-S6ZSG2B-323KLQ7"),
ownDevId}));
// reconnecting
cerr << "\n - Reconnecting ..." << endl;
waitForConnection(&SyncthingConnection::statusChanged, static_cast<void(SyncthingConnection::*)(void)>(&SyncthingConnection::reconnect), 1000);
waitForConnection(&SyncthingConnection::statusChanged, static_cast<void(SyncthingConnection::*)(void)>(&SyncthingConnection::reconnect));
CPPUNIT_ASSERT_EQUAL_MESSAGE("reconnecting", QStringLiteral("reconnecting"), m_connection.statusText());
waitForConnection(&SyncthingConnection::statusChanged, 1000);
waitForConnectionAnyAction(&SyncthingConnection::statusChanged, noop);
if(m_connection.isConnected() && m_connection.status() != SyncthingStatus::Paused) {
// FIXME: Maybe it takes one further update to recon paused dev?
waitForConnectionAnyAction(&SyncthingConnection::statusChanged, noop);
}
CPPUNIT_ASSERT_EQUAL_MESSAGE("connected again", QStringLiteral("connected, paused"), m_connection.statusText());
// resume all devs
bool devPaused = false;
waitForConnection(&SyncthingConnection::devStatusChanged, &SyncthingConnection::resumeAllDevs, static_cast<function<void(const SyncthingDev &, int)> >([&devPaused] (const SyncthingDev &dev, int) {
if(dev.name == QStringLiteral("Test dev 2") && !dev.paused) {
devPaused = true;
}
}), &devPaused);
CPPUNIT_ASSERT_EQUAL_MESSAGE("not paused anymore", QStringLiteral("connected"), m_connection.statusText());
// resume all dirs
bool dirPaused = false;
waitForConnection(&SyncthingConnection::dirStatusChanged, &SyncthingConnection::resumeAllDirs, static_cast<function<void(const SyncthingDir &, int)> >([&dirPaused] (const SyncthingDir &dir, int) {
if(dir.id == QStringLiteral("test2") && dir.paused) {
dirPaused = true;
}
}), &dirPaused);
CPPUNIT_ASSERT_EQUAL_MESSAGE("still 2 dirs present", 2ul, m_connection.dirInfo().size());
// disconnecting
cerr << "\n - Disconnecting ..." << endl;
waitForConnection(&SyncthingConnection::statusChanged, static_cast<void(SyncthingConnection::*)(void)>(&SyncthingConnection::disconnect), 5000);
waitForConnection(&SyncthingConnection::statusChanged, static_cast<void(SyncthingConnection::*)(void)>(&SyncthingConnection::disconnect));
CPPUNIT_ASSERT_EQUAL_MESSAGE("disconnected", QStringLiteral("disconnected"), m_connection.statusText());
}

128
connector/tests/helper.h Normal file
View File

@ -0,0 +1,128 @@
#ifndef TESTS_HELPER_H
#define TESTS_HELPER_H
#include <c++utilities/conversion/stringbuilder.h>
#include <cppunit/extensions/HelperMacros.h>
#include <QString>
#include <QEventLoop>
#include <QTimer>
#include <QMetaMethod>
#include <ostream>
#include <functional>
using namespace ConversionUtilities;
/*!
* \brief Prints a QString; required to use QString with CPPUNIT_ASSERT_EQUAL_MESSAGE.
*/
inline std::ostream &operator <<(std::ostream &o, const QString &qstring)
{
o << qstring.toLocal8Bit().data();
return o;
}
/*!
* \brief Prints a QString; required to use QStringList with CPPUNIT_ASSERT_EQUAL_MESSAGE.
*/
inline std::ostream &operator <<(std::ostream &o, const QStringList &qstringlist)
{
o << qstringlist.join(QStringLiteral(", ")).toLocal8Bit().data();
return o;
}
/*!
* \brief Waits for the in ms specified \a duration keeping the event loop running.
*/
inline void wait(int duration)
{
QEventLoop loop;
QTimer::singleShot(duration, &loop, &QEventLoop::quit);
loop.exec();
}
inline void noop()
{}
/*!
* \brief Waits until the \a signal is emitted by \a sender when performing \a action and connects \a signal with \a handler if specified.
* \arg sender Specifies the sender which is assumed to emit \a signal.
* \arg signal Specifies the signal.
* \arg action Specifies the action to be invoked when waiting.
* \arg timeout Specifies the max. time to wait.
* \arg handler Specifies a handler which will be also connected to \a signal.
* \arg ok Specifies whether the correct signal has been emitted. Should be set in \a handler to indicate that the emitted signal is actually the one
* the test is waiting for (and not just one which has been emitted as side-effect).
* \throws Fails if \a signal is not emitted in at least \a timeout milliseconds or when at least one of the required
* connections can not be established.
* \remarks The handler is disconnected before the function returns.
*/
template<typename Signal, typename Action, typename Handler = std::function<void(void)> >
void waitForSignal(typename QtPrivate::FunctionPointer<Signal>::Object *sender, Signal signal, Action action, int timeout = 2500, Handler handler = nullptr, bool *ok = nullptr)
{
// determine name of the signal for error messages
const QByteArray signalName(QMetaMethod::fromSignal(signal).name());
// use loop for waiting
QEventLoop loop;
// if specified, connect handler to signal
QMetaObject::Connection handlerConnection;
if(handler) {
handlerConnection = QObject::connect(sender, signal, sender, handler, Qt::DirectConnection);
if(!handlerConnection) {
CPPUNIT_FAIL(argsToString("Unable to connect signal ", signalName.data(), " to handler"));
}
}
// connect the signal to the quit slot of the loop
if(!QObject::connect(sender, signal, &loop, &QEventLoop::quit, Qt::DirectConnection)) {
CPPUNIT_FAIL(argsToString("Unable to connect signal ", signalName.data(), " for waiting"));
}
// handle case when signal is directly emitted
bool signalDirectlyEmitted = false;
if(!QObject::connect(sender, signal, sender, [&signalDirectlyEmitted] {
signalDirectlyEmitted = true;
}, Qt::DirectConnection)) {
CPPUNIT_FAIL(argsToString("Unable to connect signal ", signalName.data(), " to check for direct emmitation"));
}
// perform specified action
action();
// no reason to enter event loop when signal has been emitted directly
if((!ok || *ok) && signalDirectlyEmitted) {
QObject::disconnect(handlerConnection);
return;
}
// also connect and start a timer if a timeout has been specified
QTimer timer;
if(timeout) {
QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit, Qt::DirectConnection);
timer.setSingleShot(true);
timer.setInterval(timeout);
timer.start();
}
// exec event loop as long as the right signal has not been emitted yet and there is still time
if(!ok) {
loop.exec();
} else {
while(!*ok && (!timeout || timer.isActive())) {
loop.exec();
}
}
// check whether a timeout occured
if(timeout && !timer.isActive()) {
CPPUNIT_FAIL(argsToString("Signal ", signalName.data(), " has not emmitted within at least ", timeout, " ms."));
}
QObject::disconnect(handlerConnection);
}
#endif // TESTS_HELPER_H

View File

@ -0,0 +1,85 @@
#include "./helper.h"
#include "../syncthingconfig.h"
#include "../utils.h"
#include <c++utilities/tests/testutils.h>
#include <c++utilities/chrono/datetime.h>
#include <c++utilities/chrono/timespan.h>
#include <cppunit/TestFixture.h>
#include <QUrl>
using namespace std;
using namespace Data;
using namespace ChronoUtilities;
using namespace TestUtilities;
using namespace CPPUNIT_NS;
/*!
* \brief The MiscTests class tests various features of the connector library.
*/
class MiscTests : public TestFixture
{
CPPUNIT_TEST_SUITE(MiscTests);
CPPUNIT_TEST(testParsingConfig);
CPPUNIT_TEST(testUtils);
CPPUNIT_TEST_SUITE_END();
public:
MiscTests();
void testParsingConfig();
void testUtils();
void setUp();
void tearDown();
private:
};
CPPUNIT_TEST_SUITE_REGISTRATION(MiscTests);
MiscTests::MiscTests()
{}
//
// test setup
//
void MiscTests::setUp()
{}
void MiscTests::tearDown()
{}
//
// actual test
//
/*!
* \brief Tests basic behaviour of the SyncthingConnection class.
*/
void MiscTests::testParsingConfig()
{
SyncthingConfig config;
config.restore(QString::fromLocal8Bit(testFilePath("testconfig/config.xml").data()));
CPPUNIT_ASSERT_EQUAL_MESSAGE("address", QStringLiteral("127.0.0.1:4001"), config.guiAddress);
CPPUNIT_ASSERT_EQUAL_MESSAGE("API key", QStringLiteral("syncthingconnectortest"), config.guiApiKey);
CPPUNIT_ASSERT_MESSAGE("TLS", !config.guiEnforcesSecureConnection);
CPPUNIT_ASSERT_EQUAL_MESSAGE("url", QStringLiteral("http://127.0.0.1:4001"), config.syncthingUrl());
config.guiEnforcesSecureConnection = true;
CPPUNIT_ASSERT_EQUAL_MESSAGE("url", QStringLiteral("https://127.0.0.1:4001"), config.syncthingUrl());
}
void MiscTests::testUtils()
{
CPPUNIT_ASSERT_EQUAL(QStringLiteral("right now"), agoString(DateTime::now()));
CPPUNIT_ASSERT_EQUAL(QStringLiteral("5 h ago"), agoString(DateTime::now() - TimeSpan::fromHours(5.0)));
CPPUNIT_ASSERT(isLocal(QUrl(QStringLiteral("http://127.0.0.1"))));
CPPUNIT_ASSERT(isLocal(QUrl(QStringLiteral("http://[::1]"))));
CPPUNIT_ASSERT(isLocal(QUrl(QStringLiteral("http://localhost/"))));
CPPUNIT_ASSERT(!isLocal(QUrl(QStringLiteral("http://157.3.52.34"))));
}

View File

@ -20,142 +20,152 @@
</message>
<message>
<location filename="../syncthingconnection.cpp" line="109"/>
<source>connected, scanning</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="111"/>
<source>connected, paused</source>
<translation>verbunden, pausiert</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="111"/>
<location filename="../syncthingconnection.cpp" line="113"/>
<source>connected, synchronizing</source>
<translation>verbunden, am Synchronisieren</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="113"/>
<location filename="../syncthingconnection.cpp" line="115"/>
<source>connected, out of sync</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="117"/>
<source>unknown</source>
<translation>Verbindungsstatus unbekannt</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="140"/>
<location filename="../syncthingconnection.cpp" line="227"/>
<location filename="../syncthingconnection.cpp" line="144"/>
<location filename="../syncthingconnection.cpp" line="231"/>
<source>Connection configuration is insufficient.</source>
<translation>Verbindungskonfiguration is ungenügend</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="469"/>
<location filename="../syncthingconnection.cpp" line="473"/>
<source>Unable to pause/resume a directories when not connected</source>
<translation>Fehler beim Anfordern Gerät zu Pausieren/Fortzusetzen: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="726"/>
<location filename="../syncthingconnection.cpp" line="730"/>
<source>Unable to request QR-Code: </source>
<translation>Fehler beim Abfragen des QR-Codes: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="755"/>
<location filename="../syncthingconnection.cpp" line="759"/>
<source>Unable to parse Syncthing log: </source>
<translation>Fehler beim Auslesen des Syncthing-Logs: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="759"/>
<location filename="../syncthingconnection.cpp" line="763"/>
<source>Unable to request Syncthing log: </source>
<translation>Fehler beim Abfragen des Syncthing-Logs: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="793"/>
<location filename="../syncthingconnection.cpp" line="797"/>
<source>Unable to locate certificate used by Syncthing.</source>
<translation>Das SSL-Zertifikat von Syncthing kann nicht gefunden werden.</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="799"/>
<location filename="../syncthingconnection.cpp" line="803"/>
<source>Unable to load certificate used by Syncthing.</source>
<translation>Das SSL-Zertifikat von Syncthing kann nicht ausgelesen werden.</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="884"/>
<location filename="../syncthingconnection.cpp" line="888"/>
<source>Unable to parse Syncthing config: </source>
<translation>Fehler beim Auslesen der Syncthing-Konfiguration: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="890"/>
<location filename="../syncthingconnection.cpp" line="894"/>
<source>Unable to request Syncthing config: </source>
<translation>Fehler beim Abfragen der Syncthing-Konfiguration: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="992"/>
<location filename="../syncthingconnection.cpp" line="996"/>
<source>Unable to parse Syncthing status: </source>
<translation>Fehler beim Auslesen des Syncthing-Status: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="998"/>
<location filename="../syncthingconnection.cpp" line="1002"/>
<source>Unable to request Syncthing status: </source>
<translation>Fehler beim Abfragen des Syncthing-Status: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1077"/>
<location filename="../syncthingconnection.cpp" line="1081"/>
<source>Unable to parse connections: </source>
<translation>Fehler beim Auslesen der Verbindungen: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1083"/>
<location filename="../syncthingconnection.cpp" line="1087"/>
<source>Unable to request connections: </source>
<translation>Fehler beim Abfragen der Verbindungen: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1137"/>
<location filename="../syncthingconnection.cpp" line="1141"/>
<source>Unable to parse directory statistics: </source>
<translation>Fehler beim Auslesen der Verzeichnisstatistiken: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1143"/>
<location filename="../syncthingconnection.cpp" line="1147"/>
<source>Unable to request directory statistics: </source>
<translation>Fehler beim Abfragen der Verzeichnisstatistiken: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1179"/>
<location filename="../syncthingconnection.cpp" line="1183"/>
<source>Unable to parse device statistics: </source>
<translation>Fehler beim Auslesen der Gerätestatistiken: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1185"/>
<location filename="../syncthingconnection.cpp" line="1189"/>
<source>Unable to request device statistics: </source>
<translation>Fehler beim Abfragen der Gerätestatistiken: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1223"/>
<location filename="../syncthingconnection.cpp" line="1227"/>
<source>Unable to parse errors: </source>
<translation>Fehler beim Auslesen der Syncthing-Fehlermeldungen: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1234"/>
<location filename="../syncthingconnection.cpp" line="1238"/>
<source>Unable to request errors: </source>
<translation>Fehler beim Abfragen der Syncthing-Fehlermeldungen: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1250"/>
<location filename="../syncthingconnection.cpp" line="1254"/>
<source>Unable to request clearing errors: </source>
<translation>Fehler beim Löschen der Fehlermeldungen: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1303"/>
<location filename="../syncthingconnection.cpp" line="1307"/>
<source>Unable to parse Syncthing events: </source>
<translation>Fehler beim Auslesen der Syncthing-Ereignisse: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1325"/>
<location filename="../syncthingconnection.cpp" line="1329"/>
<source>Unable to request Syncthing events: </source>
<translation>Fehler beim Abfragen der Syncthing-Ereignisse: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1601"/>
<location filename="../syncthingconnection.cpp" line="1605"/>
<source>Unable to request rescan: </source>
<translation>Fehler beim Anfordern eines Verzeichnis-Rescans: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1621"/>
<location filename="../syncthingconnection.cpp" line="1625"/>
<source>Unable to request device pause/resume: </source>
<translation>Fehler beim Anfordern Gerät zu Pausieren/Fortzusetzen: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1638"/>
<location filename="../syncthingconnection.cpp" line="1642"/>
<source>Unable to request directory pause/resume: </source>
<translation>Fehler beim Anfordern Verzeichnis zu Pausieren/Fortzusetzen: </translation>
</message>
@ -164,12 +174,12 @@
<translation type="vanished">Fehler beim Anfordern Gerät zu Pausieren/Fortzusetzen: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1654"/>
<location filename="../syncthingconnection.cpp" line="1658"/>
<source>Unable to request restart: </source>
<translation>Fehler beim Anfordern eines Neustarts: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1670"/>
<location filename="../syncthingconnection.cpp" line="1674"/>
<source>Unable to request shutdown: </source>
<translation>Fehler beim Anfordern Syncthing zu beenden: </translation>
</message>

View File

@ -20,152 +20,162 @@
</message>
<message>
<location filename="../syncthingconnection.cpp" line="109"/>
<source>connected, paused</source>
<source>connected, scanning</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="111"/>
<source>connected, synchronizing</source>
<source>connected, paused</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="113"/>
<source>connected, synchronizing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="115"/>
<source>connected, out of sync</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="117"/>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="140"/>
<location filename="../syncthingconnection.cpp" line="227"/>
<location filename="../syncthingconnection.cpp" line="144"/>
<location filename="../syncthingconnection.cpp" line="231"/>
<source>Connection configuration is insufficient.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="469"/>
<location filename="../syncthingconnection.cpp" line="473"/>
<source>Unable to pause/resume a directories when not connected</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="726"/>
<location filename="../syncthingconnection.cpp" line="730"/>
<source>Unable to request QR-Code: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="755"/>
<location filename="../syncthingconnection.cpp" line="759"/>
<source>Unable to parse Syncthing log: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="759"/>
<location filename="../syncthingconnection.cpp" line="763"/>
<source>Unable to request Syncthing log: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="793"/>
<location filename="../syncthingconnection.cpp" line="797"/>
<source>Unable to locate certificate used by Syncthing.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="799"/>
<location filename="../syncthingconnection.cpp" line="803"/>
<source>Unable to load certificate used by Syncthing.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="884"/>
<location filename="../syncthingconnection.cpp" line="888"/>
<source>Unable to parse Syncthing config: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="890"/>
<location filename="../syncthingconnection.cpp" line="894"/>
<source>Unable to request Syncthing config: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="992"/>
<location filename="../syncthingconnection.cpp" line="996"/>
<source>Unable to parse Syncthing status: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="998"/>
<location filename="../syncthingconnection.cpp" line="1002"/>
<source>Unable to request Syncthing status: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1077"/>
<location filename="../syncthingconnection.cpp" line="1081"/>
<source>Unable to parse connections: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1083"/>
<location filename="../syncthingconnection.cpp" line="1087"/>
<source>Unable to request connections: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1137"/>
<location filename="../syncthingconnection.cpp" line="1141"/>
<source>Unable to parse directory statistics: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1143"/>
<location filename="../syncthingconnection.cpp" line="1147"/>
<source>Unable to request directory statistics: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1179"/>
<location filename="../syncthingconnection.cpp" line="1183"/>
<source>Unable to parse device statistics: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1185"/>
<location filename="../syncthingconnection.cpp" line="1189"/>
<source>Unable to request device statistics: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1223"/>
<location filename="../syncthingconnection.cpp" line="1227"/>
<source>Unable to parse errors: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1234"/>
<location filename="../syncthingconnection.cpp" line="1238"/>
<source>Unable to request errors: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1250"/>
<location filename="../syncthingconnection.cpp" line="1254"/>
<source>Unable to request clearing errors: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1303"/>
<location filename="../syncthingconnection.cpp" line="1307"/>
<source>Unable to parse Syncthing events: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1325"/>
<location filename="../syncthingconnection.cpp" line="1329"/>
<source>Unable to request Syncthing events: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1601"/>
<location filename="../syncthingconnection.cpp" line="1605"/>
<source>Unable to request rescan: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1621"/>
<location filename="../syncthingconnection.cpp" line="1625"/>
<source>Unable to request device pause/resume: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1638"/>
<location filename="../syncthingconnection.cpp" line="1642"/>
<source>Unable to request directory pause/resume: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1654"/>
<location filename="../syncthingconnection.cpp" line="1658"/>
<source>Unable to request restart: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1670"/>
<location filename="../syncthingconnection.cpp" line="1674"/>
<source>Unable to request shutdown: </source>
<translation type="unfinished"></translation>
</message>