Move test helper to separate library
Allows to share common test helper code between tests for different components
This commit is contained in:
parent
9b70b81ae9
commit
40b8713ba6
|
@ -22,6 +22,7 @@ option(NO_MODEL "specifies whether building models should be skipped, implies NO
|
|||
|
||||
# add subdirectories
|
||||
enable_testing()
|
||||
add_subdirectory(testhelper)
|
||||
add_subdirectory(connector)
|
||||
link_directories(${LIB_SYNCTHING_CONNECTOR_BINARY_DIR})
|
||||
if(NOT NO_CLI)
|
||||
|
|
|
@ -31,7 +31,6 @@ set(SRC_FILES
|
|||
)
|
||||
|
||||
set(TEST_HEADER_FILES
|
||||
tests/helper.h
|
||||
)
|
||||
set(TEST_SRC_FILES
|
||||
tests/cppunit.cpp
|
||||
|
@ -55,6 +54,11 @@ find_package(qtutilities 5.0.0 REQUIRED)
|
|||
include_directories(BEFORE SYSTEM ${QT_UTILITIES_INCLUDE_DIRS})
|
||||
list(APPEND CMAKE_MODULE_PATH ${QT_UTILITIES_MODULE_DIRS})
|
||||
|
||||
# find test helper
|
||||
find_package(syncthingtesthelper ${META_APP_VERSION} REQUIRED)
|
||||
include_directories(BEFORE SYSTEM ${SYNCTHINGTESTHELPER_INCLUDE_DIRS})
|
||||
list(APPEND TEST_LIBRARIES ${SYNCTHINGTESTHELPER_LIB})
|
||||
|
||||
# link also explicitely against the following Qt 5 modules
|
||||
list(APPEND ADDITIONAL_QT_MODULES Network)
|
||||
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
#include "./helper.h"
|
||||
#include "../syncthingconnection.h"
|
||||
|
||||
#include "../testhelper/helper.h"
|
||||
#include "../testhelper/syncthingtestinstance.h"
|
||||
|
||||
#include <c++utilities/tests/testutils.h>
|
||||
|
||||
#include <cppunit/TestFixture.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QProcess>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QStringBuilder>
|
||||
|
||||
|
@ -20,7 +19,7 @@ using namespace CPPUNIT_NS;
|
|||
/*!
|
||||
* \brief The ConnectionTests class tests the SyncthingConnector.
|
||||
*/
|
||||
class ConnectionTests : public TestFixture
|
||||
class ConnectionTests : public TestFixture, private SyncthingTestInstance
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(ConnectionTests);
|
||||
CPPUNIT_TEST(testConnection);
|
||||
|
@ -44,20 +43,12 @@ private:
|
|||
template<typename Handler>
|
||||
QMetaObject::Connection handleNewDirs(Handler handler, bool *ok);
|
||||
|
||||
QString m_apiKey;
|
||||
QCoreApplication m_app;
|
||||
QProcess m_syncthingProcess;
|
||||
SyncthingConnection m_connection;
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(ConnectionTests);
|
||||
|
||||
static int dummy1 = 0;
|
||||
static char *dummy2;
|
||||
|
||||
ConnectionTests::ConnectionTests() :
|
||||
m_apiKey(QStringLiteral("syncthingconnectortest")),
|
||||
m_app(dummy1, &dummy2)
|
||||
ConnectionTests::ConnectionTests()
|
||||
{}
|
||||
|
||||
//
|
||||
|
@ -69,44 +60,10 @@ ConnectionTests::ConnectionTests() :
|
|||
*/
|
||||
void ConnectionTests::setUp()
|
||||
{
|
||||
cerr << "\n - Launching Syncthing and setup connection ..." << endl;
|
||||
SyncthingTestInstance::start();
|
||||
|
||||
// setup st config
|
||||
const string configFilePath = workingCopyPath("testconfig/config.xml");
|
||||
if(configFilePath.empty()) {
|
||||
throw runtime_error("Unable to setup Syncthing config directory.");
|
||||
}
|
||||
const QFileInfo configFile(QString::fromLocal8Bit(configFilePath.data()));
|
||||
// clean config dir
|
||||
const QDir configDir(configFile.dir());
|
||||
for(QFileInfo &configEntry : configDir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot)) {
|
||||
if(configEntry.isDir()) {
|
||||
QDir(configEntry.absoluteFilePath()).removeRecursively();
|
||||
} else if(configEntry.fileName() != QStringLiteral("config.xml")) {
|
||||
QFile::remove(configEntry.absoluteFilePath());
|
||||
}
|
||||
}
|
||||
|
||||
// determine st path
|
||||
const QByteArray syncthingPathFromEnv(qgetenv("SYNCTHING_PATH"));
|
||||
const QString syncthingPath(syncthingPathFromEnv.isEmpty() ? QStringLiteral("syncthing") : QString::fromLocal8Bit(syncthingPathFromEnv));
|
||||
|
||||
// determine st port
|
||||
const int syncthingPortFromEnv(qEnvironmentVariableIntValue("SYNCTHING_PORT"));
|
||||
const QString syncthingPort(!syncthingPortFromEnv ? QStringLiteral("4001") : QString::number(syncthingPortFromEnv));
|
||||
|
||||
// start st
|
||||
QStringList args;
|
||||
args.reserve(2);
|
||||
args << QStringLiteral("-gui-address=http://localhost:") + syncthingPort;
|
||||
args << QStringLiteral("-gui-apikey=") + m_apiKey;
|
||||
args << QStringLiteral("-home=") + configFile.absolutePath();
|
||||
args << QStringLiteral("-no-browser");
|
||||
args << QStringLiteral("-verbose");
|
||||
m_syncthingProcess.start(syncthingPath, args);
|
||||
|
||||
// setup connection
|
||||
m_connection.setSyncthingUrl(QStringLiteral("http://localhost:") + syncthingPort);
|
||||
cerr << "\n - Preparing connection ..." << endl;
|
||||
m_connection.setSyncthingUrl(QStringLiteral("http://localhost:") + syncthingPort());
|
||||
|
||||
// keep track of status changes
|
||||
QObject::connect(&m_connection, &SyncthingConnection::statusChanged, [this] {
|
||||
|
@ -119,16 +76,7 @@ void ConnectionTests::setUp()
|
|||
*/
|
||||
void ConnectionTests::tearDown()
|
||||
{
|
||||
if(m_syncthingProcess.state() == QProcess::Running) {
|
||||
cerr << "\n - Waiting for Syncthing to terminate ..." << endl;
|
||||
m_syncthingProcess.terminate();
|
||||
m_syncthingProcess.waitForFinished();
|
||||
}
|
||||
if(m_syncthingProcess.isOpen()) {
|
||||
cerr << "\n - Syncthing terminated with exit code " << m_syncthingProcess.exitCode() << ".\n";
|
||||
cerr << "\n - Syncthing stdout during the testrun:\n" << m_syncthingProcess.readAllStandardOutput().data();
|
||||
cerr << "\n - Syncthing stderr during the testrun:\n" << m_syncthingProcess.readAllStandardError().data();
|
||||
}
|
||||
SyncthingTestInstance::stop();
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -209,7 +157,7 @@ void ConnectionTests::testConnection()
|
|||
}
|
||||
|
||||
// initial connection
|
||||
m_connection.setApiKey(m_apiKey.toUtf8());
|
||||
m_connection.setApiKey(apiKey().toUtf8());
|
||||
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());
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include "./helper.h"
|
||||
#include "../syncthingconfig.h"
|
||||
#include "../utils.h"
|
||||
|
||||
#include "../testhelper/helper.h"
|
||||
|
||||
#include <c++utilities/tests/testutils.h>
|
||||
#include <c++utilities/chrono/datetime.h>
|
||||
#include <c++utilities/chrono/timespan.h>
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
|
||||
|
||||
# metadata
|
||||
set(META_PROJECT_NAME syncthingtesthelper)
|
||||
set(META_PROJECT_TYPE library)
|
||||
set(META_APP_NAME "Syncthing Tray Test Helper")
|
||||
set(META_APP_DESCRIPTION "Helper for testing compontents of Syncthing Tray")
|
||||
set(META_PUBLIC_QT_MODULES Core)
|
||||
set(META_NO_INSTALL_TARGETS ON)
|
||||
|
||||
# add project files
|
||||
set(HEADER_FILES
|
||||
helper.h
|
||||
syncthingtestinstance.h
|
||||
)
|
||||
set(SRC_FILES
|
||||
syncthingtestinstance.cpp
|
||||
)
|
||||
|
||||
set(TEST_HEADER_FILES
|
||||
)
|
||||
set(TEST_SRC_FILES
|
||||
)
|
||||
|
||||
set(TS_FILES
|
||||
)
|
||||
|
||||
# find c++utilities
|
||||
find_package(c++utilities 4.0.0 REQUIRED)
|
||||
use_cpp_utilities()
|
||||
set(META_PUBLIC_SHARED_LIB_DEPENDS c++utilities)
|
||||
set(META_PUBLIC_STATIC_LIB_DEPENDS c++utilities_static)
|
||||
|
||||
# find qtutilities (only headers and CMake modules used)
|
||||
find_package(qtutilities 5.0.0 REQUIRED)
|
||||
include_directories(BEFORE SYSTEM ${QT_UTILITIES_INCLUDE_DIRS})
|
||||
list(APPEND CMAKE_MODULE_PATH ${QT_UTILITIES_MODULE_DIRS})
|
||||
|
||||
# link also explicitely against the following Qt 5 modules
|
||||
list(APPEND ADDITIONAL_QT_MODULES Network)
|
||||
|
||||
# include modules to apply configuration
|
||||
include(BasicConfig)
|
||||
include(QtConfig)
|
||||
include(WindowsResources)
|
||||
include(LibraryTarget)
|
||||
include(Doxygen)
|
||||
include(ConfigHeader)
|
||||
|
||||
# exclude the targets from 'all' target so it is only built when tests are built
|
||||
foreach(TESTHELPER_TARGET "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}" "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static")
|
||||
if(TARGET "${TESTHELPER_TARGET}")
|
||||
set_target_properties("${TESTHELPER_TARGET}" PROPERTIES EXCLUDE_FROM_ALL ON)
|
||||
endif()
|
||||
endforeach()
|
|
@ -0,0 +1,27 @@
|
|||
// Created via CMake from template global.h.in
|
||||
// WARNING! Any changes to this file will be overwritten by the next CMake run!
|
||||
|
||||
#ifndef SYNCTHINGTESTHELPER_GLOBAL
|
||||
#define SYNCTHINGTESTHELPER_GLOBAL
|
||||
|
||||
#include <c++utilities/application/global.h>
|
||||
|
||||
#ifdef SYNCTHINGTESTHELPER_STATIC
|
||||
# define SYNCTHINGTESTHELPER_EXPORT
|
||||
# define SYNCTHINGTESTHELPER_IMPORT
|
||||
#else
|
||||
# define SYNCTHINGTESTHELPER_EXPORT LIB_EXPORT
|
||||
# define SYNCTHINGTESTHELPER_IMPORT LIB_IMPORT
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \def SYNCTHINGTESTHELPER_EXPORT
|
||||
* \brief Marks the symbol to be exported by the syncthingtesthelper library.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \def SYNCTHINGTESTHELPER_IMPORT
|
||||
* \brief Marks the symbol to be imported from the syncthingtesthelper library.
|
||||
*/
|
||||
|
||||
#endif // SYNCTHINGTESTHELPER_GLOBAL
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef TESTS_HELPER_H
|
||||
#define TESTS_HELPER_H
|
||||
#ifndef SYNCTHINGTESTHELPER_H
|
||||
#define SYNCTHINGTESTHELPER_H
|
||||
|
||||
#include <c++utilities/conversion/stringbuilder.h>
|
||||
|
||||
|
@ -138,4 +138,4 @@ void waitForSignal(typename QtPrivate::FunctionPointer<Signal>::Object *sender,
|
|||
QObject::disconnect(handlerConnection);
|
||||
}
|
||||
|
||||
#endif // TESTS_HELPER_H
|
||||
#endif // SYNCTHINGTESTHELPER_H
|
|
@ -0,0 +1,77 @@
|
|||
#include "./syncthingtestinstance.h"
|
||||
#include "./helper.h"
|
||||
|
||||
#include <c++utilities/tests/testutils.h>
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
|
||||
using namespace std;
|
||||
using namespace TestUtilities;
|
||||
|
||||
static int dummy1 = 0;
|
||||
static char *dummy2;
|
||||
|
||||
SyncthingTestInstance::SyncthingTestInstance() :
|
||||
m_apiKey(QStringLiteral("syncthingtestinstance")),
|
||||
m_app(dummy1, &dummy2)
|
||||
{}
|
||||
|
||||
/*!
|
||||
* \brief Starts the Syncthing test instance.
|
||||
*/
|
||||
void SyncthingTestInstance::start()
|
||||
{
|
||||
cerr << "\n - Launching Syncthing ..." << endl;
|
||||
|
||||
// setup st config
|
||||
const string configFilePath = workingCopyPath("testconfig/config.xml");
|
||||
if(configFilePath.empty()) {
|
||||
throw runtime_error("Unable to setup Syncthing config directory.");
|
||||
}
|
||||
const QFileInfo configFile(QString::fromLocal8Bit(configFilePath.data()));
|
||||
// clean config dir
|
||||
const QDir configDir(configFile.dir());
|
||||
for(QFileInfo &configEntry : configDir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot)) {
|
||||
if(configEntry.isDir()) {
|
||||
QDir(configEntry.absoluteFilePath()).removeRecursively();
|
||||
} else if(configEntry.fileName() != QStringLiteral("config.xml")) {
|
||||
QFile::remove(configEntry.absoluteFilePath());
|
||||
}
|
||||
}
|
||||
|
||||
// determine st path
|
||||
const QByteArray syncthingPathFromEnv(qgetenv("SYNCTHING_PATH"));
|
||||
const QString syncthingPath(syncthingPathFromEnv.isEmpty() ? QStringLiteral("syncthing") : QString::fromLocal8Bit(syncthingPathFromEnv));
|
||||
|
||||
// determine st port
|
||||
const int syncthingPortFromEnv(qEnvironmentVariableIntValue("SYNCTHING_PORT"));
|
||||
m_syncthingPort = !syncthingPortFromEnv ? QStringLiteral("4001") : QString::number(syncthingPortFromEnv);
|
||||
|
||||
// start st
|
||||
QStringList args;
|
||||
args.reserve(2);
|
||||
args << QStringLiteral("-gui-address=http://localhost:") + m_syncthingPort;
|
||||
args << QStringLiteral("-gui-apikey=") + m_apiKey;
|
||||
args << QStringLiteral("-home=") + configFile.absolutePath();
|
||||
args << QStringLiteral("-no-browser");
|
||||
args << QStringLiteral("-verbose");
|
||||
m_syncthingProcess.start(syncthingPath, args);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Terminates Syncthing and prints stdout/stderr from Syncthing.
|
||||
*/
|
||||
void SyncthingTestInstance::stop()
|
||||
{
|
||||
if(m_syncthingProcess.state() == QProcess::Running) {
|
||||
cerr << "\n - Waiting for Syncthing to terminate ..." << endl;
|
||||
m_syncthingProcess.terminate();
|
||||
m_syncthingProcess.waitForFinished();
|
||||
}
|
||||
if(m_syncthingProcess.isOpen()) {
|
||||
cerr << "\n - Syncthing terminated with exit code " << m_syncthingProcess.exitCode() << ".\n";
|
||||
cerr << "\n - Syncthing stdout during the testrun:\n" << m_syncthingProcess.readAllStandardOutput().data();
|
||||
cerr << "\n - Syncthing stderr during the testrun:\n" << m_syncthingProcess.readAllStandardError().data();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef SYNCTHINGTESTHELPER_SYNCTHINGTESTINSTANCE_H
|
||||
#define SYNCTHINGTESTHELPER_SYNCTHINGTESTINSTANCE_H
|
||||
|
||||
#include "./global.h"
|
||||
#include "./helper.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QProcess>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*!
|
||||
* \brief The SyncthingTestInstance class provides running a test instance of Syncthing.
|
||||
*
|
||||
* The class is meant to be subclassed by tests requiring a running Syncthing instance.
|
||||
*/
|
||||
class SYNCTHINGTESTHELPER_EXPORT SyncthingTestInstance
|
||||
{
|
||||
public:
|
||||
SyncthingTestInstance();
|
||||
|
||||
const QString &apiKey() const;
|
||||
const QString &syncthingPort() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
protected:
|
||||
QCoreApplication &application();
|
||||
QProcess &syncthingProcess();
|
||||
|
||||
private:
|
||||
QString m_apiKey;
|
||||
QString m_syncthingPort;
|
||||
QCoreApplication m_app;
|
||||
QProcess m_syncthingProcess;
|
||||
};
|
||||
|
||||
inline const QString &SyncthingTestInstance::apiKey() const
|
||||
{
|
||||
return m_apiKey;
|
||||
}
|
||||
|
||||
inline const QString &SyncthingTestInstance::syncthingPort() const
|
||||
{
|
||||
return m_syncthingPort;
|
||||
}
|
||||
|
||||
inline QCoreApplication &SyncthingTestInstance::application()
|
||||
{
|
||||
return m_app;
|
||||
}
|
||||
|
||||
inline QProcess &SyncthingTestInstance::syncthingProcess()
|
||||
{
|
||||
return m_syncthingProcess;
|
||||
}
|
||||
|
||||
#endif // SYNCTHINGTESTHELPER_SYNCTHINGTESTINSTANCE_H
|
Loading…
Reference in New Issue