|
|
|
@ -1,8 +1,8 @@
|
|
|
|
|
// This file is under GNU General Public License 3.0
|
|
|
|
|
// see LICENSE.txt
|
|
|
|
|
|
|
|
|
|
#ifndef LIBPEPADAPTER_PEPTEST_PEPTESTTREE_HXX
|
|
|
|
|
#define LIBPEPADAPTER_PEPTEST_PEPTESTTREE_HXX
|
|
|
|
|
#ifndef LIBPEPADAPTER_PEPTEST_PityUnit_HXX
|
|
|
|
|
#define LIBPEPADAPTER_PEPTEST_PityUnit_HXX
|
|
|
|
|
|
|
|
|
|
#include "../../../src/std_utils.hh"
|
|
|
|
|
#include "../../framework/utils.hh"
|
|
|
|
@ -15,22 +15,20 @@
|
|
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
using namespace pEp::Adapter;
|
|
|
|
|
using namespace pEp::Utils;
|
|
|
|
|
using namespace pEp::Adapter::pEpLog;
|
|
|
|
|
|
|
|
|
|
namespace pEp {
|
|
|
|
|
namespace Test {
|
|
|
|
|
namespace PityTest11 {
|
|
|
|
|
template<class T>
|
|
|
|
|
string pEpTestTree<T>::_global_root_dir = "./peptest";
|
|
|
|
|
std::string PityUnit<T>::_global_root_dir = "./peptest";
|
|
|
|
|
template<class T>
|
|
|
|
|
bool pEpTestTree<T>::debug_log_enabled = false;
|
|
|
|
|
bool PityUnit<T>::debug_log_enabled = false;
|
|
|
|
|
|
|
|
|
|
// PUBLIC CONCSTRUCTORS / FACTORY -----------------------------------------------------------
|
|
|
|
|
template<class T>
|
|
|
|
|
pEpTestTree<T>::pEpTestTree(
|
|
|
|
|
pEpTestTree* const parent,
|
|
|
|
|
const string& name,
|
|
|
|
|
PityUnit<T>::PityUnit(
|
|
|
|
|
PityUnit* const parent,
|
|
|
|
|
const std::string& name,
|
|
|
|
|
const NodeFunc test_func,
|
|
|
|
|
T* model,
|
|
|
|
|
ExecutionMode exec_mode) :
|
|
|
|
@ -44,16 +42,15 @@ namespace pEp {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
string pEpTestTree<T>::getNodeName() const
|
|
|
|
|
std::string PityUnit<T>::getNodeName() const
|
|
|
|
|
{
|
|
|
|
|
return _name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
string pEpTestTree<T>::getNodePath() const
|
|
|
|
|
std::string PityUnit<T>::getNodePath() const
|
|
|
|
|
{
|
|
|
|
|
pEpLogClass("called");
|
|
|
|
|
string ret;
|
|
|
|
|
std::string ret;
|
|
|
|
|
|
|
|
|
|
if (!_isRootNode()) {
|
|
|
|
|
ret = _parent->getNodePath() + "/" + getNodeName();
|
|
|
|
@ -69,9 +66,9 @@ namespace pEp {
|
|
|
|
|
// When Process as dir. parent - ".../<proc>/name"
|
|
|
|
|
// When no process as dir. parent - ".../<proc>/.../name"
|
|
|
|
|
template<class T>
|
|
|
|
|
std::string pEpTestTree<T>::getNodePathShort() const
|
|
|
|
|
std::string PityUnit<T>::getNodePathShort() const
|
|
|
|
|
{
|
|
|
|
|
string ret;
|
|
|
|
|
std::string ret;
|
|
|
|
|
if (_isRootNode()) {
|
|
|
|
|
ret = getNodeName();
|
|
|
|
|
} else {
|
|
|
|
@ -90,7 +87,7 @@ namespace pEp {
|
|
|
|
|
|
|
|
|
|
// Inherited (if null see parent recursively)
|
|
|
|
|
template<class T>
|
|
|
|
|
T* pEpTestTree<T>::getModel() const
|
|
|
|
|
T* PityUnit<T>::getModel() const
|
|
|
|
|
{
|
|
|
|
|
pEpLogClass("called");
|
|
|
|
|
T* ret = nullptr;
|
|
|
|
@ -105,114 +102,100 @@ namespace pEp {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RootNodes have their own data_dir
|
|
|
|
|
// ProcessNodes have their own data_dir inside their RootNote dir (nameclash prossible)
|
|
|
|
|
// All other nodes inherit data_dir from their Root/ProcessNode
|
|
|
|
|
// string pEpTestTree::dataDir() const
|
|
|
|
|
// {
|
|
|
|
|
// pEpLogClass("called");
|
|
|
|
|
// string ret;
|
|
|
|
|
// if(!_isRootNode()) {
|
|
|
|
|
// ret = getRootNodesDir() + _getRootNode().getNodeName() + "/" + _getParentingProcessNode().getNodeName() + "/";
|
|
|
|
|
// } else {
|
|
|
|
|
// ret = getRootNodesDir() + _getRootNode().getNodeName() + "/";
|
|
|
|
|
// }
|
|
|
|
|
// return ret;
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
// Every RootNode has its own dir
|
|
|
|
|
template<class T>
|
|
|
|
|
string pEpTestTree<T>::rootNodeDir() const
|
|
|
|
|
std::string PityUnit<T>::rootNodeDir() const
|
|
|
|
|
{
|
|
|
|
|
return getGlobalRootDir() + _rootNode().getNodeName() + "/";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Every process has its own dir inside its rootNodeDir
|
|
|
|
|
// The Root node has its own processDir for future use
|
|
|
|
|
// All other nodes inherit processDir from their Root/ProcessNode
|
|
|
|
|
template<class T>
|
|
|
|
|
string pEpTestTree<T>::processDir() const
|
|
|
|
|
std::string PityUnit<T>::processDir() const
|
|
|
|
|
{
|
|
|
|
|
if (_isRootNode()) {
|
|
|
|
|
return rootNodeDir() + "rootnode_data";
|
|
|
|
|
return rootNodeDir();
|
|
|
|
|
} else {
|
|
|
|
|
if (&_parentingProcessNode() == &_rootNode()) {
|
|
|
|
|
if (_isProcessNode()) {
|
|
|
|
|
return rootNodeDir() + getNodeName() + "/";
|
|
|
|
|
} else {
|
|
|
|
|
return rootNodeDir() + _parentingProcessNode().getNodeName() + "/";
|
|
|
|
|
};
|
|
|
|
|
} else{
|
|
|
|
|
return _parent->processDir();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
void pEpTestTree<T>::setExecutionMode(ExecutionMode mode)
|
|
|
|
|
void PityUnit<T>::setExecutionMode(ExecutionMode mode)
|
|
|
|
|
{
|
|
|
|
|
_exec_mode = mode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// static
|
|
|
|
|
template<>
|
|
|
|
|
void pEpTestTree<void>::setGlobalRootDir(const string& dir)
|
|
|
|
|
void PityUnit<void>::setGlobalRootDir(const std::string& dir)
|
|
|
|
|
{
|
|
|
|
|
pEpTestTree::_global_root_dir = dir;
|
|
|
|
|
PityUnit::_global_root_dir = dir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// static
|
|
|
|
|
template<class T>
|
|
|
|
|
string pEpTestTree<T>::getGlobalRootDir()
|
|
|
|
|
std::string PityUnit<T>::getGlobalRootDir()
|
|
|
|
|
{
|
|
|
|
|
return pEpTestTree::_global_root_dir + "/";
|
|
|
|
|
return PityUnit::_global_root_dir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
void pEpTestTree<T>::run() const
|
|
|
|
|
void PityUnit<T>::run() const
|
|
|
|
|
{
|
|
|
|
|
pEpLogClass("called");
|
|
|
|
|
// caller is never nullptr if called by another pEpTestTree
|
|
|
|
|
// caller is never nullptr if called by another PityUnit
|
|
|
|
|
if (_isRootNode()) {
|
|
|
|
|
pEpLog::logH1("Starting pEpTestTree from node: " + getNodePathShort());
|
|
|
|
|
pEpLog::log(to_string());
|
|
|
|
|
logH1("Starting PityUnit from node: " + getNodePathShort());
|
|
|
|
|
log(to_string());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Execute in fork and wait here until process ends
|
|
|
|
|
if (_exec_mode == ExecutionMode::PROCESS_SEQUENTIAL) { // fork
|
|
|
|
|
pEpLog::logH2("[ " + to_string(_exec_mode) + " / " + getNodePathShort() + "]");
|
|
|
|
|
_executeInFork(bind(&pEpTestTree::_run, this), true);
|
|
|
|
|
logH2("[ " + to_string(_exec_mode) + " / " + getNodePathShort() + " ]");
|
|
|
|
|
_executeInFork(std::bind(&PityUnit::_run, this), true);
|
|
|
|
|
// Execute in fork and go on, wait for process execution in the end
|
|
|
|
|
} else if (_exec_mode == ExecutionMode::PROCESS_PARALLEL) {
|
|
|
|
|
pEpLog::logH2("[ " + to_string(_exec_mode) + " / " + getNodePathShort() + "]");
|
|
|
|
|
_executeInFork(bind(&pEpTestTree::_run, this), false);
|
|
|
|
|
logH2("[ " + to_string(_exec_mode) + " / " + getNodePathShort() + " ]");
|
|
|
|
|
_executeInFork(std::bind(&PityUnit::_run, this), false);
|
|
|
|
|
// Execute as normal funciton
|
|
|
|
|
} else if (_exec_mode == ExecutionMode::FUNCTION) {
|
|
|
|
|
pEpLog::logH3("[ " + to_string(_exec_mode) + " / " + getNodePathShort() + "]");
|
|
|
|
|
logH3("[ " + to_string(_exec_mode) + " / " + getNodePathShort() + " ]");
|
|
|
|
|
_run();
|
|
|
|
|
} else if (_exec_mode == ExecutionMode::THREAD_PARALLEL) {
|
|
|
|
|
throw invalid_argument(to_string(_exec_mode) + " - not implemented");
|
|
|
|
|
throw std::invalid_argument(to_string(_exec_mode) + " - not implemented");
|
|
|
|
|
} else if (_exec_mode == ExecutionMode::THREAD_SEQUENTIAL) {
|
|
|
|
|
throw invalid_argument(to_string(_exec_mode) + " - not implemented");
|
|
|
|
|
throw std::invalid_argument(to_string(_exec_mode) + " - not implemented");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_waitChildProcesses();
|
|
|
|
|
if(_isRootNode()) {
|
|
|
|
|
_waitChildProcesses();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
string pEpTestTree<T>::to_string(bool recursive, int indent) const
|
|
|
|
|
std::string PityUnit<T>::to_string(bool recursive, int indent) const
|
|
|
|
|
{
|
|
|
|
|
string ret;
|
|
|
|
|
stringstream builder;
|
|
|
|
|
builder << string(indent * 4, ' ');
|
|
|
|
|
std::string ret;
|
|
|
|
|
std::stringstream builder;
|
|
|
|
|
builder << std::string(indent * 4, ' ');
|
|
|
|
|
|
|
|
|
|
builder << getNodeName();
|
|
|
|
|
builder << " [ ";
|
|
|
|
|
builder << to_string(_exec_mode) << " - ";
|
|
|
|
|
builder << "\"" << processDir() << "\"";
|
|
|
|
|
builder << " ]";
|
|
|
|
|
builder << endl;
|
|
|
|
|
builder << std::endl;
|
|
|
|
|
ret = builder.str();
|
|
|
|
|
|
|
|
|
|
if (recursive) {
|
|
|
|
|
indent++;
|
|
|
|
|
for (const pair<string, const pEpTestTree&> child : _children) {
|
|
|
|
|
for (const std::pair<std::string, const PityUnit&> child : _children) {
|
|
|
|
|
ret += child.second.to_string(true, indent);
|
|
|
|
|
}
|
|
|
|
|
indent--;
|
|
|
|
@ -221,7 +204,7 @@ namespace pEp {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
string pEpTestTree<T>::to_string(const ExecutionMode& emode)
|
|
|
|
|
std::string PityUnit<T>::to_string(const ExecutionMode& emode)
|
|
|
|
|
{
|
|
|
|
|
switch (emode) {
|
|
|
|
|
case ExecutionMode::FUNCTION:
|
|
|
|
@ -243,50 +226,50 @@ namespace pEp {
|
|
|
|
|
|
|
|
|
|
//Well, ok, lets just add some little convenience logging service in here, too
|
|
|
|
|
template<class T>
|
|
|
|
|
void pEpTestTree<T>::log(const string& msg) const
|
|
|
|
|
void PityUnit<T>::log(const std::string& msg) const
|
|
|
|
|
{
|
|
|
|
|
stringstream builder;
|
|
|
|
|
std::stringstream builder;
|
|
|
|
|
builder << "[";
|
|
|
|
|
builder << std::to_string(getpid());
|
|
|
|
|
builder << " - ";
|
|
|
|
|
builder << getNodePathShort();
|
|
|
|
|
builder << "] - ";
|
|
|
|
|
builder << msg;
|
|
|
|
|
builder << endl;
|
|
|
|
|
cout << builder.str();
|
|
|
|
|
builder << std::endl;
|
|
|
|
|
std::cout << builder.str();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// PRIVATE ---------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
void pEpTestTree<T>::_run() const
|
|
|
|
|
void PityUnit<T>::_run() const
|
|
|
|
|
{
|
|
|
|
|
_runSelf();
|
|
|
|
|
_runChildren();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
void pEpTestTree<T>::_runSelf() const
|
|
|
|
|
void PityUnit<T>::_runSelf() const
|
|
|
|
|
{
|
|
|
|
|
if (_test_func != nullptr) {
|
|
|
|
|
_test_func(*this);
|
|
|
|
|
} else {
|
|
|
|
|
pEpLog::log("No function to execute");
|
|
|
|
|
log("No function to execute");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
void pEpTestTree<T>::_runChildren() const
|
|
|
|
|
void PityUnit<T>::_runChildren() const
|
|
|
|
|
{
|
|
|
|
|
if (!_children.empty()) {
|
|
|
|
|
for (const pair<string, pEpTestTree&> child : _children) {
|
|
|
|
|
for (const std::pair<std::string, PityUnit&> child : _children) {
|
|
|
|
|
child.second.run();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
void pEpTestTree<T>::_executeInFork(function<void(void)> func, bool wait_child) const
|
|
|
|
|
void PityUnit<T>::_executeInFork(std::function<void(void)> func, bool wait_child) const
|
|
|
|
|
{
|
|
|
|
|
pid_t pid;
|
|
|
|
|
pid = fork();
|
|
|
|
@ -294,7 +277,7 @@ namespace pEp {
|
|
|
|
|
func();
|
|
|
|
|
exit(0);
|
|
|
|
|
} else if (pid < pid_t(0)) {
|
|
|
|
|
throw runtime_error("Error forking");
|
|
|
|
|
throw std::runtime_error("Error forking");
|
|
|
|
|
}
|
|
|
|
|
if (wait_child) {
|
|
|
|
|
_waitChildProcesses();
|
|
|
|
@ -302,25 +285,25 @@ namespace pEp {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
void pEpTestTree<T>::_waitChildProcesses() const
|
|
|
|
|
void PityUnit<T>::_waitChildProcesses() const
|
|
|
|
|
{
|
|
|
|
|
int status;
|
|
|
|
|
pid_t pid;
|
|
|
|
|
while ((pid = wait(&status)) > 0) {
|
|
|
|
|
pEpLog::log(
|
|
|
|
|
log(
|
|
|
|
|
"process[" + std::to_string((int)pid) +
|
|
|
|
|
"] terminated with status: " + std::to_string(status));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
void pEpTestTree<T>::_addChildNode(pEpTestTree& node)
|
|
|
|
|
void PityUnit<T>::_addChildNode(PityUnit& node)
|
|
|
|
|
{
|
|
|
|
|
_children.insert(pair<string, pEpTestTree&>(node.getNodeName(), node));
|
|
|
|
|
_children.insert(std::pair<std::string, PityUnit&>(node.getNodeName(), node));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
bool pEpTestTree<T>::_isProcessNode() const
|
|
|
|
|
bool PityUnit<T>::_isProcessNode() const
|
|
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
if (_exec_mode == ExecutionMode::PROCESS_SEQUENTIAL ||
|
|
|
|
@ -331,7 +314,7 @@ namespace pEp {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
bool pEpTestTree<T>::_isRootNode() const
|
|
|
|
|
bool PityUnit<T>::_isRootNode() const
|
|
|
|
|
{
|
|
|
|
|
if (_parent == nullptr) {
|
|
|
|
|
return true;
|
|
|
|
@ -341,9 +324,9 @@ namespace pEp {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
const pEpTestTree<T>& pEpTestTree<T>::_rootNode() const
|
|
|
|
|
const PityUnit<T>& PityUnit<T>::_rootNode() const
|
|
|
|
|
{
|
|
|
|
|
const pEpTestTree* ret = nullptr;
|
|
|
|
|
const PityUnit* ret = nullptr;
|
|
|
|
|
if (!_isRootNode()) {
|
|
|
|
|
ret = &(_parent->_rootNode());
|
|
|
|
|
} else {
|
|
|
|
@ -356,7 +339,7 @@ namespace pEp {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
const pEpTestTree<T>& pEpTestTree<T>::_parentingProcessNode() const
|
|
|
|
|
const PityUnit<T>& PityUnit<T>::_parentingProcessNode() const
|
|
|
|
|
{
|
|
|
|
|
if (_isRootNode() || _isProcessNode()) {
|
|
|
|
|
return *this;
|
|
|
|
@ -367,7 +350,7 @@ namespace pEp {
|
|
|
|
|
|
|
|
|
|
// name is alphanumeric only (everything else will be replaced by an underscore)
|
|
|
|
|
template<class T>
|
|
|
|
|
string pEpTestTree<T>::_normalizeName(string name) const
|
|
|
|
|
std::string PityUnit<T>::_normalizeName(std::string name) const
|
|
|
|
|
{
|
|
|
|
|
replace_if(
|
|
|
|
|
name.begin(),
|
|
|
|
@ -379,24 +362,24 @@ namespace pEp {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
void pEpTestTree<T>::_data_dir_create()
|
|
|
|
|
void PityUnit<T>::_data_dir_create()
|
|
|
|
|
{
|
|
|
|
|
// Utils::dir_create(dataDir());
|
|
|
|
|
pEpLog::log("creating dir:" + getGlobalRootDir());
|
|
|
|
|
log("creating dir:" + getGlobalRootDir());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
void pEpTestTree<T>::_data_dir_delete()
|
|
|
|
|
void PityUnit<T>::_data_dir_delete()
|
|
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
Utils::path_delete_all(getGlobalRootDir());
|
|
|
|
|
} catch (const exception& e) {
|
|
|
|
|
pEpLog::log("DistTest: - could not delete data dir: " + getGlobalRootDir());
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
log("DistTest: - could not delete data dir: " + getGlobalRootDir());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
void pEpTestTree<T>::_data_dir_recreate()
|
|
|
|
|
void PityUnit<T>::_data_dir_recreate()
|
|
|
|
|
{
|
|
|
|
|
_data_dir_delete();
|
|
|
|
|
_data_dir_create();
|
|
|
|
@ -404,4 +387,4 @@ namespace pEp {
|
|
|
|
|
} // namespace Test
|
|
|
|
|
} // namespace pEp
|
|
|
|
|
|
|
|
|
|
#endif // LIBPEPADAPTER_PEPTEST_PEPTESTTREE_HXX
|
|
|
|
|
#endif // LIBPEPADAPTER_PEPTEST_PityUnit_HXX
|