From 31a5080395f411d21ae9e2949a4ba21049ad94c2 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Fri, 4 Mar 2016 09:56:33 +0100 Subject: [PATCH] Bug correction EDF12462 (3/3) --- src/engine/InputPort.cxx | 5 +++ src/engine/InputPort.hxx | 1 + src/evalyfx/YACSEvalYFX.cxx | 5 +++ src/evalyfx/YACSEvalYFX.hxx | 1 + src/evalyfx/YACSEvalYFXPattern.cxx | 69 ++++++++++++++++++++++++++---- src/evalyfx/YACSEvalYFXPattern.hxx | 4 ++ src/evalyfx_swig/evalyfx.i | 1 + src/evalyfx_swig/test2.py | 4 +- src/runtime/PythonPorts.cxx | 15 +++++++ src/runtime/PythonPorts.hxx | 1 + 10 files changed, 96 insertions(+), 10 deletions(-) diff --git a/src/engine/InputPort.cxx b/src/engine/InputPort.cxx index d2b13e31d..569e5aacd 100644 --- a/src/engine/InputPort.cxx +++ b/src/engine/InputPort.cxx @@ -161,6 +161,11 @@ std::string InputPort::dump() return xmldump; } +std::string InputPort::getHumanRepr() +{ + return dump(); +} + void InputPort::setStringRef(std::string strRef) { _stringRef = strRef; diff --git a/src/engine/InputPort.hxx b/src/engine/InputPort.hxx index 80c565f22..37c642dc9 100644 --- a/src/engine/InputPort.hxx +++ b/src/engine/InputPort.hxx @@ -76,6 +76,7 @@ namespace YACS virtual void *get() const = 0; virtual void put(const void *data) throw(ConversionException) = 0; virtual std::string dump(); + virtual std::string getHumanRepr(); virtual void setStringRef(std::string strRef); virtual std::string typeName() {return "YACS__ENGINE__InputPort";} bool canBeNull() const; diff --git a/src/evalyfx/YACSEvalYFX.cxx b/src/evalyfx/YACSEvalYFX.cxx index 9e7ef2f3f..dc94ec8fd 100644 --- a/src/evalyfx/YACSEvalYFX.cxx +++ b/src/evalyfx/YACSEvalYFX.cxx @@ -137,6 +137,11 @@ YACSEvalObserver *YACSEvalYFX::getObserver() return _pattern->getObserver(); } +std::string YACSEvalYFX::getErrorDetailsInCaseOfFailure() const +{ + return _pattern->getErrorDetailsInCaseOfFailure(); +} + std::string YACSEvalYFX::getStatusOfRunStr() const { return _pattern->getStatusOfRunStr(); diff --git a/src/evalyfx/YACSEvalYFX.hxx b/src/evalyfx/YACSEvalYFX.hxx index 7f723c4bc..a881e15d1 100644 --- a/src/evalyfx/YACSEvalYFX.hxx +++ b/src/evalyfx/YACSEvalYFX.hxx @@ -58,6 +58,7 @@ public: YACSEVALYFX_EXPORT bool run(YACSEvalSession *session, int& nbOfBranches); YACSEVALYFX_EXPORT void registerObserver(YACSEvalObserver *observer); YACSEVALYFX_EXPORT YACSEvalObserver *getObserver(); + YACSEVALYFX_EXPORT std::string getErrorDetailsInCaseOfFailure() const; YACSEVALYFX_EXPORT std::string getStatusOfRunStr() const; YACSEVALYFX_EXPORT std::vector getResults() const; YACSEVALYFX_EXPORT std::vector getResultsInCaseOfFailure(std::vector& passedIds) const; diff --git a/src/evalyfx/YACSEvalYFXPattern.cxx b/src/evalyfx/YACSEvalYFXPattern.cxx index 7afb739d0..6a787645c 100644 --- a/src/evalyfx/YACSEvalYFXPattern.cxx +++ b/src/evalyfx/YACSEvalYFXPattern.cxx @@ -55,6 +55,8 @@ const char YACSEvalYFXPattern::ST_FAILED[]="SOME_SAMPLES_FAILED_AND_ALL_OF_THEM_ const char YACSEvalYFXPattern::ST_ERROR[]="SOME_SAMPLES_FAILED_BUT_IMPOSSIBLE_TO_CONCLUDE_ON_THEM"; +const std::size_t YACSEvalYFXPattern::MAX_LGTH_OF_INP_DUMP=10000; + const char YACSEvalYFXRunOnlyPattern::FIRST_FE_SUBNODE_NAME[]="Bloc"; const char YACSEvalYFXRunOnlyPattern::GATHER_NODE_NAME[]="__gather__"; @@ -483,6 +485,49 @@ YACS::ENGINE::Proc *YACSEvalYFXRunOnlyPattern::getUndergroundGeneratedGraph() co return _generatedGraph; } +std::string YACSEvalYFXRunOnlyPattern::getErrorDetailsInCaseOfFailure() const +{ + std::string st(getStatusOfRunStr());//test if a run has occurred. + if(st==ST_OK) + throw YACS::Exception("YACSEvalYFXRunOnlyPattern::getErrorDetailsInCaseOfFailure : The execution of scheme has been carried out to the end without any problem !"); + // All the problem can only comes from foreach -> scan it + YACS::ENGINE::ForEachLoop *fe(findTopForEach()); + YACS::ENGINE::NodeStateNameMap nsm; + unsigned nbB(fe->getNumberOfBranchesCreatedDyn()); + std::ostringstream oss; + for(unsigned j=0;jgetChildByNameExec(FIRST_FE_SUBNODE_NAME,j)); + YACS::ENGINE::Bloc *nnc(dynamic_cast(nn)); + if(!nnc) + throw YACS::Exception("YACSEvalYFXRunOnlyPattern::getErrorDetailsInCaseOfFailure : internal error 1 ! The direct son of main foreach is expected to be a Bloc !"); + if(nnc->getState()==YACS::DONE) + continue; + std::list< YACS::ENGINE::ElementaryNode *> fec(nnc->getRecursiveConstituents()); + for(std::list< YACS::ENGINE::ElementaryNode *>::reverse_iterator it=fec.rbegin();it!=fec.rend();it++) + { + YACS::StatesForNode st0((*it)->getState()); + if(st0!=YACS::DONE) + { + oss << "NODE = " << nnc->getChildName(*it) << std::endl; + oss << "STATUS = " << nsm[st0] << std::endl; + oss << "BRANCH ID = " << j << std::endl; + std::list inps((*it)->getSetOfInputPort()); + for(std::list::const_iterator it=inps.begin();it!=inps.end();it++) + { + std::string d((*it)->getHumanRepr()); + if(d.size()>10000) + d=d.substr(0,MAX_LGTH_OF_INP_DUMP); + oss << "INPUT \"" << (*it)->getName() << "\" = " << d << std::endl; + } + oss << "DETAILS = " << std::endl; + oss << (*it)->getErrorDetails(); + } + } + } + return oss.str(); +} + std::string YACSEvalYFXRunOnlyPattern::getStatusOfRunStr() const { YACS::StatesForNode st(_generatedGraph->getState()); @@ -566,15 +611,7 @@ std::vector YACSEvalYFXRunOnlyPattern::getResultsInCaseOfFailu } getStatusOfRunStr();// To check that the status is recognized. std::list lns(_generatedGraph->edGetDirectDescendants()); - YACS::ENGINE::ForEachLoop *fe(0); - for(std::list::const_iterator it=lns.begin();it!=lns.end();it++) - { - fe=dynamic_cast(*it); - if(fe) - break; - } - if(!fe) - throw YACS::Exception("YACSEvalYFXRunOnlyPattern::getResultsInCaseOfFailure : internal error 2 ! ForEach is not accessible !"); + YACS::ENGINE::ForEachLoop *fe(findTopForEach()); // YACS::ENGINE::Executor exe; std::vector outputs; @@ -691,3 +728,17 @@ void YACSEvalYFXRunOnlyPattern::buildOutputPorts() } } +YACS::ENGINE::ForEachLoop *YACSEvalYFXRunOnlyPattern::findTopForEach() const +{ + std::list lns(_generatedGraph->edGetDirectDescendants()); + YACS::ENGINE::ForEachLoop *fe(0); + for(std::list::const_iterator it=lns.begin();it!=lns.end();it++) + { + fe=dynamic_cast(*it); + if(fe) + break; + } + if(!fe) + throw YACS::Exception("YACSEvalYFXRunOnlyPattern::findTopForEach : internal error 2 ! ForEach is not accessible !"); + return fe; +} diff --git a/src/evalyfx/YACSEvalYFXPattern.hxx b/src/evalyfx/YACSEvalYFXPattern.hxx index 6db957d04..4a9654bd5 100644 --- a/src/evalyfx/YACSEvalYFXPattern.hxx +++ b/src/evalyfx/YACSEvalYFXPattern.hxx @@ -75,6 +75,7 @@ public: virtual bool isLocked() const = 0; virtual YACSEvalListOfResources *giveResources() = 0; virtual YACS::ENGINE::Proc *getUndergroundGeneratedGraph() const = 0; + virtual std::string getErrorDetailsInCaseOfFailure() const = 0; virtual std::string getStatusOfRunStr() const = 0; virtual std::vector getResults() const = 0; virtual std::vector getResultsInCaseOfFailure(std::vector& passedIds) const = 0; @@ -107,6 +108,7 @@ public: static const char ST_OK[]; // execution goes to the end without any trouble -> results can be exploited without any problem with getResults and getResultsInCaseOfFailure. static const char ST_FAILED[]; // execution has reached some failed evaluation (normal errors due to incapacity of one node to evaluate) -> results can be exploited without any problem with getResultsInCaseOfFailure static const char ST_ERROR[]; // execution has encountered hard errors (SIGSEGV in a server, internal error in YACS) -> results can be exploited with getResultsInCaseOfFailure but you can't make hypothesis for other ids not in passedIds. + static const std::size_t MAX_LGTH_OF_INP_DUMP; }; class YACSEvalYFXRunOnlyPattern : public YACSEvalYFXPattern @@ -123,6 +125,7 @@ public: bool isLocked() const; YACSEvalListOfResources *giveResources(); YACS::ENGINE::Proc *getUndergroundGeneratedGraph() const; + std::string getErrorDetailsInCaseOfFailure() const; std::string getStatusOfRunStr() const; std::vector getResults() const; std::vector getResultsInCaseOfFailure(std::vector& passedIds) const; @@ -136,6 +139,7 @@ public: private: void buildInputPorts(); void buildOutputPorts(); + YACS::ENGINE::ForEachLoop *findTopForEach() const; private: YACS::ENGINE::ComposedNode *_runNode; std::vector _outputsOfInterest; diff --git a/src/evalyfx_swig/evalyfx.i b/src/evalyfx_swig/evalyfx.i index 212865470..b67dbb4a1 100644 --- a/src/evalyfx_swig/evalyfx.i +++ b/src/evalyfx_swig/evalyfx.i @@ -394,6 +394,7 @@ public: bool isLocked() const; YACS::ENGINE::Proc *getUndergroundGeneratedGraph() const; YACSEvalListOfResources *giveResources(); + std::string getErrorDetailsInCaseOfFailure() const; std::string getStatusOfRunStr() const; void setParallelizeStatus(bool newVal); bool getParallelizeStatus() const; diff --git a/src/evalyfx_swig/test2.py b/src/evalyfx_swig/test2.py index 706b1707d..b47d37caa 100644 --- a/src/evalyfx_swig/test2.py +++ b/src/evalyfx_swig/test2.py @@ -46,4 +46,6 @@ c=c[0] for f,g in zip(c,[0.3333333333333333,0.5,1.0,-1.0,-0.5]): assert(abs(f-g)<1e-12) pass - +st=efx.getErrorDetailsInCaseOfFailure() +assert("NODE = toto.PyScript0" in st) +assert("float division by zero" in st) diff --git a/src/runtime/PythonPorts.cxx b/src/runtime/PythonPorts.cxx index 4d25d1f09..040a1d1cf 100644 --- a/src/runtime/PythonPorts.cxx +++ b/src/runtime/PythonPorts.cxx @@ -190,6 +190,21 @@ std::string InputPyPort::getAsString() return ret; } +std::string InputPyPort::getHumanRepr() +{ + if(!_data) + return dump(); + PyObject *ret(PyObject_Str(_data)); + if(!ret) + return dump(); + std::string retCpp; + char *val(PyString_AsString(ret)); + if(val) + retCpp=val; + Py_XDECREF(ret); + return retCpp; +} + bool InputPyPort::isEmpty() { return _data == Py_None; diff --git a/src/runtime/PythonPorts.hxx b/src/runtime/PythonPorts.hxx index 6fd090925..1c338b5d4 100644 --- a/src/runtime/PythonPorts.hxx +++ b/src/runtime/PythonPorts.hxx @@ -85,6 +85,7 @@ namespace YACS virtual PyObj * getPyObj() const; virtual std::string getAsString(); void *get() const throw(Exception); + virtual std::string getHumanRepr(); virtual bool isEmpty(); virtual void exSaveInit(); virtual void exRestoreInit(); -- 2.30.2