Browse Source

Tests: PityTest - PityUnit, move tree functionality into base class

LIB-11
heck 4 years ago
parent
commit
f08fd36f42
  1. 139
      test/pitytest11/src/AbstractPityUnit.cc
  2. 22
      test/pitytest11/src/AbstractPityUnit.hh
  3. 59
      test/pitytest11/src/PityTree.hh
  4. 139
      test/pitytest11/src/PityTree.hxx

139
test/pitytest11/src/AbstractPityUnit.cc

@ -25,18 +25,29 @@ namespace pEp {
// static // static
int AbstractPityUnit::procUnitsCount = 0; int AbstractPityUnit::procUnitsCount = 0;
AbstractPityUnit::AbstractPityUnit(const std::string &name, ExecutionMode exec_mode) :
PityTree<AbstractPityUnit>(*this, name),
_exec_mode{ exec_mode }
{
_init();
}
AbstractPityUnit::AbstractPityUnit( AbstractPityUnit::AbstractPityUnit(
AbstractPityUnit *const parent, AbstractPityUnit &parent,
const std::string &name, const std::string &name,
ExecutionMode exec_mode) : ExecutionMode exec_mode) :
_parent{ parent }, PityTree<AbstractPityUnit>(*this, name, parent),
_name{ _normalizeName(name) }, _exec_mode{ exec_mode } _exec_mode{ exec_mode }
{
_init();
}
void AbstractPityUnit::_init()
{ {
logger_debug.set_instancename(getPath()); logger_debug.set_instancename(getPath());
if (!_isRootUnit()) { if (!isRoot()) {
parent->_addChildUnit(*this);
// Inherit // Inherit
procUnitNr = _parent->procUnitNr; procUnitNr = getParent()->procUnitNr;
//Or update if procUnit //Or update if procUnit
if (_isProcessUnit()) { if (_isProcessUnit()) {
_createTransport(); _createTransport();
@ -47,36 +58,18 @@ namespace pEp {
procUnitNr = procUnitsCount; procUnitNr = procUnitsCount;
} }
} }
// static
std::string AbstractPityUnit::getName() const void AbstractPityUnit::setGlobalRootDir(const std::string &dir)
{ {
return _name; AbstractPityUnit::_global_root_dir = dir;
} }
// name is alphanumeric only (everything else will be replaced by an underscore)
// static // static
std::string AbstractPityUnit::_normalizeName(std::string name) std::string AbstractPityUnit::getGlobalRootDir()
{ {
replace_if( return AbstractPityUnit::_global_root_dir;
name.begin(),
name.end(),
[](char c) -> bool { return !isalnum(c); },
'_');
return name;
} }
std::string AbstractPityUnit::getPath() const
{
std::string ret;
if (!_isRootUnit()) {
ret = _parent->getPath() + "/" + getName();
} else {
ret = getName();
}
return ret;
}
// For: // For:
// RootUnit - "<name>" // RootUnit - "<name>"
@ -86,13 +79,13 @@ namespace pEp {
std::string AbstractPityUnit::getPathShort() const std::string AbstractPityUnit::getPathShort() const
{ {
std::string ret; std::string ret;
if (_isRootUnit()) { if (isRoot()) {
ret = getName(); ret = getName();
} else { } else {
if (_isProcessUnit()) { if (_isProcessUnit()) {
ret += ".../" + getName(); ret += ".../" + getName();
} else { } else {
if (&(parentingProcessUnit()) == (_parent)) { if (&(parentingProcessUnit()) == (getParent())) {
ret = parentingProcessUnit().getPathShort() + "/" + getName(); ret = parentingProcessUnit().getPathShort() + "/" + getName();
} else { } else {
ret = parentingProcessUnit().getPathShort() + "/.../" + getName(); ret = parentingProcessUnit().getPathShort() + "/.../" + getName();
@ -102,22 +95,17 @@ namespace pEp {
return ret; return ret;
} }
AbstractPityUnit *AbstractPityUnit::getParent() const
{
return _parent;
}
// Every process has its own dir inside its rootUnitDir // Every process has its own dir inside its rootUnitDir
// All other units inherit processDir from their Root/ProcessUnit // All other units inherit processDir from their Root/ProcessUnit
std::string AbstractPityUnit::processDir() std::string AbstractPityUnit::processDir()
{ {
if (_isRootUnit()) { if (isRoot()) {
return _rootUnitDir(); return _rootUnitDir();
} else { } else {
if (_isProcessUnit()) { if (_isProcessUnit()) {
return _rootUnitDir() + getName() + "/"; return _rootUnitDir() + getName() + "/";
} else { } else {
return _parent->processDir(); return getParent()->processDir();
} }
} }
} }
@ -125,36 +113,24 @@ namespace pEp {
// Every RootUnit has its own dir // Every RootUnit has its own dir
std::string AbstractPityUnit::_rootUnitDir() std::string AbstractPityUnit::_rootUnitDir()
{ {
return getGlobalRootDir() + rootUnit()->getName() + "/"; return getGlobalRootDir() + getRoot().getName() + "/";
} }
// Every process has its own dir inside its rootUnitDir // Every process has its own dir inside its rootUnitDir
// All other units inherit transportDir from their Root/ProcessUnit // All other units inherit transportDir from their Root/ProcessUnit
std::string AbstractPityUnit::transportDir() std::string AbstractPityUnit::transportDir()
{ {
if (_isRootUnit()) { if (isRoot()) {
throw std::runtime_error("No transport dir"); throw std::runtime_error("No transport dir");
} else { } else {
if (_isProcessUnit()) { if (_isProcessUnit()) {
return processDir() + "inbox/"; return processDir() + "inbox/";
} else { } else {
return _parent->transportDir(); return getParent()->transportDir();
} }
} }
} }
// static
void AbstractPityUnit::setGlobalRootDir(const std::string &dir)
{
AbstractPityUnit::_global_root_dir = dir;
}
// static
std::string AbstractPityUnit::getGlobalRootDir()
{
return AbstractPityUnit::_global_root_dir;
}
void AbstractPityUnit::run() void AbstractPityUnit::run()
{ {
pEpLogClass("called"); pEpLogClass("called");
@ -163,8 +139,8 @@ namespace pEp {
setenv("HOME", processDir().c_str(), true); setenv("HOME", processDir().c_str(), true);
if (_isRootUnit()) { if (isRoot()) {
_init(); _initrun();
} }
// Execute in fork and wait here until process ends // Execute in fork and wait here until process ends
@ -182,7 +158,7 @@ namespace pEp {
throw std::invalid_argument(to_string(_exec_mode) + " - not implemented"); throw std::invalid_argument(to_string(_exec_mode) + " - not implemented");
} }
if (_isRootUnit()) { if (isRoot()) {
_waitChildProcesses(); _waitChildProcesses();
} }
} }
@ -202,9 +178,9 @@ namespace pEp {
ret = builder.str(); ret = builder.str();
if (recursive) { if (recursive) {
if (!_children.empty()) { if (!getChildren().empty()) {
indent++; indent++;
for (const std::pair<std::string, AbstractPityUnit &> child : _children) { for (const auto child : getChildren()) {
ret += child.second.to_string(true, indent); ret += child.second.to_string(true, indent);
} }
indent--; indent--;
@ -236,8 +212,8 @@ namespace pEp {
void AbstractPityUnit::recreateDirsRecursively() void AbstractPityUnit::recreateDirsRecursively()
{ {
Utils::dir_recreate(processDir()); Utils::dir_recreate(processDir());
if (!_children.empty()) { if (!getChildren().empty()) {
for (const std::pair<std::string, AbstractPityUnit &> child : _children) { for (const auto child : getChildren()) {
child.second.recreateDirsRecursively(); child.second.recreateDirsRecursively();
} }
} }
@ -250,10 +226,10 @@ namespace pEp {
Endpoints &AbstractPityUnit::transportEndpoints() Endpoints &AbstractPityUnit::transportEndpoints()
{ {
if (_isRootUnit()) { if (isRoot()) {
return _transport_endpoints; return _transport_endpoints;
} else { } else {
return rootUnit()->transportEndpoints(); return getRoot().transportEndpoints();
} }
} }
@ -286,7 +262,7 @@ namespace pEp {
} }
// PRIVATE --------------------------------------------------------------------------------- // PRIVATE ---------------------------------------------------------------------------------
void AbstractPityUnit::_init() void AbstractPityUnit::_initrun()
{ {
logH1("PityTest Starting..."); logH1("PityTest Starting...");
_logRaw("RootUnit: " + getPathShort()); _logRaw("RootUnit: " + getPathShort());
@ -310,8 +286,8 @@ namespace pEp {
void AbstractPityUnit::_runChildren() const void AbstractPityUnit::_runChildren() const
{ {
if (!_children.empty()) { if (!getChildren().empty()) {
for (const std::pair<std::string, AbstractPityUnit &> child : _children) { for (const auto child : getChildren()) {
child.second.run(); child.second.run();
} }
} }
@ -350,11 +326,6 @@ namespace pEp {
} }
} }
void AbstractPityUnit::_addChildUnit(AbstractPityUnit &unit)
{
_children.insert(std::pair<std::string, AbstractPityUnit &>(unit.getName(), unit));
}
bool AbstractPityUnit::_isProcessUnit() const bool AbstractPityUnit::_isProcessUnit() const
{ {
bool ret = false; bool ret = false;
@ -365,30 +336,12 @@ namespace pEp {
return ret; return ret;
} }
bool AbstractPityUnit::_isRootUnit() const
{
if (_parent == nullptr) {
return true;
} else {
return false;
}
}
AbstractPityUnit *AbstractPityUnit::rootUnit()
{
if (!_isRootUnit()) {
return _parent->rootUnit();
} else {
return this;
}
}
const AbstractPityUnit &AbstractPityUnit::parentingProcessUnit() const const AbstractPityUnit &AbstractPityUnit::parentingProcessUnit() const
{ {
if (_isRootUnit() || _isProcessUnit()) { if (isRoot() || _isProcessUnit()) {
return *this; return *this;
} else { } else {
return _parent->parentingProcessUnit(); return getParent()->parentingProcessUnit();
} }
} }
@ -409,8 +362,8 @@ namespace pEp {
if (_transport != nullptr) { if (_transport != nullptr) {
ret = _transport.get(); ret = _transport.get();
} else { } else {
if (!_isRootUnit()) { if (!isRoot()) {
ret = _parent->transport(); ret = getParent()->transport();
} }
} }
return ret; return ret;
@ -449,7 +402,6 @@ namespace pEp {
} }
} }
Utils::Color AbstractPityUnit::_termColor() const Utils::Color AbstractPityUnit::_termColor() const
{ {
return _colForProcUnitNr(procUnitNr); return _colForProcUnitNr(procUnitNr);
@ -465,4 +417,3 @@ namespace pEp {
} // namespace PityTest11 } // namespace PityTest11
} // namespace pEp } // namespace pEp

22
test/pitytest11/src/AbstractPityUnit.hh

@ -7,6 +7,7 @@
#include "../../../src/pEpLog.hh" #include "../../../src/pEpLog.hh"
#include "../../../src/std_utils.hh" #include "../../../src/std_utils.hh"
#include "fs_mutex.hh" #include "fs_mutex.hh"
#include "PityTree.hh"
#include "PityTransport.hh" #include "PityTransport.hh"
#include <string> #include <string>
#include <map> #include <map>
@ -18,7 +19,7 @@
namespace pEp { namespace pEp {
namespace PityTest11 { namespace PityTest11 {
class AbstractPityUnit { class AbstractPityUnit : public PityTree<AbstractPityUnit> {
public: public:
enum class ExecutionMode enum class ExecutionMode
{ {
@ -30,8 +31,9 @@ namespace pEp {
INHERIT INHERIT
}; };
AbstractPityUnit(const std::string& name, ExecutionMode exec_mode = ExecutionMode::FUNCTION);
AbstractPityUnit( AbstractPityUnit(
AbstractPityUnit* const parent, AbstractPityUnit& parent,
const std::string& name, const std::string& name,
ExecutionMode exec_mode = ExecutionMode::FUNCTION); ExecutionMode exec_mode = ExecutionMode::FUNCTION);
@ -40,13 +42,9 @@ namespace pEp {
static std::string getGlobalRootDir(); static std::string getGlobalRootDir();
// Read-Only // Read-Only
std::string getName() const;
std::string getPath() const;
std::string getPathShort() const; std::string getPathShort() const;
std::string processDir(); // own process dir std::string processDir(); // own process dir
std::string transportDir(); std::string transportDir();
AbstractPityUnit* getParent() const;
bool _isRootUnit() const; // true if has no parent
// Main funcs // Main funcs
void run(); void run();
@ -61,8 +59,6 @@ namespace pEp {
void logH3(const std::string& msg) const; void logH3(const std::string& msg) const;
// Util // Util
static std::string _normalizeName(
std::string name); //TODO HACK in PityTransport this should be private
void recreateDirsRecursively(); void recreateDirsRecursively();
//Transport //Transport
@ -87,17 +83,13 @@ namespace pEp {
// METHODS // METHODS
// Execution // Execution
void _init(); void _init();
void _initrun();
void _run(); void _run();
virtual void _runSelf() = 0; virtual void _runSelf() = 0;
void _runChildren() const; void _runChildren() const;
void _executeInFork(std::function<void(void)> func, bool wait_child) const; void _executeInFork(std::function<void(void)> func, bool wait_child) const;
void _waitChildProcesses() const; void _waitChildProcesses() const;
// Modify
void _addChildUnit(AbstractPityUnit& unit);
AbstractPityUnit* rootUnit();
const AbstractPityUnit& parentingProcessUnit() const; const AbstractPityUnit& parentingProcessUnit() const;
// Query // Query
@ -107,13 +99,9 @@ namespace pEp {
// Transport // Transport
void _createTransport(); void _createTransport();
// Fields // Fields
// ------ // ------
AbstractPityUnit* _parent; //nullptr if RootUnit
std::map<const std::string, AbstractPityUnit&> _children; // map to guarantee uniqueness of sibling-names
static std::string _global_root_dir; static std::string _global_root_dir;
const std::string _name;
int procUnitNr; int procUnitNr;
ExecutionMode _exec_mode; ExecutionMode _exec_mode;
static int procUnitsCount; // will be increased in every constructor static int procUnitsCount; // will be increased in every constructor

59
test/pitytest11/src/PityTree.hh

@ -0,0 +1,59 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#ifndef PITYTEST_PITYTREE_HH
#define PITYTEST_PITYTREE_HH
//#include "../../../src/pEpLog.hh"
#include <string>
#include <map>
#include <memory>
#include <unordered_map>
#include <functional>
#include <type_traits>
namespace pEp {
namespace PityTest11 {
template<class T>
class PityTree {
// TODO: NEEEEED THIS
// static_assert(std::is_base_of<PityTree<T>, T>::value, "PityTree<T> must be a base of T");
public:
using Children = std::map<const std::string, T&>;
explicit PityTree(T& self, const std::string& name);
explicit PityTree(T& self, const std::string& name, T& parent);
T& add(T& node);
T* getParent() const;
Children getChildren() const;
T& getRoot();
std::string getName() const;
std::string getPath() const;
bool isRoot() const; // true if has no parent
std::string to_string(bool recursive = true, int indent = 0);
//TODO HACK in PityTransport, this should be private
static std::string _normalizeName(std::string name);
virtual ~PityTree() = default;
protected:
void setParent(T* const parent);
private:
// Fields
const std::string _nodename;
T& _self;
T* _parent = nullptr; //nullptr if RootUnit
Children _children; // map to guarantee uniqueness of sibling-names
};
}; // namespace PityTest11
}; // namespace pEp
#include "PityTree.hxx"
#endif

139
test/pitytest11/src/PityTree.hxx

@ -0,0 +1,139 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#ifndef PITYTEST_PITYTREE_HXX
#define PITYTEST_PITYTREE_HXX
#include <iostream>
#include <unistd.h>
#include <cstdlib>
#include <sys/stat.h>
#include <functional>
#include <algorithm>
#include <sstream>
#include <exception>
#include <memory>
#include <unordered_map>
#include <sys/wait.h>
namespace pEp {
namespace PityTest11 {
template<class T>
PityTree<T>::PityTree(T& self, const std::string &name) :
_self{ self }, _nodename{ _normalizeName(name) }
{
}
template<class T>
PityTree<T>::PityTree(T& self, const std::string &name, T& parent) :
_self(self), _nodename{ _normalizeName(name) }
{
parent.add(_self);
}
template<class T>
T& PityTree<T>::add(T& node)
{
node.setParent(&_self);
_children.insert(std::pair<const std::string, T&>(node.getName(), node));
return node;
}
template<class T>
void PityTree<T>::setParent(T *parent)
{
_parent = parent;
}
template<class T>
T *PityTree<T>::getParent() const
{
return _parent;
}
template<class T>
bool PityTree<T>::isRoot() const
{
if (_parent == nullptr) {
return true;
} else {
return false;
}
}
template<class T>
std::string PityTree<T>::getName() const
{
return _nodename;
}
template<class T>
std::string PityTree<T>::getPath() const
{
std::string ret;
if (!isRoot()) {
ret = _parent->getPath() + "/" + getName();
} else {
ret = getName();
}
return ret;
}
template<class T>
std::string PityTree<T>::to_string(bool recursive, int indent)
{
std::string ret;
std::stringstream builder;
builder << std::string(indent * 4, ' ');
builder << getName();
builder << std::endl;
ret = builder.str();
if (recursive) {
if (!getChildren().empty()) {
indent++;
for (auto child : getChildren()) {
ret += child.second.to_string(true, indent);
}
indent--;
}
}
return ret;
}
template<class T>
T& PityTree<T>::getRoot()
{
if (!isRoot()) {
return _parent->getRoot();
} else {
return _self;
}
}
template<class T>
typename PityTree<T>::Children PityTree<T>::getChildren() const
{
return _children;
}
// name is alphanumeric only (everything else will be replaced by an underscore)
// static
template<class T>
std::string PityTree<T>::_normalizeName(std::string name)
{
replace_if(
name.begin(),
name.end(),
[](char c) -> bool { return !isalnum(c); },
'_');
return name;
}
} // namespace PityTest11
} // namespace pEp
#endif
Loading…
Cancel
Save