loleaflet/.gitignore | 1 loolwsd/.gitignore | 44 +++++++++++--------- loolwsd/LOOLKit.hpp | 1 loolwsd/LOOLWSD.cpp | 31 ++++++++++++-- loolwsd/Makefile.am | 4 + loolwsd/Unit.cpp | 90 ++++++++++++++++++++++++++++++++++++++++++ loolwsd/Unit.hpp | 53 +++++++++++++++++++++++++ loolwsd/Util.cpp | 91 ++++++++++++++++++++++++++++++++----------- loolwsd/configure.ac | 37 +++++++++++++++++ loolwsd/test/.gitignore | 10 ++-- loolwsd/test/Makefile.am | 50 ++++++++++++++++++++++- loolwsd/test/UnitPrefork.cpp | 45 +++++++++++++++++++++ loolwsd/test/run_unit.sh | 25 +++++++++++ 13 files changed, 430 insertions(+), 52 deletions(-)
New commits: commit cd47b5e044893994a534c7b94b3fa11b87cfaeca Author: Michael Meeks <[email protected]> Date: Thu Apr 7 17:43:26 2016 +0100 Signal safe signal handlers. diff --git a/loolwsd/Util.cpp b/loolwsd/Util.cpp index 2d73562..678b1d7 100644 --- a/loolwsd/Util.cpp +++ b/loolwsd/Util.cpp @@ -18,6 +18,7 @@ #include <random> #include <sstream> #include <string> +#include <unistd.h> #include <png.h> @@ -89,6 +90,8 @@ namespace rng } } +static char LogPrefix[256] = { '\0' }; + namespace Log { static const Poco::Int64 epochStart = Poco::Timestamp().epochMicroseconds(); @@ -135,7 +138,6 @@ namespace Log return stream.str(); } - void initialize(const std::string& name) { Source.name = name; @@ -143,6 +145,8 @@ namespace Log oss << Source.name << '-' << std::setw(5) << std::setfill('0') << Poco::Process::id(); Source.id = oss.str(); + assert (sizeof (LogPrefix) > strlen(oss.str().c_str()) + 1); + strcpy(LogPrefix, oss.str().c_str()); auto channel = (isatty(fileno(stdout)) || std::getenv("LOOL_LOGCOLOR") ? static_cast<Poco::Channel*>(new Poco::ColorConsoleChannel()) @@ -356,19 +360,38 @@ namespace Util } } + // We need a signal safe means of writing messages + // $ man 7 signal + static + void log_signal(const char *message) + { + while (true) { + int length = strlen(message); + int written = write (STDERR_FILENO, message, length); + if (written < 0) + { + if (errno == EINTR) + continue; // ignore. + else + break; + } + message += written; + if (message[0] == '\0') + break; + } + } + static void handleTerminationSignal(const int signal) { if (!TerminationFlag) { - // Poco::Log takes a lock that isn't recursive. - // If we are signaled while having that lock, - // logging again will deadlock on it. TerminationFlag = true; - Log::info() << "Termination signal received: " - << Util::signalName(signal) << " " - << strsignal(signal) << Log::end; + log_signal(LogPrefix); + log_signal(" Termination signal received: "); + log_signal(strsignal(signal)); + log_signal("\n"); } } @@ -386,19 +409,19 @@ namespace Util sigaction(SIGHUP, &action, nullptr); } + static char FatalGdbString[256] = { '\0' }; + static void handleFatalSignal(const int signal) { - Log::error() << "Fatal signal received: " - << Util::signalName(signal) << " " - << strsignal(signal) << Log::end; + log_signal(LogPrefix); + log_signal(" Fatal signal received: "); + log_signal(strsignal(signal)); + log_signal("\n"); if (std::getenv("LOOL_DEBUG")) { - Log::error() << "\nFatal signal! Attach debugger with:\n" - << "sudo gdb --pid=" << Poco::Process::id() << "\n or \n" - << "sudo gdb --q --n --ex 'thread apply all backtrace full' --batch --pid=" - << Poco::Process::id() << "\n" << Log::end; + log_signal(FatalGdbString); sleep(30); } @@ -426,6 +449,16 @@ namespace Util sigaction(SIGABRT, &action, NULL); sigaction(SIGILL, &action, NULL); sigaction(SIGFPE, &action, NULL); + + // prepare this in advance just in case. + std::ostringstream stream; + stream << "\nFatal signal! Attach debugger with:\n" + << "sudo gdb --pid=" << Poco::Process::id() << "\n or \n" + << "sudo gdb --q --n --ex 'thread apply all backtrace full' --batch --pid=" + << Poco::Process::id() << "\n"; + std::string streamStr = stream.str(); + assert (sizeof (FatalGdbString) > strlen(streamStr.c_str()) + 1); + strcpy(FatalGdbString, streamStr.c_str()); } int getChildStatus(const int code) commit a454a3c407825cf5abe150f59765733b79c051df Author: Michael Meeks <[email protected]> Date: Wed Apr 6 19:50:55 2016 +0100 Improve test API, and handle failure better. diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index 95ab3e5..3c497db 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -164,9 +164,9 @@ void forkChildren(int number) void preForkChildren() { std::unique_lock<std::mutex> lock(newChildrenMutex); - int nPreSpawn = LOOLWSD::NumPreSpawnedChildren; - UnitHooks::get().preSpawnCount(nPreSpawn); - forkChildren(nPreSpawn); + int numPreSpawn = LOOLWSD::NumPreSpawnedChildren; + UnitHooks::get().preSpawnCount(numPreSpawn); + forkChildren(numPreSpawn); } std::shared_ptr<ChildProcess> getNewChild() @@ -662,6 +662,7 @@ public: newChildren.emplace_back(std::make_shared<ChildProcess>(pid, ws)); Log::info("Have " + std::to_string(newChildren.size()) + " children."); newChildrenCV.notify_one(); + UnitHooks::get().newChild(); return; } @@ -1543,8 +1544,12 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/) Poco::Net::uninitializeSSL(); Poco::Crypto::uninitializeCrypto(); - Log::info("Process finished."); - return Application::EXIT_OK; + Log::info("Process [loolwsd] finished."); + + int returnValue = Application::EXIT_OK; + UnitHooks::get().returnValue(returnValue); + + return returnValue; } POCO_SERVER_MAIN(LOOLWSD) diff --git a/loolwsd/Unit.cpp b/loolwsd/Unit.cpp index 82718ce..2a9448c 100644 --- a/loolwsd/Unit.cpp +++ b/loolwsd/Unit.cpp @@ -13,6 +13,9 @@ #include "Util.hpp" #include "Unit.hpp" +#include <Poco/Util/Application.h> +using Poco::Util::Application; + UnitHooks *UnitHooks::_global = nullptr; UnitHooks *UnitHooks::linkAndCreateUnit(const std::string &unitLibPath) @@ -56,9 +59,32 @@ UnitHooks::UnitHooks() UnitHooks::~UnitHooks() { - if (_dlHandle) - dlclose(_dlHandle); +// FIXME: we should really clean-up properly. +// if (_dlHandle) +// dlclose(_dlHandle); _dlHandle = NULL; } +void UnitHooks::exitTest(TestResult result) +{ + _setRetValue = true; + _retValue = result == TestResult::TEST_OK ? + Application::EXIT_OK : Application::EXIT_SOFTWARE; + TerminationFlag = true; +} + +/// Tweak the return value from LOOLWSD. +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); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/loolwsd/Unit.hpp b/loolwsd/Unit.hpp index 36c6af6..dc53d9f 100644 --- a/loolwsd/Unit.hpp +++ b/loolwsd/Unit.hpp @@ -21,10 +21,16 @@ extern "C" { UnitHooks *unit_create(void); } class UnitHooks { void *_dlHandle; + bool _setRetValue; + int _retValue; static UnitHooks *_global; void setHandle(void *dlHandle) { _dlHandle = dlHandle; } static UnitHooks *linkAndCreateUnit(const std::string &unitLibPath); +protected: + enum TestResult { TEST_FAILED, TEST_OK, TEST_TIMED_OUT }; + /// Encourages loolwsd to exit with this value (unless hooked) + void exitTest(TestResult result); public: UnitHooks(); virtual ~UnitHooks(); @@ -32,7 +38,14 @@ public: /// Load unit test hook shared library from this path static bool init(const std::string &unitLibPath); + /// Tweak the count of pre-spawned kits. virtual void preSpawnCount(int & /* numPrefork */) {} + /// Tweak the return value from LOOLWSD. + virtual void returnValue(int & /* retValue */); + /// When a new child kit process reports + virtual void newChild() {} + /// If the test times out + virtual void timeout(); }; #endif // LOOL_UNIT_HPP diff --git a/loolwsd/test/Makefile.am b/loolwsd/test/Makefile.am index 412606c..d7a17a3 100644 --- a/loolwsd/test/Makefile.am +++ b/loolwsd/test/Makefile.am @@ -1,3 +1,12 @@ +# variables for tests +jails=${top_builddir}/test/jails +systemplate=${top_builddir}/test/systemplate +export jails +export systemplate +export LO_PATH + +AUTOMAKE_OPTION = serial-tests + check_PROGRAMS = test AM_CXXFLAGS = $(CPPUNIT_CFLAGS) @@ -17,11 +26,6 @@ unit_prefork_la_SOURCES = \ UnitPrefork.cpp unit_prefork_la_LDFLAGS = -module -jails=${top_builddir}/test/jails -systemplate=${top_builddir}/test/systemplate -export jails -export systemplate - ${systemplate}/system_stamp : rm -rf ${systemplate} ${top_srcdir}/loolwsd-systemplate-setup ${systemplate} ${LO_PATH} && touch ${systemplate}/system_stamp @@ -29,17 +33,25 @@ ${systemplate}/system_stamp : ${jails} : mkdir -p ${jails} -run_tests : ${systemplate}/system_stamp ${jails} - ${top_srcdir}/test/run_unit.sh "${LO_PATH}" +${top_builddir}/test/run_unit.sh.log ${top_builddir}/test/run_unit.sh.trs : \ + ${systemplate}/system_stamp ${jails} \ + ${top_srcdir}/test/run_unit.sh \ + ${top_builddir}/loolwsd \ + ${top_builddir}/loolforkit \ + unit-prefork.la + if ${top_srcdir}/test/run_unit.sh; then \ + touch ${top_builddir}/test/run_unit.sh.log; \ + fi if HAVE_LO_PATH -TESTS = run_tests $(top_builddir)/test/test +TESTS = ${top_builddir}/test/run_unit.sh ${top_builddir}/test/test clean-local: rm -rf ${top_builddir}/test/jails rm -rf ${systemplate} + rm -f ${top_builddir}/test/unit_stamp; else -TESTS = $(top_builddir)/test/test +TESTS = ${top_builddir}/test/test endif EXTRA_DIST = data/hello.odt data/hello.txt $(test_SOURCES) run_unit.sh diff --git a/loolwsd/test/UnitPrefork.cpp b/loolwsd/test/UnitPrefork.cpp index 3d93d4d..6bca7b9 100644 --- a/loolwsd/test/UnitPrefork.cpp +++ b/loolwsd/test/UnitPrefork.cpp @@ -13,16 +13,28 @@ #include "Util.hpp" #include "Unit.hpp" -class UnitPrefork : public UnitHooks { +class UnitPrefork : public UnitHooks +{ + int _numStarted; + const int _numToPrefork; public: UnitPrefork() + : _numStarted(0), + _numToPrefork(20) { } - virtual void preSpawnCount(int &numPrefork) + virtual void preSpawnCount(int &numPrefork) override { - numPrefork = 20; + numPrefork = _numToPrefork; Log::error("Hello world"); } + + virtual void newChild() override + { + _numStarted++; + if (_numStarted >= _numToPrefork + 1) + exitTest(TestResult::TEST_OK); + } }; UnitHooks *unit_create(void) diff --git a/loolwsd/test/run_unit.sh b/loolwsd/test/run_unit.sh index d8ec7f8..8f2a79a 100755 --- a/loolwsd/test/run_unit.sh +++ b/loolwsd/test/run_unit.sh @@ -2,11 +2,24 @@ export LOOL_LOGLEVEL=trace -for test in prefork; do - echo "Running test: $test"; - if ../loolwsd --systemplate=${systemplate} --lotemplate="$1" --childroot="${jails}" --unitlib=".libs/unit-$test.so" >& "${jails}/$test.log"; then +mkdir -p test_output + +# result logging +echo > run_unit.sh.trs + +for tst in 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" >& "$tst_log"; then + echo "Test $tst passed." + echo ":test-result: PASS $tst" >> run_unit.sh.trs else + cat "$tst_log" + echo "=============================================================" + echo "Test failed on unit: $tst re-run with:" + echo " $ gdb --args ../loolwsd --systemplate=${systemplate} --lotemplate=\"${LO_PATH}\" --childroot=\"${jails}\" --unitlib=\".libs/unit-$tst.so\"" + echo "=============================================================" + echo ":test-result: FAIL $tst" >> run_unit.sh.trs fi done - commit 024fd2ee8d639dc52c9038c4e54a7705a9709b4c Author: Michael Meeks <[email protected]> Date: Tue Apr 5 23:04:40 2016 +0100 Scripting to create and populate jails automatically. 'make check' now builds a system image, and runs tests inside it. diff --git a/loolwsd/test/Makefile.am b/loolwsd/test/Makefile.am index 94de2de..412606c 100644 --- a/loolwsd/test/Makefile.am +++ b/loolwsd/test/Makefile.am @@ -17,14 +17,31 @@ unit_prefork_la_SOURCES = \ UnitPrefork.cpp unit_prefork_la_LDFLAGS = -module +jails=${top_builddir}/test/jails +systemplate=${top_builddir}/test/systemplate +export jails +export systemplate + +${systemplate}/system_stamp : + rm -rf ${systemplate} + ${top_srcdir}/loolwsd-systemplate-setup ${systemplate} ${LO_PATH} && touch ${systemplate}/system_stamp + +${jails} : + mkdir -p ${jails} + +run_tests : ${systemplate}/system_stamp ${jails} + ${top_srcdir}/test/run_unit.sh "${LO_PATH}" + if HAVE_LO_PATH -TESTS = $(top_builddir)/test/test $(top_builddir)/loolwsd/test/run_unit.sh +TESTS = run_tests $(top_builddir)/test/test + +clean-local: + rm -rf ${top_builddir}/test/jails + rm -rf ${systemplate} else TESTS = $(top_builddir)/test/test endif EXTRA_DIST = data/hello.odt data/hello.txt $(test_SOURCES) run_unit.sh -clean-hook: - @echo "rm -Rf $(top_builddir)/test/jails" diff --git a/loolwsd/test/run_unit.sh b/loolwsd/test/run_unit.sh new file mode 100755 index 0000000..d8ec7f8 --- /dev/null +++ b/loolwsd/test/run_unit.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +export LOOL_LOGLEVEL=trace + +for test in prefork; do + echo "Running test: $test"; + if ../loolwsd --systemplate=${systemplate} --lotemplate="$1" --childroot="${jails}" --unitlib=".libs/unit-$test.so" >& "${jails}/$test.log"; then + else + fi +done + + commit ad13dca8f89b94fe8013fd6d6fb91087d9b9a9a4 Author: Michael Meeks <[email protected]> Date: Tue Apr 5 17:41:10 2016 +0100 First cut at adding integration and unit test hooks into loolwsd. Add new configure parameter --with-lo-path= which can be used to auto-populate a system template as required. diff --git a/loolwsd/LOOLKit.hpp b/loolwsd/LOOLKit.hpp index 3a4ca67..4f1bcc3 100644 --- a/loolwsd/LOOLKit.hpp +++ b/loolwsd/LOOLKit.hpp @@ -1,3 +1,4 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index d8669d4..95ab3e5 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -92,6 +92,7 @@ #include "Storage.hpp" #include "IoUtil.hpp" #include "Util.hpp" +#include "Unit.hpp" using namespace LOOLProtocol; @@ -163,7 +164,9 @@ void forkChildren(int number) void preForkChildren() { std::unique_lock<std::mutex> lock(newChildrenMutex); - forkChildren(LOOLWSD::NumPreSpawnedChildren); + int nPreSpawn = LOOLWSD::NumPreSpawnedChildren; + UnitHooks::get().preSpawnCount(nPreSpawn); + forkChildren(nPreSpawn); } std::shared_ptr<ChildProcess> getNewChild() @@ -954,6 +957,7 @@ std::string LOOLWSD::LoSubPath = "lo"; std::string LOOLWSD::FileServerRoot; std::string LOOLWSD::AdminCreds; bool LOOLWSD::AllowLocalStorage = false; +std::string UnitTestLibrary; unsigned int LOOLWSD::NumPreSpawnedChildren = 0; bool LOOLWSD::DoTest = false; @@ -1139,9 +1143,15 @@ void LOOLWSD::defineOptions(OptionSet& optionSet) optionSet.addOption(Option("test", "", "Interactive testing.") .required(false) .repeatable(false)); + + optionSet.addOption(Option("unitlib", "", "Unit testing library path.") + .required(false) + .repeatable(false) + .argument("unitlib")); } -void LOOLWSD::handleOption(const std::string& optionName, const std::string& value) +void LOOLWSD::handleOption(const std::string& optionName, + const std::string& value) { ServerApplication::handleOption(optionName, value); @@ -1175,6 +1185,8 @@ void LOOLWSD::handleOption(const std::string& optionName, const std::string& val AdminCreds = value; else if (optionName == "allowlocalstorage") AllowLocalStorage = true; + else if (optionName == "unitlib") + UnitTestLibrary = value; else if (optionName == "test") LOOLWSD::DoTest = true; } @@ -1223,6 +1235,12 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/) return Application::EXIT_USAGE; } + if (!UnitHooks::init(UnitTestLibrary)) + { + Log::error("Failed to load unit test library"); + return Application::EXIT_USAGE; + } + initializeSSL(); char *locale = setlocale(LC_ALL, nullptr); diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am index 0731b3e..c555b88 100644 --- a/loolwsd/Makefile.am +++ b/loolwsd/Makefile.am @@ -5,7 +5,7 @@ bin_PROGRAMS = loolwsd loolforkit loolmap loolmount dist_bin_SCRIPTS = loolwsd-systemplate-setup discovery.xml AM_CPPFLAGS = -pthread -AM_LDFLAGS = -pthread +AM_LDFLAGS = -pthread -Wl,-E AM_ETAGSFLAGS = --c++-kinds=+p --fields=+iaS --extra=+q -R --totals=yes * AM_CTAGSFLAGS = $(AM_ETAGSFLAGS) @@ -25,6 +25,7 @@ loolwsd_SOURCES = Admin.cpp \ MasterProcessSession.cpp \ Storage.cpp \ TileCache.cpp \ + Unit.cpp \ $(shared_sources) noinst_PROGRAMS = connect \ @@ -73,6 +74,7 @@ noinst_HEADERS = Admin.hpp \ Rectangle.hpp \ Storage.hpp \ TileCache.hpp \ + Unit.hpp \ Util.hpp \ bundled/include/LibreOfficeKit/LibreOfficeKit.h \ bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h \ diff --git a/loolwsd/Unit.cpp b/loolwsd/Unit.cpp new file mode 100644 index 0000000..82718ce --- /dev/null +++ b/loolwsd/Unit.cpp @@ -0,0 +1,64 @@ +/* -*- 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 "Util.hpp" +#include "Unit.hpp" + +UnitHooks *UnitHooks::_global = nullptr; + +UnitHooks *UnitHooks::linkAndCreateUnit(const std::string &unitLibPath) +{ + void *dlHandle = dlopen(unitLibPath.c_str(), RTLD_GLOBAL|RTLD_NOW); + if (!dlHandle) + { + Log::error("Failed to load " + unitLibPath + ": " + std::string(dlerror())); + return NULL; + } + + CreateUnitHooksFunction* createHooks; + createHooks = (CreateUnitHooksFunction *)dlsym(dlHandle, CREATE_UNIT_HOOKS_SYMBOL); + if (!createHooks) + { + Log::error("No " CREATE_UNIT_HOOKS_SYMBOL " symbol in " + unitLibPath); + return NULL; + } + UnitHooks *pHooks = createHooks(); + + if (pHooks) + pHooks->setHandle(dlHandle); + + return pHooks; +} + +bool UnitHooks::init(const std::string &unitLibPath) +{ + if (!unitLibPath.empty()) + _global = linkAndCreateUnit(unitLibPath); + else + _global = new UnitHooks(); + + return _global != NULL; +} + +UnitHooks::UnitHooks() + : _dlHandle(NULL) +{ +} + +UnitHooks::~UnitHooks() +{ + if (_dlHandle) + dlclose(_dlHandle); + _dlHandle = NULL; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/loolwsd/Unit.hpp b/loolwsd/Unit.hpp new file mode 100644 index 0000000..36c6af6 --- /dev/null +++ b/loolwsd/Unit.hpp @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + */ +#ifndef LOOL_UNIT_HPP +#define LOOL_UNIT_HPP + +#include <string> + +class UnitHooks; + +#define CREATE_UNIT_HOOKS_SYMBOL "unit_create" +typedef UnitHooks *(CreateUnitHooksFunction)(); +extern "C" { UnitHooks *unit_create(void); } + +/// Derive your unit test / hooks from me. +class UnitHooks +{ + void *_dlHandle; + static UnitHooks *_global; + + void setHandle(void *dlHandle) { _dlHandle = dlHandle; } + static UnitHooks *linkAndCreateUnit(const std::string &unitLibPath); +public: + UnitHooks(); + virtual ~UnitHooks(); + static UnitHooks &get() { return *_global; } + /// Load unit test hook shared library from this path + static bool init(const std::string &unitLibPath); + + virtual void preSpawnCount(int & /* numPrefork */) {} +}; + +#endif // LOOL_UNIT_HPP + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/loolwsd/configure.ac b/loolwsd/configure.ac index 1066ff6..d50fce2 100644 --- a/loolwsd/configure.ac +++ b/loolwsd/configure.ac @@ -4,6 +4,7 @@ AC_PREREQ([2.69]) AC_INIT([loolwsd], [1.5.5], [[email protected]]) +LT_INIT([disable-static]) AM_INIT_AUTOMAKE([1.11 silent-rules subdir-objects]) @@ -43,6 +44,10 @@ AC_ARG_WITH([lokit-path], AS_HELP_STRING([--with-lokit-path=<path>], [Path to the "include" directory with the LibreOfficeKit headers])) +AC_ARG_WITH([lo-path], + AS_HELP_STRING([--with-lo-path=<path>], + [Path to a working installation directory or instdir of LibreOffice])) + AC_ARG_WITH([poco-includes], AS_HELP_STRING([--with-poco-includes=<path>], [Path to the "include" directory with the Poco headers])) @@ -82,6 +87,30 @@ AS_IF([test -z "$with_poco_libs"], with_lokit_path=`readlink -f $with_lokit_path` AS_IF([test -n "$with_lokit_path"], [CPPFLAGS="$CPPFLAGS -I${with_lokit_path}"]) +lokit_msg="$with_lokit_path" + +dnl +dnl lo_path is not required; but useful for testing. +dnl +LO_PATH= +have_lo_path=false +AC_MSG_CHECKING([whether to run tests against a LibreOffice]) +if test -n "$with_lo_path"; then + version_file="$with_lo_path/program/versionrc" + if test -f $version_file; then + LO_PATH="$with_lo_path" + have_lo_path=true + lo_msg="test against $LO_PATH" + AC_MSG_RESULT([yes]) + else + AC_MSG_ERROR([LibreOffice install looks dodgy, missing $version_file]) + fi +else + lo_msg="no integration tests" + AC_MSG_RESULT([no]) +fi +AC_SUBST(LO_PATH) +AM_CONDITIONAL(HAVE_LO_PATH,[test "$have_lo_path" = "true"]) AS_IF([test -n "$with_poco_includes"], [CPPFLAGS="$CPPFLAGS -I${with_poco_includes}"]) @@ -177,4 +206,12 @@ AC_OUTPUT AC_LANG_POP +echo " +Configuration: + Source code location: ${srcdir} + Build location: ${top_builddir} + LOKit path ${lokit_msg} + LO integration tests ${lo_msg} +" + dnl vim:set shiftwidth=4 softtabstop=4 expandtab: diff --git a/loolwsd/test/Makefile.am b/loolwsd/test/Makefile.am index e99adb9..94de2de 100644 --- a/loolwsd/test/Makefile.am +++ b/loolwsd/test/Makefile.am @@ -2,12 +2,29 @@ check_PROGRAMS = test AM_CXXFLAGS = $(CPPUNIT_CFLAGS) +lib_LTLIBRARIES = unit-prefork.la + +AM_CPPFLAGS = -pthread -I$(top_srcdir) + test_CPPFLAGS = -DTDOC=\"$(top_srcdir)/test/data\" test_LDADD = $(CPPUNIT_LIBS) test_SOURCES = httpposttest.cpp httpwstest.cpp test.cpp ../LOOLProtocol.cpp -EXTRA_DIST = data/hello.odt data/hello.txt $(test_SOURCES) +# unit test modules: +unit_prefork_la_SOURCES = \ + UnitPrefork.cpp +unit_prefork_la_LDFLAGS = -module + +if HAVE_LO_PATH +TESTS = $(top_builddir)/test/test $(top_builddir)/loolwsd/test/run_unit.sh +else +TESTS = $(top_builddir)/test/test +endif + +EXTRA_DIST = data/hello.odt data/hello.txt $(test_SOURCES) run_unit.sh + +clean-hook: + @echo "rm -Rf $(top_builddir)/test/jails" -TESTS = test diff --git a/loolwsd/test/UnitPrefork.cpp b/loolwsd/test/UnitPrefork.cpp new file mode 100644 index 0000000..3d93d4d --- /dev/null +++ b/loolwsd/test/UnitPrefork.cpp @@ -0,0 +1,33 @@ +/* -*- 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 "Util.hpp" +#include "Unit.hpp" + +class UnitPrefork : public UnitHooks { +public: + UnitPrefork() + { + } + virtual void preSpawnCount(int &numPrefork) + { + numPrefork = 20; + Log::error("Hello world"); + } +}; + +UnitHooks *unit_create(void) +{ + return new UnitPrefork(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit b6ab8982e6921b60fa785baf47480420f6d97601 Author: Michael Meeks <[email protected]> Date: Thu Apr 7 13:13:03 2016 +0100 Guard logger so it can be used during static destructors safely. diff --git a/loolwsd/Util.cpp b/loolwsd/Util.cpp index c58202b..2d73562 100644 --- a/loolwsd/Util.cpp +++ b/loolwsd/Util.cpp @@ -92,8 +92,21 @@ namespace rng namespace Log { static const Poco::Int64 epochStart = Poco::Timestamp().epochMicroseconds(); - static std::string SourceName; - static std::string SourceId; + // help avoid destruction ordering issues. + struct StaticNames { + bool inited; + std::string name; + std::string id; + StaticNames() : + inited(true) + { + } + ~StaticNames() + { + inited = false; + } + }; + static StaticNames Source; std::string logPrefix() { @@ -108,7 +121,8 @@ namespace Log usec %= (one_s); std::ostringstream stream; - stream << Log::SourceId << '-' << std::setw(2) << std::setfill('0') + stream << (Source.inited ? Source.id : std::string()) + << '-' << std::setw(2) << std::setfill('0') << (Poco::Thread::current() ? Poco::Thread::current()->id() : 0) << ' ' << std::setw(2) << hours << ':' << std::setw(2) << minutes << ':' << std::setw(2) << seconds << "." << std::setw(6) << usec @@ -124,16 +138,16 @@ namespace Log void initialize(const std::string& name) { - SourceName = name; + Source.name = name; std::ostringstream oss; - oss << SourceName << '-' + oss << Source.name << '-' << std::setw(5) << std::setfill('0') << Poco::Process::id(); - SourceId = oss.str(); + Source.id = oss.str(); auto channel = (isatty(fileno(stdout)) || std::getenv("LOOL_LOGCOLOR") ? static_cast<Poco::Channel*>(new Poco::ColorConsoleChannel()) : static_cast<Poco::Channel*>(new Poco::ConsoleChannel())); - auto& logger = Poco::Logger::create(SourceName, channel, Poco::Message::PRIO_TRACE); + auto& logger = Poco::Logger::create(Source.name, channel, Poco::Message::PRIO_TRACE); // Configure the logger. // TODO: This should come from a file. @@ -149,7 +163,7 @@ namespace Log Poco::Logger& logger() { - return Poco::Logger::get(SourceName); + return Poco::Logger::get(Source.inited ? Source.name : std::string()); } void trace(const std::string& msg) commit 72a0926b4a5ca36f52aaeac33aeb650ec49b41ae Author: Michael Meeks <[email protected]> Date: Wed Apr 6 17:39:44 2016 +0100 Hush - update gitignores. diff --git a/loleaflet/.gitignore b/loleaflet/.gitignore index 1423824..ddcd766 100644 --- a/loleaflet/.gitignore +++ b/loleaflet/.gitignore @@ -12,6 +12,7 @@ _site dist/*.js dist/admin/*.js plugins/draw-0.2.4/dist/*.js +plugins/draw-0.2.4/npm-debug.log coverage/ /load_test_out /spec/data/load_test diff --git a/loolwsd/.gitignore b/loolwsd/.gitignore index 60d6cd2..fa27586 100644 --- a/loolwsd/.gitignore +++ b/loolwsd/.gitignore @@ -3,25 +3,29 @@ \#* # Autofoo -/.deps -/Makefile -/Makefile.in -/aclocal.m4 -/autom4te.cache -/config.h -/config.h.in -/config.log -/config.status -/configure -/compile -/depcomp -/install-sh -/missing -/stamp-h1 -/systemplate -/test-driver -/jails -/loolwsd.spec +.deps +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +config.h +config.h.in +config.log +config.guess +config.status +config.sub +configure +compile +depcomp +install-sh +libtool +ltmain.sh +missing +stamp-h1 +systemplate +test-driver +jails +loolwsd.spec *.o *.exe @@ -36,6 +40,8 @@ loolwsd loolforkit loolmount loolmap +loolmount +looltool sockettransporttest # Debug output diff --git a/loolwsd/test/.gitignore b/loolwsd/test/.gitignore index 81defda..2016409 100644 --- a/loolwsd/test/.gitignore +++ b/loolwsd/test/.gitignore @@ -1,9 +1,11 @@ # Autofoo -/.deps -/Makefile -/Makefile.in +.deps +Makefile +Makefile.in *.log *.trs - +.libs +*.la +*.lo *.o test _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
