test: create UnitSyntheticLok - to stub and override LOK behavior.
Simple example to re-instate previous unit test. Signed-off-by: Michael Meeks <michael.meeks@collabora.com> Change-Id: I26da1178bc897797a656eb5ae9f838d17cbaf75fpull/8880/head
parent
14e3a20e18
commit
642da39dc5
|
@ -31,6 +31,7 @@ class WebSocketHandler;
|
||||||
class ClientSession;
|
class ClientSession;
|
||||||
class Message;
|
class Message;
|
||||||
|
|
||||||
|
|
||||||
// Forward declaration to avoid pulling the world here.
|
// Forward declaration to avoid pulling the world here.
|
||||||
namespace Poco
|
namespace Poco
|
||||||
{
|
{
|
||||||
|
@ -53,11 +54,13 @@ class StorageBase;
|
||||||
|
|
||||||
typedef UnitBase *(CreateUnitHooksFunction)();
|
typedef UnitBase *(CreateUnitHooksFunction)();
|
||||||
typedef UnitBase**(CreateUnitHooksFunctionMulti)();
|
typedef UnitBase**(CreateUnitHooksFunctionMulti)();
|
||||||
extern "C" { UnitBase *unit_create_wsd(void); }
|
extern "C" {
|
||||||
extern "C" { UnitBase** unit_create_wsd_multi(void); }
|
UnitBase *unit_create_wsd(void);
|
||||||
extern "C" { UnitBase *unit_create_kit(void); }
|
UnitBase** unit_create_wsd_multi(void);
|
||||||
extern "C" { typedef struct _LibreOfficeKit LibreOfficeKit; }
|
UnitBase *unit_create_kit(void);
|
||||||
|
typedef struct _LibreOfficeKit LibreOfficeKit;
|
||||||
|
typedef LibreOfficeKit *(LokHookFunction2)( const char *install_path, const char *user_profile_url );
|
||||||
|
}
|
||||||
/// Derive your WSD unit test / hooks from me.
|
/// Derive your WSD unit test / hooks from me.
|
||||||
class UnitBase
|
class UnitBase
|
||||||
{
|
{
|
||||||
|
@ -103,7 +106,7 @@ protected:
|
||||||
STATE_ENUM(TestResult, Failed, Ok, TimedOut);
|
STATE_ENUM(TestResult, Failed, Ok, TimedOut);
|
||||||
|
|
||||||
/// Encourages the process to exit with this value (unless hooked)
|
/// Encourages the process to exit with this value (unless hooked)
|
||||||
void exitTest(TestResult result, const std::string& reason = std::string());
|
virtual void exitTest(TestResult result, const std::string& reason = std::string());
|
||||||
|
|
||||||
/// Fail the test with the given reason.
|
/// Fail the test with the given reason.
|
||||||
void failTest(const std::string& reason)
|
void failTest(const std::string& reason)
|
||||||
|
@ -117,7 +120,7 @@ protected:
|
||||||
exitTest(TestResult::Ok, reason);
|
exitTest(TestResult::Ok, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called when a test has eneded, to clean up.
|
/// Called when a test has ended, to clean up.
|
||||||
virtual void endTest(const std::string& reason);
|
virtual void endTest(const std::string& reason);
|
||||||
|
|
||||||
/// Construct a UnitBase instance with a default name.
|
/// Construct a UnitBase instance with a default name.
|
||||||
|
@ -543,7 +546,8 @@ public:
|
||||||
|
|
||||||
/// Allow a custom LibreOfficeKit wrapper
|
/// Allow a custom LibreOfficeKit wrapper
|
||||||
virtual LibreOfficeKit *lok_init(const char * /* instdir */,
|
virtual LibreOfficeKit *lok_init(const char * /* instdir */,
|
||||||
const char * /* userdir */)
|
const char * /* userdir */,
|
||||||
|
LokHookFunction2 /* fn */)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
11
kit/Kit.cpp
11
kit/Kit.cpp
|
@ -3062,13 +3062,14 @@ void lokit_main(
|
||||||
{
|
{
|
||||||
const char *instdir = instdir_path.c_str();
|
const char *instdir = instdir_path.c_str();
|
||||||
const char *userdir = userdir_url.c_str();
|
const char *userdir = userdir_url.c_str();
|
||||||
|
|
||||||
|
if (!initFunction)
|
||||||
|
initFunction = lok_init_2;
|
||||||
|
|
||||||
if (!Util::isKitInProcess())
|
if (!Util::isKitInProcess())
|
||||||
kit = UnitKit::get().lok_init(instdir, userdir);
|
kit = UnitKit::get().lok_init(instdir, userdir, initFunction);
|
||||||
if (!kit)
|
if (!kit)
|
||||||
{
|
kit = initFunction(instdir, userdir);
|
||||||
kit = (initFunction ? initFunction(instdir, userdir)
|
|
||||||
: lok_init_2(instdir, userdir));
|
|
||||||
}
|
|
||||||
|
|
||||||
loKit = std::make_shared<lok::Office>(kit);
|
loKit = std::make_shared<lok::Office>(kit);
|
||||||
if (!loKit)
|
if (!loKit)
|
||||||
|
|
|
@ -32,6 +32,7 @@ AM_CXXFLAGS = $(CPPUNIT_CFLAGS) -DTDOC=\"$(abs_top_srcdir)/test/data\" -DTDIST=\
|
||||||
# 'Finished in' in the `make check` output.
|
# 'Finished in' in the `make check` output.
|
||||||
# When adding new tests, please maintain order.
|
# When adding new tests, please maintain order.
|
||||||
all_la_unit_tests = \
|
all_la_unit_tests = \
|
||||||
|
unit-synthetic-lok.la \
|
||||||
unit-wopi-async-slow.la \
|
unit-wopi-async-slow.la \
|
||||||
unit-tiletest.la \
|
unit-tiletest.la \
|
||||||
unit-wopi-fail-upload.la \
|
unit-wopi-fail-upload.la \
|
||||||
|
@ -272,6 +273,8 @@ unit_load_torture_la_SOURCES = UnitLoadTorture.cpp
|
||||||
unit_load_torture_la_LIBADD = $(CPPUNIT_LIBS)
|
unit_load_torture_la_LIBADD = $(CPPUNIT_LIBS)
|
||||||
unit_save_torture_la_SOURCES = UnitSaveTorture.cpp
|
unit_save_torture_la_SOURCES = UnitSaveTorture.cpp
|
||||||
unit_save_torture_la_LIBADD = $(CPPUNIT_LIBS)
|
unit_save_torture_la_LIBADD = $(CPPUNIT_LIBS)
|
||||||
|
unit_synthetic_lok_la_SOURCES = UnitSyntheticLok.cpp
|
||||||
|
unit_synthetic_lok__la_LIBADD = $(CPPUNIT_LIBS)
|
||||||
unit_rendering_options_la_SOURCES = UnitRenderingOptions.cpp
|
unit_rendering_options_la_SOURCES = UnitRenderingOptions.cpp
|
||||||
unit_rendering_options_la_LIBADD = $(CPPUNIT_LIBS)
|
unit_rendering_options_la_LIBADD = $(CPPUNIT_LIBS)
|
||||||
unit_password_protected_la_SOURCES = UnitPasswordProtected.cpp
|
unit_password_protected_la_SOURCES = UnitPasswordProtected.cpp
|
||||||
|
|
|
@ -92,7 +92,6 @@ void UnitSaveTorture::saveTortureOne(
|
||||||
{
|
{
|
||||||
auto timeout = std::chrono::seconds(10);
|
auto timeout = std::chrono::seconds(10);
|
||||||
|
|
||||||
// Save same document from many threads together.
|
|
||||||
std::string documentPath, documentURL;
|
std::string documentPath, documentURL;
|
||||||
helpers::getDocumentPathAndURL(docName, documentPath, documentURL, name);
|
helpers::getDocumentPathAndURL(docName, documentPath, documentURL, name);
|
||||||
|
|
||||||
|
@ -146,6 +145,7 @@ UnitSaveTorture::UnitSaveTorture()
|
||||||
: UnitWSD("UnitSaveTorture"),
|
: UnitWSD("UnitSaveTorture"),
|
||||||
forceAutosave(false)
|
forceAutosave(false)
|
||||||
{
|
{
|
||||||
|
setHasKitHooks();
|
||||||
// Double of the default.
|
// Double of the default.
|
||||||
constexpr std::chrono::minutes timeout_minutes(1);
|
constexpr std::chrono::minutes timeout_minutes(1);
|
||||||
setTimeout(timeout_minutes);
|
setTimeout(timeout_minutes);
|
||||||
|
|
|
@ -0,0 +1,243 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||||
|
/*
|
||||||
|
* Copyright the Collabora Online contributors.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* 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 <config.h>
|
||||||
|
|
||||||
|
#include <Unit.hpp>
|
||||||
|
#include <Util.hpp>
|
||||||
|
#include <helpers.hpp>
|
||||||
|
#include <StringVector.hpp>
|
||||||
|
#include <WebSocketSession.hpp>
|
||||||
|
#include <test/testlog.hpp>
|
||||||
|
#include <test/lokassert.hpp>
|
||||||
|
|
||||||
|
#include <LibreOfficeKit/LibreOfficeKit.hxx>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void *memdup(const void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
auto p = malloc(size);
|
||||||
|
memcpy(p, ptr, size);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Save torture testcase.
|
||||||
|
class UnitSyntheticLok : public UnitWSD
|
||||||
|
{
|
||||||
|
void loadAndSynthesize(const std::string& name, const std::string& docName);
|
||||||
|
|
||||||
|
public:
|
||||||
|
UnitSyntheticLok();
|
||||||
|
void invokeWSDTest() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
void UnitSyntheticLok::loadAndSynthesize(
|
||||||
|
const std::string& name, const std::string& docName)
|
||||||
|
{
|
||||||
|
auto timeout = std::chrono::seconds(10);
|
||||||
|
|
||||||
|
std::string documentPath, documentURL;
|
||||||
|
helpers::getDocumentPathAndURL(docName, documentPath, documentURL, name);
|
||||||
|
|
||||||
|
TST_LOG("Starting test on " << documentURL << ' ' << documentPath);
|
||||||
|
|
||||||
|
std::shared_ptr<SocketPoll> poll = std::make_shared<SocketPoll>("WebSocketPoll");
|
||||||
|
poll->startThread();
|
||||||
|
|
||||||
|
Poco::URI uri(helpers::getTestServerURI());
|
||||||
|
auto wsSession = helpers::loadDocAndGetSession(poll, docName, uri, testname);
|
||||||
|
|
||||||
|
std::vector<char> message
|
||||||
|
= wsSession->waitForMessage("status:", timeout, name);
|
||||||
|
const std::string status = COOLProtocol::getFirstLine(message);
|
||||||
|
|
||||||
|
// Kit will signal success through unitresult: to wsd in its own time.
|
||||||
|
}
|
||||||
|
|
||||||
|
UnitSyntheticLok::UnitSyntheticLok()
|
||||||
|
: UnitWSD("UnitSyntheticLok")
|
||||||
|
{
|
||||||
|
setHasKitHooks();
|
||||||
|
// Double of the default.
|
||||||
|
constexpr std::chrono::minutes timeout_minutes(1);
|
||||||
|
setTimeout(timeout_minutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnitSyntheticLok::invokeWSDTest()
|
||||||
|
{
|
||||||
|
const auto name = "syntheticLok";
|
||||||
|
|
||||||
|
static bool started = false;
|
||||||
|
if (!started)
|
||||||
|
{
|
||||||
|
started = true;
|
||||||
|
loadAndSynthesize(name, "empty.ods");
|
||||||
|
}
|
||||||
|
// wait for result from the Kit process
|
||||||
|
}
|
||||||
|
|
||||||
|
class UnitKitSyntheticLok;
|
||||||
|
|
||||||
|
UnitKitSyntheticLok *GlobalUnitKit;
|
||||||
|
|
||||||
|
// Inside the forkit & kit processes
|
||||||
|
class UnitKitSyntheticLok : public UnitKit
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LibreOfficeKit *_kit;
|
||||||
|
|
||||||
|
// Original and overridden vtables
|
||||||
|
LibreOfficeKitClass *_kitClass;
|
||||||
|
LibreOfficeKitClass *_kitClassClean;
|
||||||
|
|
||||||
|
// Original and overridden vtables
|
||||||
|
LibreOfficeKitDocumentClass *_docClass;
|
||||||
|
LibreOfficeKitDocumentClass *_docClassClean;
|
||||||
|
|
||||||
|
// Polling replacement
|
||||||
|
LibreOfficeKitPollCallback _pollCallback;
|
||||||
|
LibreOfficeKitWakeCallback _wakeCallback;
|
||||||
|
void* _pollData;
|
||||||
|
|
||||||
|
LibreOfficeKitCallback _docCallback;
|
||||||
|
void *_docCallbackData;
|
||||||
|
|
||||||
|
bool isDocumentCreated() const { return _docCallback != nullptr; }
|
||||||
|
|
||||||
|
UnitKitSyntheticLok()
|
||||||
|
: UnitKit("SyntheticLok")
|
||||||
|
, _docCallback(nullptr)
|
||||||
|
, _docCallbackData(nullptr)
|
||||||
|
{
|
||||||
|
TST_LOG("SyntheticLOK kit bootstrap\n");
|
||||||
|
setTimeout(std::chrono::hours(1));
|
||||||
|
GlobalUnitKit = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual LibreOfficeKit *lok_init(
|
||||||
|
const char *instdir, const char *userdir,
|
||||||
|
LokHookFunction2 fn) override;
|
||||||
|
|
||||||
|
void postLOKDocumentEvent(int nType, const char* pPayload)
|
||||||
|
{
|
||||||
|
assert(_docCallback);
|
||||||
|
_docCallback(nType, pPayload, _docCallbackData);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool prePollCallback(int /* timeoutUs */)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void doTest()
|
||||||
|
{
|
||||||
|
if (isDocumentCreated())
|
||||||
|
{
|
||||||
|
TST_LOG("Send test event");
|
||||||
|
postLOKDocumentEvent(LOK_CALLBACK_CELL_CURSOR, "EMPTY");
|
||||||
|
exitTest(TestResult::Ok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
int syn_pollCallback(void* /* pData */, int timeoutUs)
|
||||||
|
{
|
||||||
|
assert(GlobalUnitKit);
|
||||||
|
bool finished = UnitKit::get().isFinished();
|
||||||
|
if (!finished && timeoutUs > 1000) // post initial setup we hope
|
||||||
|
GlobalUnitKit->doTest();
|
||||||
|
if (GlobalUnitKit->prePollCallback(timeoutUs))
|
||||||
|
return GlobalUnitKit->_pollCallback(GlobalUnitKit->_pollData, timeoutUs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void syn_wakeCallback(void* /* pData */)
|
||||||
|
{
|
||||||
|
assert(GlobalUnitKit);
|
||||||
|
GlobalUnitKit->_wakeCallback(GlobalUnitKit->_pollData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void syn_registerCallback (LibreOfficeKitDocument* pThis,
|
||||||
|
LibreOfficeKitCallback pCallback,
|
||||||
|
void* pData)
|
||||||
|
{
|
||||||
|
assert(GlobalUnitKit);
|
||||||
|
GlobalUnitKit->_docCallback = pCallback;
|
||||||
|
GlobalUnitKit->_docCallbackData = pData;
|
||||||
|
GlobalUnitKit->_docClassClean->registerCallback(pThis, pCallback, pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
LibreOfficeKitDocument* syn_documentLoadWithOptions (LibreOfficeKit* pThis,
|
||||||
|
const char* pURL,
|
||||||
|
const char* pOptions)
|
||||||
|
{
|
||||||
|
assert(GlobalUnitKit);
|
||||||
|
|
||||||
|
// chain to parent
|
||||||
|
LibreOfficeKitDocument *doc = GlobalUnitKit->_kitClassClean->documentLoadWithOptions(pThis, pURL, pOptions);
|
||||||
|
|
||||||
|
GlobalUnitKit->_docClass = reinterpret_cast<LibreOfficeKitDocumentClass *>(memdup(doc->pClass, doc->pClass->nSize));
|
||||||
|
GlobalUnitKit->_docClassClean = reinterpret_cast<LibreOfficeKitDocumentClass *>(memdup(doc->pClass, doc->pClass->nSize));
|
||||||
|
doc->pClass = GlobalUnitKit->_docClass;
|
||||||
|
|
||||||
|
GlobalUnitKit->_docClass->registerCallback = syn_registerCallback;
|
||||||
|
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void syn_runLoop (LibreOfficeKit* pThis,
|
||||||
|
LibreOfficeKitPollCallback pPollCallback,
|
||||||
|
LibreOfficeKitWakeCallback pWakeCallback,
|
||||||
|
void* pData)
|
||||||
|
{
|
||||||
|
assert(GlobalUnitKit);
|
||||||
|
|
||||||
|
GlobalUnitKit->_pollCallback = pPollCallback;
|
||||||
|
GlobalUnitKit->_wakeCallback = pWakeCallback;
|
||||||
|
GlobalUnitKit->_pollData = pData;
|
||||||
|
|
||||||
|
GlobalUnitKit->_kitClassClean->runLoop(pThis, syn_pollCallback, syn_wakeCallback, pData);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
LibreOfficeKit *UnitKitSyntheticLok::lok_init(const char *instdir,
|
||||||
|
const char *userdir,
|
||||||
|
LokHookFunction2 fn)
|
||||||
|
{
|
||||||
|
// Let the parent have a go
|
||||||
|
_kit = fn(instdir, userdir);
|
||||||
|
if (!_kit || !_kit->pClass)
|
||||||
|
LOK_ASSERT_FAIL("Failed to get kit initialized");
|
||||||
|
|
||||||
|
_kitClass = reinterpret_cast<LibreOfficeKitClass *>(memdup(_kit->pClass, _kit->pClass->nSize));
|
||||||
|
_kitClassClean = reinterpret_cast<LibreOfficeKitClass *>(memdup(_kit->pClass, _kit->pClass->nSize));
|
||||||
|
|
||||||
|
// switch to our vtable
|
||||||
|
_kit->pClass = _kitClass;
|
||||||
|
|
||||||
|
_kitClass->runLoop = syn_runLoop;
|
||||||
|
_kitClass->documentLoadWithOptions = syn_documentLoadWithOptions;
|
||||||
|
|
||||||
|
return _kit;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnitBase* unit_create_wsd(void) { return new UnitSyntheticLok(); }
|
||||||
|
|
||||||
|
UnitBase *unit_create_kit(void) { return new UnitKitSyntheticLok(); }
|
||||||
|
|
||||||
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
Loading…
Reference in New Issue