|
|
@ -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"); |
|
|
|
} |
|
|
|
|
|
|
|
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
|