[Libreoffice-commits] online.git: loolwsd/test loolwsd/Unit.cpp loolwsd/Unit.hpp

Michael Meeks michael.meeks at collabora.com
Fri Apr 8 16:36:43 UTC 2016


 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 <michael.meeks at collabora.com>
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


More information about the Libreoffice-commits mailing list