2016-04-05 11:41:10 -05:00
|
|
|
/* -*- 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/.
|
|
|
|
*/
|
2016-04-08 03:08:41 -05:00
|
|
|
#ifndef INCLUDED_UNIT_HPP
|
|
|
|
#define INCLUDED_UNIT_HPP
|
2016-04-05 11:41:10 -05:00
|
|
|
|
2016-04-08 11:36:08 -05:00
|
|
|
#include <atomic>
|
2016-08-30 02:06:39 -05:00
|
|
|
#include <cassert>
|
2016-10-29 20:15:00 -05:00
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
2016-04-05 11:41:10 -05:00
|
|
|
|
2016-11-10 02:47:25 -06:00
|
|
|
#include <LOOLWebSocket.hpp>
|
2016-04-18 08:29:17 -05:00
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
class UnitBase;
|
|
|
|
class UnitWSD;
|
|
|
|
class UnitKit;
|
2016-04-08 11:36:08 -05:00
|
|
|
class UnitTimeout;
|
2016-04-07 15:59:27 -05:00
|
|
|
class UnitHTTPServerRequest;
|
|
|
|
class UnitHTTPServerResponse;
|
|
|
|
|
2016-04-16 13:37:38 -05:00
|
|
|
// Forward declaration to avoid pulling the world here.
|
2016-10-29 20:15:00 -05:00
|
|
|
namespace Poco
|
|
|
|
{
|
|
|
|
namespace Net
|
|
|
|
{
|
2016-04-12 15:30:06 -05:00
|
|
|
class HTTPServerRequest;
|
|
|
|
class HTTPServerResponse;
|
2016-04-16 13:37:38 -05:00
|
|
|
}
|
|
|
|
|
2016-10-29 20:15:00 -05:00
|
|
|
namespace Util
|
|
|
|
{
|
2016-04-16 13:37:38 -05:00
|
|
|
class LayeredConfiguration;
|
|
|
|
}
|
|
|
|
}
|
2016-04-12 15:30:06 -05:00
|
|
|
|
2016-12-12 18:53:58 -06:00
|
|
|
class Session;
|
2016-04-07 15:59:27 -05:00
|
|
|
class StorageBase;
|
2016-04-05 11:41:10 -05:00
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
typedef UnitBase *(CreateUnitHooksFunction)();
|
|
|
|
extern "C" { UnitBase *unit_create_wsd(void); }
|
|
|
|
extern "C" { UnitBase *unit_create_kit(void); }
|
2016-05-01 03:04:19 -05:00
|
|
|
extern "C" { typedef struct _LibreOfficeKit LibreOfficeKit; }
|
2016-04-05 11:41:10 -05:00
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
/// Derive your WSD unit test / hooks from me.
|
|
|
|
class UnitBase
|
2016-04-05 11:41:10 -05:00
|
|
|
{
|
2016-04-08 11:36:08 -05:00
|
|
|
friend UnitTimeout;
|
2016-04-09 11:30:48 -05:00
|
|
|
friend UnitWSD;
|
|
|
|
friend UnitKit;
|
2016-04-08 11:36:08 -05:00
|
|
|
|
2016-04-06 13:50:55 -05:00
|
|
|
protected:
|
2016-04-07 15:59:27 -05:00
|
|
|
// ---------------- Helper API ----------------
|
2016-04-08 11:36:08 -05:00
|
|
|
/// After this time we invoke 'timeout' default 30 seconds
|
|
|
|
void setTimeout(int timeoutMilliSeconds);
|
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
/// If the test times out this gets invoked, the default just exits.
|
|
|
|
virtual void timeout();
|
|
|
|
|
2016-12-22 03:27:30 -06:00
|
|
|
enum class TestResult
|
2016-10-29 20:15:00 -05:00
|
|
|
{
|
2016-12-22 03:27:30 -06:00
|
|
|
Failed,
|
|
|
|
Ok,
|
|
|
|
TimedOut
|
2016-10-29 20:15:00 -05:00
|
|
|
};
|
2016-04-09 11:30:48 -05:00
|
|
|
|
|
|
|
/// Encourages the process to exit with this value (unless hooked)
|
2016-04-06 13:50:55 -05:00
|
|
|
void exitTest(TestResult result);
|
2016-04-07 15:59:27 -05:00
|
|
|
|
2016-10-29 20:15:00 -05:00
|
|
|
UnitBase();
|
2016-04-09 11:30:48 -05:00
|
|
|
virtual ~UnitBase();
|
|
|
|
|
|
|
|
public:
|
2016-12-22 03:27:30 -06:00
|
|
|
enum class UnitType
|
2016-10-29 20:15:00 -05:00
|
|
|
{
|
2016-12-22 03:27:30 -06:00
|
|
|
Wsd,
|
|
|
|
Kit
|
2016-10-29 20:15:00 -05:00
|
|
|
};
|
2016-04-09 11:30:48 -05:00
|
|
|
/// Load unit test hook shared library from this path
|
2016-10-29 20:15:00 -05:00
|
|
|
static bool init(UnitType type, const std::string& unitLibPath);
|
2016-04-09 11:30:48 -05:00
|
|
|
|
2016-10-22 10:35:30 -05:00
|
|
|
/// Do we have a unit test library hooking things & loaded
|
|
|
|
static bool isUnitTesting();
|
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
/// Tweak the return value from the process.
|
2016-10-29 20:15:00 -05:00
|
|
|
virtual void returnValue(int& /* retValue */);
|
2016-04-09 11:30:48 -05:00
|
|
|
|
2016-12-07 15:32:08 -06:00
|
|
|
/// Input message either for WSD or Kit
|
2016-12-12 18:53:58 -06:00
|
|
|
virtual bool filterSessionInput(Session *, const char */* buffer */,
|
2016-12-07 15:32:08 -06:00
|
|
|
int /* length */,
|
|
|
|
std::unique_ptr< std::vector<char> > & /* replace */)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static UnitBase& get()
|
|
|
|
{
|
|
|
|
assert(Global);
|
|
|
|
return *static_cast<UnitBase *>(Global);
|
|
|
|
}
|
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
private:
|
|
|
|
void setHandle(void *dlHandle) { _dlHandle = dlHandle; }
|
2016-10-29 20:15:00 -05:00
|
|
|
static UnitBase *linkAndCreateUnit(UnitType type, const std::string& unitLibPath);
|
2016-04-09 11:30:48 -05:00
|
|
|
|
|
|
|
void *_dlHandle;
|
|
|
|
bool _setRetValue;
|
2016-10-29 20:15:00 -05:00
|
|
|
int _retValue;
|
|
|
|
int _timeoutMilliSeconds;
|
2016-04-09 11:30:48 -05:00
|
|
|
std::atomic<bool> _timeoutShutdown;
|
2016-06-07 02:18:49 -05:00
|
|
|
static UnitBase *Global;
|
2016-04-09 11:30:48 -05:00
|
|
|
UnitType _type;
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Derive your WSD unit test / hooks from me.
|
|
|
|
class UnitWSD : public UnitBase
|
|
|
|
{
|
|
|
|
bool _hasKitHooks;
|
2016-10-29 20:15:00 -05:00
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
public:
|
2016-10-29 20:15:00 -05:00
|
|
|
UnitWSD();
|
2016-04-09 11:30:48 -05:00
|
|
|
virtual ~UnitWSD();
|
|
|
|
|
2016-10-29 20:15:00 -05:00
|
|
|
static UnitWSD& get()
|
2016-04-09 11:30:48 -05:00
|
|
|
{
|
2016-12-22 03:27:30 -06:00
|
|
|
assert(Global && Global->_type == UnitType::Wsd);
|
2016-06-07 02:18:49 -05:00
|
|
|
return *static_cast<UnitWSD *>(Global);
|
2016-04-09 11:30:48 -05:00
|
|
|
}
|
|
|
|
|
2016-12-22 03:27:30 -06:00
|
|
|
enum class TestRequest
|
2016-10-29 20:15:00 -05:00
|
|
|
{
|
2016-12-22 03:27:30 -06:00
|
|
|
Client,
|
|
|
|
Prisoner
|
2016-10-29 20:15:00 -05:00
|
|
|
};
|
2016-04-07 15:59:27 -05:00
|
|
|
/// Simulate an incoming request
|
2016-12-23 00:42:35 -06:00
|
|
|
static void testHandleRequest(TestRequest type,
|
2016-04-07 15:59:27 -05:00
|
|
|
UnitHTTPServerRequest& request,
|
|
|
|
UnitHTTPServerResponse& response);
|
2016-04-09 11:30:48 -05:00
|
|
|
/// Do we have hooks for the Kit too
|
|
|
|
bool hasKitHooks() { return _hasKitHooks; }
|
|
|
|
/// set in your unit if you want to be injected into the kit too.
|
2016-04-09 12:26:33 -05:00
|
|
|
void setHasKitHooks(bool hasHooks = true) { _hasKitHooks = hasHooks; }
|
2016-04-05 11:41:10 -05:00
|
|
|
|
2016-04-09 12:26:33 -05:00
|
|
|
// ---------------- WSD hooks ----------------
|
2016-04-07 15:59:27 -05:00
|
|
|
|
2016-04-16 13:37:38 -05:00
|
|
|
/// Manipulate and modify the configuration before any usage.
|
2016-10-29 20:15:00 -05:00
|
|
|
virtual void configure(Poco::Util::LayeredConfiguration& /* config */);
|
2016-04-07 15:59:27 -05:00
|
|
|
/// Main-loop reached, time for testing
|
|
|
|
virtual void invokeTest() {}
|
2016-04-06 13:50:55 -05:00
|
|
|
/// Tweak the count of pre-spawned kits.
|
2016-10-29 20:15:00 -05:00
|
|
|
virtual void preSpawnCount(int& /* numPrefork */) {}
|
2016-04-06 13:50:55 -05:00
|
|
|
/// When a new child kit process reports
|
2016-11-10 02:47:25 -06:00
|
|
|
virtual void newChild(const std::shared_ptr<LOOLWebSocket>& /* socket */) {}
|
2016-04-07 15:59:27 -05:00
|
|
|
/// Intercept createStorage
|
2016-10-14 05:09:43 -05:00
|
|
|
virtual bool createStorage(const Poco::URI& /* uri */,
|
|
|
|
const std::string& /* jailRoot */,
|
2016-04-07 15:59:27 -05:00
|
|
|
const std::string& /* jailPath */,
|
2016-10-29 20:15:00 -05:00
|
|
|
std::unique_ptr<StorageBase>& /*rStorage */)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2016-04-12 15:30:06 -05:00
|
|
|
/// Intercept incoming requests, so unit tests can silently communicate
|
|
|
|
virtual bool filterHandleRequest(
|
2016-10-29 20:15:00 -05:00
|
|
|
TestRequest /* type */,
|
|
|
|
Poco::Net::HTTPServerRequest& /* request */,
|
|
|
|
Poco::Net::HTTPServerResponse& /* response */)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2016-04-17 08:54:05 -05:00
|
|
|
|
2016-05-20 21:31:53 -05:00
|
|
|
/// Child sent a message
|
|
|
|
virtual bool filterChildMessage(const std::vector<char>& /* payload */)
|
2016-10-29 20:15:00 -05:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2016-05-20 21:31:53 -05:00
|
|
|
|
2016-05-01 09:24:31 -05:00
|
|
|
// ---------------- TileCache hooks ----------------
|
|
|
|
/// Called before the lookupTile call returns. Should always be called to fire events.
|
|
|
|
virtual void lookupTile(int part, int width, int height, int tilePosX, int tilePosY,
|
|
|
|
int tileWidth, int tileHeight, std::unique_ptr<std::fstream>& cacheFile);
|
|
|
|
|
2016-10-20 16:09:00 -05:00
|
|
|
// ---------------- DocumentBroker hooks ----------------
|
2016-10-29 20:15:00 -05:00
|
|
|
virtual bool filterLoad(const std::string& /* sessionId */,
|
|
|
|
const std::string& /* jailId */,
|
|
|
|
bool& /* result */)
|
2016-10-20 16:09:00 -05:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-04-17 08:54:05 -05:00
|
|
|
// ---------------- WSD events ----------------
|
|
|
|
virtual void onChildConnected(const int /* pid */, const std::string& /* sessionId */) {}
|
2016-04-18 08:29:17 -05:00
|
|
|
/// When admin notify message is sent
|
|
|
|
virtual void onAdminNotifyMessage(const std::string& /* message */) {}
|
|
|
|
/// When admin message is sent in response to a query
|
|
|
|
virtual void onAdminQueryMessage(const std::string& /* message */) {}
|
2016-05-01 09:24:31 -05:00
|
|
|
|
|
|
|
// ---------------- TileCache events ----------------
|
|
|
|
virtual void onTileCacheHit(int /*part*/, int /*width*/, int /*height*/,
|
|
|
|
int /*tilePosX*/, int /*tilePosY*/,
|
|
|
|
int /*tileWidth*/, int /*tileHeight*/) {}
|
|
|
|
virtual void onTileCacheMiss(int /*part*/, int /*width*/, int /*height*/,
|
|
|
|
int /*tilePosX*/, int /*tilePosY*/,
|
|
|
|
int /*tileWidth*/, int /*tileHeight*/) {}
|
|
|
|
virtual void onTileCacheSubscribe(int /*part*/, int /*width*/, int /*height*/,
|
|
|
|
int /*tilePosX*/, int /*tilePosY*/,
|
|
|
|
int /*tileWidth*/, int /*tileHeight*/) {}
|
2016-04-09 11:30:48 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Derive your Kit unit test / hooks from me.
|
|
|
|
class UnitKit : public UnitBase
|
|
|
|
{
|
|
|
|
public:
|
2016-10-29 20:15:00 -05:00
|
|
|
UnitKit();
|
2016-04-09 11:30:48 -05:00
|
|
|
virtual ~UnitKit();
|
2016-10-29 20:15:00 -05:00
|
|
|
static UnitKit& get()
|
2016-04-09 11:30:48 -05:00
|
|
|
{
|
2016-12-22 03:27:30 -06:00
|
|
|
assert(Global && Global->_type == UnitType::Kit);
|
2016-06-07 02:18:49 -05:00
|
|
|
return *static_cast<UnitKit *>(Global);
|
2016-04-09 11:30:48 -05:00
|
|
|
}
|
2016-04-09 12:26:33 -05:00
|
|
|
|
|
|
|
// ---------------- ForKit hooks ----------------
|
|
|
|
|
|
|
|
/// main-loop reached, time for testing
|
|
|
|
virtual void invokeForKitTest() {}
|
|
|
|
|
2016-04-12 15:30:06 -05:00
|
|
|
/// Post fork hook - just after we fork to init the child kit
|
|
|
|
virtual void launchedKit(int /* pid */) {}
|
|
|
|
|
2016-04-09 12:26:33 -05:00
|
|
|
// ---------------- Kit hooks ----------------
|
|
|
|
|
|
|
|
/// Post fork hook - just before we init the child kit
|
|
|
|
virtual void postFork() {}
|
|
|
|
|
|
|
|
/// Kit got a message
|
2016-11-10 02:47:25 -06:00
|
|
|
virtual bool filterKitMessage(const std::shared_ptr<LOOLWebSocket>& /* ws */,
|
2016-10-29 20:15:00 -05:00
|
|
|
std::string& /* message */)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2016-05-01 03:04:19 -05:00
|
|
|
|
|
|
|
/// Allow a custom LibreOfficeKit wrapper
|
|
|
|
virtual LibreOfficeKit *lok_init(const char * /* instdir */,
|
|
|
|
const char * /* userdir */)
|
2016-10-29 20:15:00 -05:00
|
|
|
{
|
2016-12-22 08:04:07 -06:00
|
|
|
return nullptr;
|
2016-10-29 20:15:00 -05:00
|
|
|
}
|
2016-04-05 11:41:10 -05:00
|
|
|
};
|
|
|
|
|
2016-04-08 03:08:41 -05:00
|
|
|
#endif
|
2016-04-05 11:41:10 -05:00
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|