loolwsd/Unit.cpp | 45 +++++++++++++++++++++++++-------- loolwsd/Unit.hpp | 11 +++++++- loolwsd/test/Makefile.am | 6 ++-- loolwsd/test/UnitTimeout.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++ loolwsd/test/run_unit.sh | 2 - 5 files changed, 108 insertions(+), 14 deletions(-)
New commits: commit 3e618a97e3cf04fee09f3fe28f5afe9605e74017 Author: Michael Meeks <[email protected]> Date: Fri Apr 8 17:36:08 2016 +0100 Tests: add timeout, and test for timeout. diff --git a/loolwsd/Unit.cpp b/loolwsd/Unit.cpp index 2a9448c..abafa12 100644 --- a/loolwsd/Unit.cpp +++ b/loolwsd/Unit.cpp @@ -13,11 +13,13 @@ #include "Util.hpp" #include "Unit.hpp" +#include <Poco/Thread.h> #include <Poco/Util/Application.h> -using Poco::Util::Application; UnitHooks *UnitHooks::_global = nullptr; +static Poco::Thread TimeoutThread("unit timeout"); + UnitHooks *UnitHooks::linkAndCreateUnit(const std::string &unitLibPath) { void *dlHandle = dlopen(unitLibPath.c_str(), RTLD_GLOBAL|RTLD_NOW); @@ -45,15 +47,33 @@ UnitHooks *UnitHooks::linkAndCreateUnit(const std::string &unitLibPath) bool UnitHooks::init(const std::string &unitLibPath) { if (!unitLibPath.empty()) + { _global = linkAndCreateUnit(unitLibPath); + TimeoutThread.startFunc([](){ + TimeoutThread.trySleep(_global->_timeoutMilliSeconds); + if (!_global->_timeoutShutdown) + { + Log::error("Timeout"); + _global->timeout(); + } + }); + } else _global = new UnitHooks(); return _global != NULL; } +void UnitHooks::setTimeout(int timeoutMilliSeconds) +{ + assert(!TimeoutThread.isRunning()); + _timeoutMilliSeconds = timeoutMilliSeconds; +} + UnitHooks::UnitHooks() - : _dlHandle(NULL) + : _dlHandle(NULL), + _timeoutMilliSeconds(30 * 1000), + _timeoutShutdown(false) { } @@ -69,22 +89,27 @@ void UnitHooks::exitTest(TestResult result) { _setRetValue = true; _retValue = result == TestResult::TEST_OK ? - Application::EXIT_OK : Application::EXIT_SOFTWARE; + Poco::Util::Application::EXIT_OK : + Poco::Util::Application::EXIT_SOFTWARE; TerminationFlag = true; } -/// Tweak the return value from LOOLWSD. +void UnitHooks::timeout() +{ + exitTest(TestResult::TEST_TIMED_OUT); +} + void UnitHooks::returnValue(int &retValue) { if (_setRetValue) retValue = _retValue; -} -// FIXME: trigger the timeout. -void UnitHooks::timeout() -{ - Log::error("Test timed out - failing."); - exitTest(TestResult::TEST_TIMED_OUT); + _timeoutShutdown = true; + TimeoutThread.wakeUp(); + TimeoutThread.join(); + + delete _global; + _global = nullptr; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/loolwsd/Unit.hpp b/loolwsd/Unit.hpp index a2d4f0d..0a16d34 100644 --- a/loolwsd/Unit.hpp +++ b/loolwsd/Unit.hpp @@ -11,8 +11,10 @@ #include <string> #include <memory> +#include <atomic> class UnitHooks; +class UnitTimeout; class UnitHTTPServerRequest; class UnitHTTPServerResponse; @@ -25,9 +27,13 @@ extern "C" { UnitHooks *unit_create(void); } /// Derive your unit test / hooks from me. class UnitHooks { + friend UnitTimeout; + void *_dlHandle; bool _setRetValue; int _retValue; + int _timeoutMilliSeconds; + std::atomic<bool> _timeoutShutdown; static UnitHooks *_global; void setHandle(void *dlHandle) { _dlHandle = dlHandle; } @@ -36,6 +42,9 @@ protected: // ---------------- Helper API ---------------- + /// After this time we invoke 'timeout' default 30 seconds + void setTimeout(int timeoutMilliSeconds); + enum TestResult { TEST_FAILED, TEST_OK, TEST_TIMED_OUT }; /// Encourages loolwsd to exit with this value (unless hooked) void exitTest(TestResult result); @@ -63,7 +72,7 @@ public: virtual void returnValue(int & /* retValue */); /// When a new child kit process reports virtual void newChild() {} - /// If the test times out this gets invoked + /// If the test times out this gets invoked, default exits. virtual void timeout(); /// Intercept createStorage virtual bool createStorage(const std::string& /* jailRoot */, diff --git a/loolwsd/test/Makefile.am b/loolwsd/test/Makefile.am index 03f3718..f0a9c21 100644 --- a/loolwsd/test/Makefile.am +++ b/loolwsd/test/Makefile.am @@ -11,7 +11,7 @@ check_PROGRAMS = test AM_CXXFLAGS = $(CPPUNIT_CFLAGS) -lib_LTLIBRARIES = unit-prefork.la unit-storage.la +lib_LTLIBRARIES = unit-timeout.la unit-prefork.la unit-storage.la AM_CPPFLAGS = -pthread -I$(top_srcdir) @@ -22,6 +22,8 @@ test_LDADD = $(CPPUNIT_LIBS) test_SOURCES = httpposttest.cpp httpwstest.cpp test.cpp ../LOOLProtocol.cpp # unit test modules: +unit_timeout_la_SOURCES = UnitTimeout.cpp +unit_timeout_la_LDFLAGS = -module unit_prefork_la_SOURCES = UnitPrefork.cpp unit_prefork_la_LDFLAGS = -module unit_storage_la_SOURCES = UnitStorage.cpp @@ -39,7 +41,7 @@ ${top_builddir}/test/run_unit.sh.log ${top_builddir}/test/run_unit.sh.trs : \ ${top_srcdir}/test/run_unit.sh \ ${top_builddir}/loolwsd \ ${top_builddir}/loolforkit \ - unit-prefork.la unit-storage.la + unit-timeout.la unit-prefork.la unit-storage.la if ${top_srcdir}/test/run_unit.sh; then \ touch ${top_builddir}/test/run_unit.sh.log; \ fi diff --git a/loolwsd/test/UnitTimeout.cpp b/loolwsd/test/UnitTimeout.cpp new file mode 100644 index 0000000..7c400b5 --- /dev/null +++ b/loolwsd/test/UnitTimeout.cpp @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <dlfcn.h> +#include <ftw.h> +#include <cassert> +#include <iostream> + +#include "Util.hpp" +#include "Unit.hpp" + +#include <Poco/Timestamp.h> +#include <Poco/Util/Application.h> +using Poco::Timestamp; + +class UnitTimeout : public UnitHooks +{ + std::atomic<bool> _timedOut; +public: + UnitTimeout() + : _timedOut(false) + { + setTimeout(10); + } + virtual void timeout() override + { + _timedOut = true; + UnitHooks::timeout(); + } + virtual void returnValue(int & retValue) override + { + if (!_timedOut) + { + Log::info("Failed to timeout"); + retValue = Poco::Util::Application::EXIT_SOFTWARE; + } + else + { + assert(_setRetValue); + assert(_retValue == Poco::Util::Application::EXIT_SOFTWARE); + // we wanted a timeout. + retValue = Poco::Util::Application::EXIT_OK; + } + } +}; + +UnitHooks *unit_create(void) +{ + return new UnitTimeout(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/loolwsd/test/run_unit.sh b/loolwsd/test/run_unit.sh index 22f7363..a86fb70 100755 --- a/loolwsd/test/run_unit.sh +++ b/loolwsd/test/run_unit.sh @@ -7,7 +7,7 @@ mkdir -p test_output # result logging echo > run_unit.sh.trs -for tst in storage prefork; do +for tst in timeout storage prefork; do tst_log="test_output/$tst.log" echo "Running test: $tst | $tst_log ..."; if ../loolwsd --systemplate=${systemplate} --lotemplate="${LO_PATH}" --childroot="${jails}" --unitlib=".libs/unit-$tst.so" 2> "$tst_log"; then _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
