From 037c5a309b8d6637416e0a93d01740cf0f3b3c3e Mon Sep 17 00:00:00 2001 From: Martchus Date: Sat, 29 Oct 2022 21:22:21 +0200 Subject: [PATCH] Fail tests early when Syncthing exists unexpectedly or cannot be started at all Before tests ran until a timeout was reached and failed not with a clear error message stating the root cause. This is now the case and can be tested by setting `SYNCTHING_PATH` to e.g. false/true or a non-existing binary. This may help with the test issue mentioned in https://github.com/Martchus/syncthingtray/issues/144 although I could never reproduce the concrete error message myself. --- testhelper/syncthingtestinstance.cpp | 33 ++++++++++++++++++++++++++++ testhelper/syncthingtestinstance.h | 5 +++++ 2 files changed, 38 insertions(+) diff --git a/testhelper/syncthingtestinstance.cpp b/testhelper/syncthingtestinstance.cpp index 585ef55..4f4f394 100644 --- a/testhelper/syncthingtestinstance.cpp +++ b/testhelper/syncthingtestinstance.cpp @@ -2,13 +2,18 @@ #include "./helper.h" #include +#include #include #include #include #include +#include +#include + using namespace std; +using namespace std::placeholders; namespace CppUtilities { @@ -19,7 +24,12 @@ SyncthingTestInstance::SyncthingTestInstance() : m_apiKey(QStringLiteral("syncthingtestinstance")) , m_app(dummy1, &dummy2) , m_interleavedOutput(false) + , m_processSupposedToRun(false) { + QObject::connect(&m_syncthingProcess, &Data::SyncthingProcess::errorOccurred, &m_syncthingProcess, + std::bind(&SyncthingTestInstance::handleError, this, _1), Qt::QueuedConnection); + QObject::connect(&m_syncthingProcess, &Data::SyncthingProcess::finished, &m_syncthingProcess, + std::bind(&SyncthingTestInstance::handleFinished, this, _1, _2), Qt::QueuedConnection); } /*! @@ -85,6 +95,7 @@ void SyncthingTestInstance::start() cerr << "\n - Launching Syncthing: " << syncthingPath.toStdString() << ' ' << args.join(QChar(' ')).toStdString() << endl; + m_processSupposedToRun = true; m_syncthingProcess.start(syncthingPath, args); // clang-format on } @@ -94,6 +105,7 @@ void SyncthingTestInstance::start() */ void SyncthingTestInstance::stop() { + m_processSupposedToRun = false; if (m_syncthingProcess.isRunning()) { cerr << "\n - Waiting for Syncthing to terminate ..." << endl; m_syncthingProcess.terminate(); @@ -135,4 +147,25 @@ void SyncthingTestInstance::setInterleavedOutputEnabledFromEnv() setInterleavedOutputEnabled(true); } } + +/*! + * \brief Throws an exception to abort testing when the process cannot be started. + */ +void SyncthingTestInstance::handleError(QProcess::ProcessError error) +{ + Q_UNUSED(error) + throw std::runtime_error(argsToString("Unable to start Syncthing ("sv, m_syncthingProcess.errorString().toStdString(), ')')); +} + +/*! + * \brief Throws an exception to abort testing when the process exists unexpectedly. + */ +void SyncthingTestInstance::handleFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + if (m_processSupposedToRun) { + throw std::runtime_error(argsToString("Syncthing exited unexpectedly ("sv, + exitStatus == QProcess::NormalExit ? "normal exit"sv : "exited with error"sv, ", exit code: "sv, exitCode, ')')); + } +} + } // namespace CppUtilities diff --git a/testhelper/syncthingtestinstance.h b/testhelper/syncthingtestinstance.h index 4e401ff..bb90364 100644 --- a/testhelper/syncthingtestinstance.h +++ b/testhelper/syncthingtestinstance.h @@ -34,12 +34,17 @@ public: void setInterleavedOutputEnabled(bool interleavedOutputEnabled); void setInterleavedOutputEnabledFromEnv(); +private: + void handleError(QProcess::ProcessError error); + void handleFinished(int exitCode, QProcess::ExitStatus exitStatus); + private: QString m_apiKey; QString m_syncthingPort; QCoreApplication m_app; Data::SyncthingProcess m_syncthingProcess; bool m_interleavedOutput; + bool m_processSupposedToRun; }; inline const QString &SyncthingTestInstance::apiKey() const