libreoffice-online/loolwsd/test/UnitFonts.cpp
Jan Holesovsky 191ee00f2c Run the tests on ports that do not conflict with a 'normal' loolwsd.
For the moment, it will allow running 'make check' that does not conflict with
an already running loolwsd (eg. from 'make run').  Later we can consider
running more tests in parallel.
2016-05-04 13:39:32 +02:00

168 lines
4.9 KiB
C++

/* -*- 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 "Common.hpp"
#include "Util.hpp"
#include "Unit.hpp"
#include "LOOLProtocol.hpp"
#include <dlfcn.h>
#include <Poco/Timestamp.h>
#include <Poco/StringTokenizer.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPServerRequest.h>
#define UNIT_URI "/loolwsd/unit-font"
namespace {
// interrogate the vcl/ fontmanager for its hook ...
std::string getFontList()
{
void *me = dlopen(NULL,RTLD_NOW);
typedef const char *(GetFontsFn)(void);
GetFontsFn *fn = reinterpret_cast<GetFontsFn *>(
dlsym(me, "unit_online_get_fonts"));
if (fn)
return std::string(fn());
else
return std::string("can't find unit_online_get_fonts hook");
}
std::string readFontList(const std::shared_ptr< Poco::Net::WebSocket > &socket)
{
int flags;
char buffer[100 * 1000];
int length = socket->receiveFrame(buffer, sizeof (buffer), flags);
if (length > 0)
{
assert(length<(int)sizeof(buffer));
buffer[length] = '\0';
return std::string(buffer);
}
else
return std::string("read failure");
}
}
// Inside the WSD process
class UnitPrefork : public UnitWSD
{
std::string _fontsKit;
std::string _fontsBroker;
public:
UnitPrefork()
{
setHasKitHooks();
}
void check()
{
if (!_fontsKit.length() || !_fontsBroker.length())
return; // defer till we have all the data.
if (_fontsKit != _fontsBroker)
{
std::cout << "Error - font list mismatch" << std::endl;
std::cerr << "Kit : '" << _fontsKit << "' vs. Broker : '" << _fontsBroker << "'" << std::endl;
exitTest(TestResult::TEST_FAILED);
}
else
{
Poco::StringTokenizer tokens(_fontsKit, "\n");
if (tokens.count() > 0)
std::cout << " " << tokens[0] << std::endl;
exitTest(TestResult::TEST_OK);
}
}
virtual void newChild(const std::shared_ptr<Poco::Net::WebSocket> &socket) override
{
Log::info("Fetching font list from kit");
socket->sendFrame("unit-getfontlist: \n",
sizeof("unit-getfontlist: \n") - 1);
_fontsKit = readFontList(socket);
check();
}
virtual bool filterHandleRequest(
TestRequest type,
Poco::Net::HTTPServerRequest& request,
Poco::Net::HTTPServerResponse& response) override
{
if (type == UnitWSD::TestRequest::TEST_REQ_PRISONER &&
request.getURI().find(UNIT_URI) == 0)
{
auto ws = std::make_shared<Poco::Net::WebSocket>(request, response);
_fontsBroker = readFontList(ws);
check();
return true;
}
return false;
}
};
// Inside the forkit & kit processes
class UnitKitPrefork : public UnitKit
{
public:
UnitKitPrefork()
{
}
// Called in the forkit after forking the kit
virtual void launchedKit(int /* pid */) override
{
// Open websocket connection between the child process and WSD.
Poco::Net::HTTPClientSession cs("127.0.0.1", MasterPortNumber);
cs.setTimeout(0);
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET,
std::string(UNIT_URI));
Poco::Net::HTTPResponse response;
auto ws = std::make_shared<Poco::Net::WebSocket>(cs, request, response);
ws->setReceiveTimeout(0);
Log::info("Fetching font list from forkit");
std::string fontListMsg = getFontList() + "\n";
ws->sendFrame(fontListMsg.c_str(), fontListMsg.length());
}
// Called from WSD and handled inside the kit.
virtual bool filterKitMessage(const std::shared_ptr<Poco::Net::WebSocket> &ws,
std::string &message) override
{
std::string token = LOOLProtocol::getFirstToken(message.c_str(), message.length());
if (token == "unit-getfontlist:")
{
std::string fontListReply = getFontList() + "\n";
ws->sendFrame(fontListReply.c_str(), fontListReply.length());
return true;
}
return false;
}
};
UnitBase *unit_create_wsd(void)
{
return new UnitPrefork();
}
UnitBase *unit_create_kit(void)
{
return new UnitKitPrefork();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */