Extend tests of connector library
This commit is contained in:
parent
a3887749a5
commit
0868f2cf6a
|
@ -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})
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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"))));
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue