2016-04-05 11:41:10 -05:00
|
|
|
/* -*- 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/.
|
|
|
|
*/
|
|
|
|
|
2016-10-21 06:30:35 -05:00
|
|
|
#include <iostream>
|
loolwsd: include cleanup and organization
A source file (.cpp) must include its own header first.
This insures that the header is self-contained and
doesn't depend on arbitrary (and accidental) includes
before it to compile.
Furthermore, system headers should go next, followed by
C then C++ headers, then libraries (Poco, etc) and, finally,
project headers come last.
This makes sure that headers and included in the same dependency
order to avoid side-effects. For example, Poco should never rely on
anything from our project in the same way that a C header should
never rely on anything in C++, Poco, or project headers.
Also, includes ought to be sorted where possible, to improve
readability and avoid accidental duplicates (of which there
were a few).
Change-Id: I62cc1343e4a091d69195e37ed659dba20cfcb1ef
Reviewed-on: https://gerrit.libreoffice.org/25262
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2016-05-21 09:23:07 -05:00
|
|
|
#include "Unit.hpp"
|
|
|
|
#include "config.h"
|
|
|
|
|
2016-04-05 11:41:10 -05:00
|
|
|
#include <cassert>
|
loolwsd: include cleanup and organization
A source file (.cpp) must include its own header first.
This insures that the header is self-contained and
doesn't depend on arbitrary (and accidental) includes
before it to compile.
Furthermore, system headers should go next, followed by
C then C++ headers, then libraries (Poco, etc) and, finally,
project headers come last.
This makes sure that headers and included in the same dependency
order to avoid side-effects. For example, Poco should never rely on
anything from our project in the same way that a C header should
never rely on anything in C++, Poco, or project headers.
Also, includes ought to be sorted where possible, to improve
readability and avoid accidental duplicates (of which there
were a few).
Change-Id: I62cc1343e4a091d69195e37ed659dba20cfcb1ef
Reviewed-on: https://gerrit.libreoffice.org/25262
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2016-05-21 09:23:07 -05:00
|
|
|
#include <dlfcn.h>
|
2016-05-01 09:24:31 -05:00
|
|
|
#include <fstream>
|
loolwsd: include cleanup and organization
A source file (.cpp) must include its own header first.
This insures that the header is self-contained and
doesn't depend on arbitrary (and accidental) includes
before it to compile.
Furthermore, system headers should go next, followed by
C then C++ headers, then libraries (Poco, etc) and, finally,
project headers come last.
This makes sure that headers and included in the same dependency
order to avoid side-effects. For example, Poco should never rely on
anything from our project in the same way that a C header should
never rely on anything in C++, Poco, or project headers.
Also, includes ought to be sorted where possible, to improve
readability and avoid accidental duplicates (of which there
were a few).
Change-Id: I62cc1343e4a091d69195e37ed659dba20cfcb1ef
Reviewed-on: https://gerrit.libreoffice.org/25262
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2016-05-21 09:23:07 -05:00
|
|
|
#include <ftw.h>
|
2016-04-05 11:41:10 -05:00
|
|
|
|
2016-04-08 11:36:08 -05:00
|
|
|
#include <Poco/Thread.h>
|
2016-04-06 13:50:55 -05:00
|
|
|
#include <Poco/Util/Application.h>
|
|
|
|
|
loolwsd: include cleanup and organization
A source file (.cpp) must include its own header first.
This insures that the header is self-contained and
doesn't depend on arbitrary (and accidental) includes
before it to compile.
Furthermore, system headers should go next, followed by
C then C++ headers, then libraries (Poco, etc) and, finally,
project headers come last.
This makes sure that headers and included in the same dependency
order to avoid side-effects. For example, Poco should never rely on
anything from our project in the same way that a C header should
never rely on anything in C++, Poco, or project headers.
Also, includes ought to be sorted where possible, to improve
readability and avoid accidental duplicates (of which there
were a few).
Change-Id: I62cc1343e4a091d69195e37ed659dba20cfcb1ef
Reviewed-on: https://gerrit.libreoffice.org/25262
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2016-05-21 09:23:07 -05:00
|
|
|
#include "Log.hpp"
|
|
|
|
#include "Util.hpp"
|
|
|
|
|
2016-11-14 07:58:04 -06:00
|
|
|
#include "common/SigUtil.hpp"
|
|
|
|
|
2016-06-07 02:18:49 -05:00
|
|
|
UnitBase *UnitBase::Global = nullptr;
|
2016-04-05 11:41:10 -05:00
|
|
|
|
2016-04-08 11:36:08 -05:00
|
|
|
static Poco::Thread TimeoutThread("unit timeout");
|
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
UnitBase *UnitBase::linkAndCreateUnit(UnitType type, const std::string &unitLibPath)
|
2016-04-05 11:41:10 -05:00
|
|
|
{
|
|
|
|
void *dlHandle = dlopen(unitLibPath.c_str(), RTLD_GLOBAL|RTLD_NOW);
|
|
|
|
if (!dlHandle)
|
|
|
|
{
|
2016-11-06 11:06:21 -06:00
|
|
|
LOG_ERR("Failed to load " << unitLibPath << ": " << dlerror());
|
2016-12-22 08:04:07 -06:00
|
|
|
return nullptr;
|
2016-04-05 11:41:10 -05:00
|
|
|
}
|
|
|
|
|
2016-12-22 08:04:07 -06:00
|
|
|
const char *symbol = nullptr;
|
2016-04-09 11:30:48 -05:00
|
|
|
switch (type)
|
|
|
|
{
|
2016-12-22 03:27:30 -06:00
|
|
|
case UnitType::Wsd:
|
2016-04-09 11:30:48 -05:00
|
|
|
symbol = "unit_create_wsd";
|
|
|
|
break;
|
2016-12-22 03:27:30 -06:00
|
|
|
case UnitType::Kit:
|
2016-04-09 11:30:48 -05:00
|
|
|
symbol = "unit_create_kit";
|
|
|
|
break;
|
|
|
|
}
|
2016-04-05 11:41:10 -05:00
|
|
|
CreateUnitHooksFunction* createHooks;
|
2016-04-09 11:30:48 -05:00
|
|
|
createHooks = reinterpret_cast<CreateUnitHooksFunction *>(dlsym(dlHandle, symbol));
|
2016-04-05 11:41:10 -05:00
|
|
|
if (!createHooks)
|
|
|
|
{
|
2016-11-06 11:06:21 -06:00
|
|
|
LOG_ERR("No " << symbol << " symbol in " << unitLibPath);
|
2016-12-22 08:04:07 -06:00
|
|
|
return nullptr;
|
2016-04-05 11:41:10 -05:00
|
|
|
}
|
2017-01-13 06:52:08 -06:00
|
|
|
UnitBase *hooks = createHooks();
|
2016-04-05 11:41:10 -05:00
|
|
|
|
2017-01-13 06:52:08 -06:00
|
|
|
if (hooks)
|
|
|
|
hooks->setHandle(dlHandle);
|
2016-04-05 11:41:10 -05:00
|
|
|
|
2017-01-13 06:52:08 -06:00
|
|
|
return hooks;
|
2016-04-05 11:41:10 -05:00
|
|
|
}
|
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
bool UnitBase::init(UnitType type, const std::string &unitLibPath)
|
2016-04-05 11:41:10 -05:00
|
|
|
{
|
2016-06-07 02:18:49 -05:00
|
|
|
assert(!Global);
|
2016-04-05 11:41:10 -05:00
|
|
|
if (!unitLibPath.empty())
|
2016-04-08 11:36:08 -05:00
|
|
|
{
|
2016-06-07 02:18:49 -05:00
|
|
|
Global = linkAndCreateUnit(type, unitLibPath);
|
|
|
|
if (Global)
|
2016-04-09 11:30:48 -05:00
|
|
|
{
|
|
|
|
TimeoutThread.startFunc([](){
|
2016-12-23 00:56:56 -06:00
|
|
|
Poco::Thread::trySleep(Global->_timeoutMilliSeconds);
|
2016-06-07 02:18:49 -05:00
|
|
|
if (!Global->_timeoutShutdown)
|
2016-04-09 11:30:48 -05:00
|
|
|
{
|
2016-11-06 11:06:21 -06:00
|
|
|
LOG_ERR("Unit test timeout");
|
2016-06-07 02:18:49 -05:00
|
|
|
Global->timeout();
|
2016-04-09 11:30:48 -05:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2016-04-08 11:36:08 -05:00
|
|
|
}
|
2016-04-05 11:41:10 -05:00
|
|
|
else
|
2016-04-09 11:30:48 -05:00
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
2016-12-22 03:27:30 -06:00
|
|
|
case UnitType::Wsd:
|
2016-06-07 02:18:49 -05:00
|
|
|
Global = new UnitWSD();
|
2016-04-09 11:30:48 -05:00
|
|
|
break;
|
2016-12-22 03:27:30 -06:00
|
|
|
case UnitType::Kit:
|
2016-06-07 02:18:49 -05:00
|
|
|
Global = new UnitKit();
|
2016-04-09 11:30:48 -05:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-07 02:18:49 -05:00
|
|
|
if (Global)
|
|
|
|
Global->_type = type;
|
2016-04-05 11:41:10 -05:00
|
|
|
|
2016-12-22 08:04:07 -06:00
|
|
|
return Global != nullptr;
|
2016-04-05 11:41:10 -05:00
|
|
|
}
|
|
|
|
|
2016-10-22 10:35:30 -05:00
|
|
|
bool UnitBase::isUnitTesting()
|
|
|
|
{
|
|
|
|
return Global && Global->_dlHandle;
|
|
|
|
}
|
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
void UnitBase::setTimeout(int timeoutMilliSeconds)
|
2016-04-08 11:36:08 -05:00
|
|
|
{
|
|
|
|
assert(!TimeoutThread.isRunning());
|
|
|
|
_timeoutMilliSeconds = timeoutMilliSeconds;
|
|
|
|
}
|
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
UnitBase::UnitBase()
|
2016-12-22 08:04:07 -06:00
|
|
|
: _dlHandle(nullptr),
|
2016-04-09 11:30:48 -05:00
|
|
|
_setRetValue(false),
|
|
|
|
_retValue(0),
|
2016-04-08 11:36:08 -05:00
|
|
|
_timeoutMilliSeconds(30 * 1000),
|
2016-09-28 03:20:24 -05:00
|
|
|
_timeoutShutdown(false),
|
2016-12-22 03:27:30 -06:00
|
|
|
_type(UnitType::Wsd)
|
2016-04-05 11:41:10 -05:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
UnitBase::~UnitBase()
|
2016-04-05 11:41:10 -05:00
|
|
|
{
|
2016-04-06 13:50:55 -05:00
|
|
|
// FIXME: we should really clean-up properly.
|
|
|
|
// if (_dlHandle)
|
|
|
|
// dlclose(_dlHandle);
|
2016-12-22 08:04:07 -06:00
|
|
|
_dlHandle = nullptr;
|
2016-04-05 11:41:10 -05:00
|
|
|
}
|
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
UnitWSD::UnitWSD()
|
|
|
|
: _hasKitHooks(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
UnitWSD::~UnitWSD()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-10-21 15:25:23 -05:00
|
|
|
void UnitWSD::configure(Poco::Util::LayeredConfiguration &config)
|
|
|
|
{
|
2016-10-22 10:35:30 -05:00
|
|
|
if (isUnitTesting())
|
2016-10-21 15:25:23 -05:00
|
|
|
{
|
|
|
|
// Force HTTP - helps stracing.
|
|
|
|
config.setBool("ssl.enable", false);
|
2016-12-03 16:40:58 -06:00
|
|
|
// Use http:// everywhere.
|
|
|
|
config.setBool("ssl.termination", false);
|
2016-10-21 15:25:23 -05:00
|
|
|
// Force console output - easier to debug.
|
|
|
|
config.setBool("logging.file[@enable]", false);
|
|
|
|
}
|
2016-10-22 10:35:30 -05:00
|
|
|
// else - a product run.
|
2016-10-21 15:25:23 -05:00
|
|
|
}
|
|
|
|
|
2016-05-01 09:24:31 -05:00
|
|
|
void UnitWSD::lookupTile(int part, int width, int height, int tilePosX, int tilePosY,
|
|
|
|
int tileWidth, int tileHeight, std::unique_ptr<std::fstream>& cacheFile)
|
|
|
|
{
|
|
|
|
if (cacheFile && cacheFile->is_open())
|
|
|
|
{
|
|
|
|
onTileCacheHit(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
onTileCacheMiss(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
UnitKit::UnitKit()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
UnitKit::~UnitKit()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void UnitBase::exitTest(TestResult result)
|
2016-04-06 13:50:55 -05:00
|
|
|
{
|
2016-12-22 03:27:30 -06:00
|
|
|
LOG_INF("exitTest: " << (int)result << ". Flagging for termination.");
|
2016-04-06 13:50:55 -05:00
|
|
|
_setRetValue = true;
|
2016-12-22 03:27:30 -06:00
|
|
|
_retValue = result == TestResult::Ok ?
|
2016-04-08 11:36:08 -05:00
|
|
|
Poco::Util::Application::EXIT_OK :
|
|
|
|
Poco::Util::Application::EXIT_SOFTWARE;
|
2016-04-06 13:50:55 -05:00
|
|
|
TerminationFlag = true;
|
|
|
|
}
|
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
void UnitBase::timeout()
|
2016-04-08 11:36:08 -05:00
|
|
|
{
|
2016-11-15 21:01:15 -06:00
|
|
|
LOG_ERR("Timed out waiting for unit test to complete");
|
2016-12-22 03:27:30 -06:00
|
|
|
exitTest(TestResult::TimedOut);
|
2016-04-08 11:36:08 -05:00
|
|
|
}
|
|
|
|
|
2016-04-09 11:30:48 -05:00
|
|
|
void UnitBase::returnValue(int &retValue)
|
2016-04-06 13:50:55 -05:00
|
|
|
{
|
|
|
|
if (_setRetValue)
|
|
|
|
retValue = _retValue;
|
|
|
|
|
2016-04-08 11:36:08 -05:00
|
|
|
_timeoutShutdown = true;
|
|
|
|
TimeoutThread.wakeUp();
|
|
|
|
TimeoutThread.join();
|
|
|
|
|
2016-06-07 02:18:49 -05:00
|
|
|
delete Global;
|
|
|
|
Global = nullptr;
|
2016-04-06 13:50:55 -05:00
|
|
|
}
|
|
|
|
|
2016-04-05 11:41:10 -05:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|