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 Message;
|
||||
|
||||
|
||||
// Forward declaration to avoid pulling the world here.
|
||||
namespace Poco
|
||||
{
|
||||
|
@ -53,11 +54,13 @@ class StorageBase;
|
|||
|
||||
typedef UnitBase *(CreateUnitHooksFunction)();
|
||||
typedef UnitBase**(CreateUnitHooksFunctionMulti)();
|
||||
extern "C" { UnitBase *unit_create_wsd(void); }
|
||||
extern "C" { UnitBase** unit_create_wsd_multi(void); }
|
||||
extern "C" { UnitBase *unit_create_kit(void); }
|
||||
extern "C" { typedef struct _LibreOfficeKit LibreOfficeKit; }
|
||||
|
||||
extern "C" {
|
||||
UnitBase *unit_create_wsd(void);
|
||||
UnitBase** unit_create_wsd_multi(void);
|
||||
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.
|
||||
class UnitBase
|
||||
{
|
||||
|
@ -103,7 +106,7 @@ protected:
|
|||
STATE_ENUM(TestResult, Failed, Ok, TimedOut);
|
||||
|
||||
/// 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.
|
||||
void failTest(const std::string& reason)
|
||||
|
@ -117,7 +120,7 @@ protected:
|
|||
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);
|
||||
|
||||
/// Construct a UnitBase instance with a default name.
|
||||
|
@ -543,7 +546,8 @@ public:
|
|||
|
||||
/// Allow a custom LibreOfficeKit wrapper
|
||||
virtual LibreOfficeKit *lok_init(const char * /* instdir */,
|
||||
const char * /* userdir */)
|
||||
const char * /* userdir */,
|
||||
LokHookFunction2 /* fn */)
|
||||
{
|
||||
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 *userdir = userdir_url.c_str();
|
||||
|
||||
if (!initFunction)
|
||||
initFunction = lok_init_2;
|
||||
|
||||
if (!Util::isKitInProcess())
|
||||
kit = UnitKit::get().lok_init(instdir, userdir);
|
||||
kit = UnitKit::get().lok_init(instdir, userdir, initFunction);
|
||||
if (!kit)
|
||||
{
|
||||
kit = (initFunction ? initFunction(instdir, userdir)
|
||||
: lok_init_2(instdir, userdir));
|
||||
}
|
||||
kit = initFunction(instdir, userdir);
|
||||
|
||||
loKit = std::make_shared<lok::Office>(kit);
|
||||
if (!loKit)
|
||||
|
|
|
@ -32,6 +32,7 @@ AM_CXXFLAGS = $(CPPUNIT_CFLAGS) -DTDOC=\"$(abs_top_srcdir)/test/data\" -DTDIST=\
|
|||
# 'Finished in' in the `make check` output.
|
||||
# When adding new tests, please maintain order.
|
||||
all_la_unit_tests = \
|
||||
unit-synthetic-lok.la \
|
||||
unit-wopi-async-slow.la \
|
||||
unit-tiletest.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_save_torture_la_SOURCES = UnitSaveTorture.cpp
|
||||
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_LIBADD = $(CPPUNIT_LIBS)
|
||||
unit_password_protected_la_SOURCES = UnitPasswordProtected.cpp
|
||||
|
|
|
@ -92,7 +92,6 @@ void UnitSaveTorture::saveTortureOne(
|
|||
{
|
||||
auto timeout = std::chrono::seconds(10);
|
||||
|
||||
// Save same document from many threads together.
|
||||
std::string documentPath, documentURL;
|
||||
helpers::getDocumentPathAndURL(docName, documentPath, documentURL, name);
|
||||
|
||||
|
@ -146,6 +145,7 @@ UnitSaveTorture::UnitSaveTorture()
|
|||
: UnitWSD("UnitSaveTorture"),
|
||||
forceAutosave(false)
|
||||
{
|
||||
setHasKitHooks();
|
||||
// Double of the default.
|
||||
constexpr std::chrono::minutes timeout_minutes(1);
|
||||
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