From 3654b5a86dd3af3276122e84c3cb13f84e013977 Mon Sep 17 00:00:00 2001 From: heck Date: Thu, 10 Jun 2021 05:16:44 +0200 Subject: [PATCH] Tests: PityTest - integrate transport into PityUnit --- src/PityUnit.hh | 52 +++++--- src/PityUnit.hxx | 309 +++++++++++++++++++++++++++++------------------ 2 files changed, 228 insertions(+), 133 deletions(-) diff --git a/src/PityUnit.hh b/src/PityUnit.hh index 3bccaed..5703428 100644 --- a/src/PityUnit.hh +++ b/src/PityUnit.hh @@ -10,12 +10,17 @@ #include #include #include "fs_mutex.hh" +#include "PityTransport.hh" +//#include "PityModel.hh" // Yes, the mem mgmt is purely static on purpose (so far) namespace pEp { namespace PityTest11 { - template + class PityModel; + class PityPerspective; + + template class PityUnit { public: enum class ExecutionMode @@ -30,20 +35,20 @@ namespace pEp { // Constructors are private PityUnit() = delete; - explicit PityUnit( - PityUnit* parent, + explicit PityUnit( + PityUnit<>* parent, const std::string& name, - const std::function test_func = nullptr, + const std::function test_func = nullptr, T* model = nullptr, + P* perspective = nullptr, ExecutionMode exec_mode = ExecutionMode::FUNCTION); // Read-Only std::string getName() const; std::string getPath() const; std::string getPathShort() const; - T* getModel() const; - std::string processDir() const; // own process dir - + std::string processDir(); // own process dir + std::string transportDir(); // Read-Write // void setExecutionMode(ExecutionMode mode); static void setGlobalRootDir(const std::string& dir); @@ -52,11 +57,17 @@ namespace pEp { // Main funcs void run(); - std::string to_string(bool recursive = true, int indent = 0) const; + std::string to_string(bool recursive = true, int indent = 0); static std::string to_string(const ExecutionMode& emode); // Util - void recreateDirsRecursively() const; + void recreateDirsRecursively(); + + //Transport + PityTransport* transport() const; + void registerAsTransportEndpoint(); + Endpoints& transportEndpoints(); + // logging service void log(const std::string& msg) const; @@ -73,9 +84,9 @@ namespace pEp { // METHODS // Execution - void _init() const; - void _run() const; - void _runSelf() const; + void _init(); + void _run(); + void _runSelf(); void _runChildren() const; void _executeInFork(std::function func, bool wait_child) const; void _waitChildProcesses() const; @@ -86,9 +97,13 @@ namespace pEp { // Query bool _isProcessUnit() const; bool _isRootUnit() const; - const PityUnit& _rootUnit() const; - std::string _rootUnitDir() const; + PityUnit* _rootUnit(); + std::string _rootUnitDir(); const PityUnit& _parentingProcessUnit() const; + T* _getModel() const; + P* _getPerspective() const; + void createTransport(); + // Util std::string _normalizeName(std::string name) const; @@ -99,14 +114,17 @@ namespace pEp { // Fields const std::string _name; - const PityUnit* _parent; //nullptr if RootUnit + PityUnit* _parent; //nullptr if RootUnit T* _model; //nullptr if inherited - const std::function _test_func; + P* _perspective; //nullptr if inherited + const std::function _test_func; ExecutionMode _exec_mode; static std::string _global_root_dir; std::map _children; // map to guarantee uniqueness of sibling-names int procUnitNr; - static int procUnitsCount; // will be increased in everuy constructor + static int procUnitsCount; // will be increased in everuy constructor + std::shared_ptr _transport; //only ever read via transport() + Endpoints _transport_endpoints; // only ever access via transportEndpoints() std::shared_ptr _log_mutex = nullptr; // internal logging diff --git a/src/PityUnit.hxx b/src/PityUnit.hxx index 00fb93c..5451fee 100644 --- a/src/PityUnit.hxx +++ b/src/PityUnit.hxx @@ -14,33 +14,34 @@ #include #include #include +#include //using namespace pEp::Adapter::pEpLog; namespace pEp { namespace PityTest11 { // static - template - std::string PityUnit::_global_root_dir = "./pitytest_data/"; + template + std::string PityUnit::_global_root_dir = "./pitytest_data/"; // static - template - bool PityUnit::debug_log_enabled = false; + template + bool PityUnit::debug_log_enabled = false; // static - template - int PityUnit::procUnitsCount = 0; + template + int PityUnit::procUnitsCount = 0; // CONSTRUCTOR - template - PityUnit::PityUnit( - PityUnit* const parent, + template + PityUnit::PityUnit( + PityUnit<>* const parent, const std::string& name, - const std::function test_func, + const std::function test_func, T* model, + P* perspective, ExecutionMode exec_mode) : _parent{ parent }, - _model{ model }, _name{ _normalizeName(name) }, _test_func{ test_func }, _exec_mode{ - exec_mode - } + _model{ model }, _perspective{ perspective }, _name{ _normalizeName(name) }, + _test_func{ test_func }, _exec_mode{ exec_mode } { logger_debug.set_instancename(getPath()); if (!_isRootUnit()) { @@ -49,6 +50,7 @@ namespace pEp { procUnitNr = _parent->procUnitNr; //Or update if procUnit if (_isProcessUnit()) { + createTransport(); procUnitsCount++; procUnitNr = procUnitsCount; } @@ -57,14 +59,14 @@ namespace pEp { } } - template - std::string PityUnit::getName() const + template + std::string PityUnit::getName() const { return _name; } - template - std::string PityUnit::getPath() const + template + std::string PityUnit::getPath() const { std::string ret; @@ -81,8 +83,8 @@ namespace pEp { // ProcessUnit - ".../" // When Process as dir. parent - "...//name" // When no process as dir. parent - "...//.../name" - template - std::string PityUnit::getPathShort() const + template + std::string PityUnit::getPathShort() const { std::string ret; if (_isRootUnit()) { @@ -101,34 +103,18 @@ namespace pEp { return ret; } - // Inherited (if null see parent recursively) - template - T* PityUnit::getModel() const - { - pEpLogClass("called"); - T* ret = nullptr; - - if (_model != nullptr) { - ret = _model; - } else { - if (!_isRootUnit()) { - ret = _parent->getModel(); - } - } - return ret; - } // Every RootUnit has its own dir - template - std::string PityUnit::_rootUnitDir() const + template + std::string PityUnit::_rootUnitDir() { - return getGlobalRootDir() + _rootUnit().getName() + "/"; + return getGlobalRootDir() + _rootUnit()->getName() + "/"; } // Every process has its own dir inside its rootUnitDir // All other units inherit processDir from their Root/ProcessUnit - template - std::string PityUnit::processDir() const + template + std::string PityUnit::processDir() { if (_isRootUnit()) { return _rootUnitDir(); @@ -141,28 +127,44 @@ namespace pEp { } } - // template - // void PityUnit::setExecutionMode(ExecutionMode mode) + // Every process has its own dir inside its rootUnitDir + // All other units inherit transportDir from their Root/ProcessUnit + template + std::string PityUnit::transportDir() + { + if (_isRootUnit()) { + throw std::runtime_error("No transport dir"); + } else { + if (_isProcessUnit()) { + return processDir() + "inbox/"; + } else { + return _parent->transportDir(); + } + } + } + + // template + // void PityUnit::setExecutionMode(ExecutionMode mode) // { // _exec_mode = mode; // } // static - template - void PityUnit::setGlobalRootDir(const std::string& dir) + template + void PityUnit::setGlobalRootDir(const std::string& dir) { - PityUnit::_global_root_dir = dir; + PityUnit::_global_root_dir = dir; } // static - template - std::string PityUnit::getGlobalRootDir() + template + std::string PityUnit::getGlobalRootDir() { return PityUnit::_global_root_dir; } - template - void PityUnit::run() + template + void PityUnit::run() { pEpLogClass("called"); _log_mutex = std::make_shared("fds"); @@ -174,10 +176,10 @@ namespace pEp { // Execute in fork and wait here until process ends if (_exec_mode == ExecutionMode::PROCESS_SEQUENTIAL) { // fork - _executeInFork(std::bind(&PityUnit::_run, this), true); + _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) { - _executeInFork(std::bind(&PityUnit::_run, this), false); + _executeInFork(std::bind(&PityUnit::_run, this), false); // Execute as normal funciton } else if (_exec_mode == ExecutionMode::FUNCTION) { _run(); @@ -192,8 +194,8 @@ namespace pEp { } } - template - std::string PityUnit::to_string(bool recursive, int indent) const + template + std::string PityUnit::to_string(bool recursive, int indent) { std::string ret; std::stringstream builder; @@ -210,7 +212,7 @@ namespace pEp { if (recursive) { if (!_children.empty()) { indent++; - for (const std::pair&> child : _children) { + for (const std::pair&> child : _children) { ret += child.second.to_string(true, indent); } indent--; @@ -219,8 +221,8 @@ namespace pEp { return ret; } - template - std::string PityUnit::to_string(const ExecutionMode& emode) + template + std::string PityUnit::to_string(const ExecutionMode& emode) { switch (emode) { case ExecutionMode::FUNCTION: @@ -240,8 +242,36 @@ namespace pEp { } } - template - void PityUnit::log(const std::string& msg) const + template + void PityUnit::recreateDirsRecursively() + { + Utils::dir_recreate(processDir()); + if (!_children.empty()) { + for (const std::pair&> child : _children) { + child.second.recreateDirsRecursively(); + } + } + } + + template + void PityUnit::registerAsTransportEndpoint() + { + transportEndpoints().insert({ getName(), transportDir() }); + } + + template + Endpoints& PityUnit::transportEndpoints() + { + if (_isRootUnit()) { + return _transport_endpoints; + } else { + return _rootUnit()->transportEndpoints(); + } + } + + + template + void PityUnit::log(const std::string& msg) const { std::stringstream builder; builder << "["; @@ -255,28 +285,28 @@ namespace pEp { } - template - void PityUnit::logH1(const std::string& msg) const + template + void PityUnit::logH1(const std::string& msg) const { Adapter::pEpLog::logH1(msg, _termColor()); } - template - void PityUnit::logH2(const std::string& msg) const + template + void PityUnit::logH2(const std::string& msg) const { Adapter::pEpLog::logH2(msg, _termColor()); } - template - void PityUnit::logH3(const std::string& msg) const + template + void PityUnit::logH3(const std::string& msg) const { Adapter::pEpLog::logH3(msg, _termColor()); } // PRIVATE --------------------------------------------------------------------------------- - template - void PityUnit::_init() const + template + void PityUnit::_init() { logH1("PityTest Starting..."); logRaw("RootUnit: " + getPathShort()); @@ -292,20 +322,20 @@ namespace pEp { } - template - void PityUnit::_run() const + template + void PityUnit::_run() { logH2(_status_string("STARTING")); _runSelf(); _runChildren(); } - template - void PityUnit::_runSelf() const + template + void PityUnit::_runSelf() { if (_test_func != nullptr) { try { - _test_func(*this); + _test_func(*this, _getModel(), _getPerspective()); logH3(_status_string("\033[1m\033[32mSUCCESS" + Utils::to_termcol(_termColor()))); } catch (const std::exception& e) { logRaw("reason: " + std::string(e.what())); @@ -316,18 +346,18 @@ namespace pEp { } } - template - void PityUnit::_runChildren() const + template + void PityUnit::_runChildren() const { if (!_children.empty()) { - for (const std::pair&> child : _children) { + for (const std::pair&> child : _children) { child.second.run(); } } } - template - void PityUnit::_executeInFork(std::function func, bool wait_child) const + template + void PityUnit::_executeInFork(std::function func, bool wait_child) const { pid_t pid; pid = fork(); @@ -342,8 +372,8 @@ namespace pEp { } } - template - void PityUnit::_waitChildProcesses() const + template + void PityUnit::_waitChildProcesses() const { int status; pid_t pid; @@ -354,14 +384,14 @@ namespace pEp { } } - template - void PityUnit::_addChildUnit(PityUnit& unit) + template + void PityUnit::_addChildUnit(PityUnit& unit) { - _children.insert(std::pair&>(unit.getName(), unit)); + _children.insert(std::pair&>(unit.getName(), unit)); } - template - bool PityUnit::_isProcessUnit() const + template + bool PityUnit::_isProcessUnit() const { bool ret = false; if (_exec_mode == ExecutionMode::PROCESS_SEQUENTIAL || @@ -371,8 +401,8 @@ namespace pEp { return ret; } - template - bool PityUnit::_isRootUnit() const + template + bool PityUnit::_isRootUnit() const { if (_parent == nullptr) { return true; @@ -381,23 +411,23 @@ namespace pEp { } } - template - const PityUnit& PityUnit::_rootUnit() const + template + PityUnit* PityUnit::_rootUnit() { - const PityUnit* ret = nullptr; + // const PityUnit* ret = nullptr; if (!_isRootUnit()) { - ret = &(_parent->_rootUnit()); + return _parent->_rootUnit(); } else { - ret = this; + return this; } - assert(ret != nullptr); + // assert(ret != nullptr); // cant be null because for createChildUnit() you need to provide a TestUnit& and // the only other way is using createRootUnit() which has parent == nullptr - return *ret; + // return *ret; } - template - const PityUnit& PityUnit::_parentingProcessUnit() const + template + const PityUnit& PityUnit::_parentingProcessUnit() const { if (_isRootUnit() || _isProcessUnit()) { return *this; @@ -406,9 +436,68 @@ namespace pEp { } } + // Inherited (if null see parent recursively) + template + T* PityUnit::_getModel() const + { + pEpLogClass("called"); + T* ret = nullptr; + + if (_model != nullptr) { + ret = _model; + } else { + if (!_isRootUnit()) { + ret = _parent->_getModel(); + } + } + return ret; + } + + // Inherited (if null see parent recursively) + template + P* PityUnit::_getPerspective() const + { + pEpLogClass("called"); + P* ret = nullptr; + + if (_perspective != nullptr) { + ret = _perspective; + } else { + if (!_isRootUnit()) { + ret = _parent->_getPerspective(); + } + } + return ret; + } + + // Inherited (if null see parent recursively) + template + void PityUnit::createTransport() + { + registerAsTransportEndpoint(); + _transport = std::shared_ptr(transportDir(), transportEndpoints()); + } + + // Inherited (if null see parent recursively) + template + PityTransport* PityUnit::transport() const + { + pEpLogClass("called"); + PityTransport* ret = nullptr; + + if (_transport.get() != nullptr) { + ret = _transport.get(); + } else { + if (!_isRootUnit()) { + ret = _parent->transport(); + } + } + return ret; + } + // name is alphanumeric only (everything else will be replaced by an underscore) - template - std::string PityUnit::_normalizeName(std::string name) const + template + std::string PityUnit::_normalizeName(std::string name) const { replace_if( name.begin(), @@ -419,8 +508,8 @@ namespace pEp { return name; } - template - std::string PityUnit::_status_string(const std::string& msg) const + template + std::string PityUnit::_status_string(const std::string& msg) const { std::string ret; ret = "[ " + to_string(_exec_mode) + ":" + std::to_string(getpid()) + " ] [ " + @@ -429,8 +518,8 @@ namespace pEp { } - template - Utils::Color PityUnit::_colForProcUnitNr(int procUnitNr) const + template + Utils::Color PityUnit::_colForProcUnitNr(int procUnitNr) const { int nrColors = 7; switch (procUnitNr % nrColors) { @@ -453,32 +542,20 @@ namespace pEp { } } - template - Utils::Color PityUnit::_termColor() const + template + Utils::Color PityUnit::_termColor() const { return _colForProcUnitNr(procUnitNr); } - template - void PityUnit::logRaw(const std::string& msg) const + template + void PityUnit::logRaw(const std::string& msg) const { _log_mutex->aquire(); Adapter::pEpLog::log(msg, _termColor()); _log_mutex->release(); } - - template - void PityUnit::recreateDirsRecursively() const - { - Utils::dir_recreate(processDir()); - if (!_children.empty()) { - for (const std::pair&> child : _children) { - child.second.recreateDirsRecursively(); - } - } - } - } // namespace PityTest11 } // namespace pEp