Parcourir la source

Add trace class for unit test

Eric Ramat il y a 11 ans
Parent
commit
86ffab65a5

+ 1 - 1
CMakeLists.txt

@@ -49,7 +49,7 @@ INCLUDE(CMakeCPack.cmake)
 
 IF (CMAKE_COMPILER_IS_GNUCC AND CMAKE_COMPILER_IS_GNUCXX)
   SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
-  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
+  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -std=c++11")
   IF (UNIX)
     SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic")
     SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")

+ 4 - 4
src/common/CMakeLists.txt

@@ -9,11 +9,11 @@ LINK_DIRECTORIES(
   ${GLIBMM_LIBRARY_DIRS}
   ${LIBXML_LIBRARY_DIR})
 
-SET(COMMON_CPP Builder.cpp EventTable.cpp InternalEvent.cpp Links.cpp Message.cpp
-  Node.cpp)
+SET(COMMON_CPP Builder.cpp EventTable.cpp InternalEvent.cpp Links.cpp
+  Message.cpp Node.cpp Trace.cpp)
 
-SET(COMMON_HPP Builder.hpp EventTable.hpp InternalEvent.hpp Links.hpp Message.hpp
-  Node.hpp Time.hpp)
+SET(COMMON_HPP Builder.hpp EventTable.hpp InternalEvent.hpp Links.hpp
+  Message.hpp Node.hpp Time.hpp Trace.cpp)
 
 ADD_LIBRARY(common SHARED ${COMMON_CPP};${COMMON_HPP})
 

+ 2 - 1
src/common/Message.cpp

@@ -64,7 +64,8 @@ std::string Message::to_string() const
 {
     std::ostringstream ss;
 
-    ss << "( " << _port_name << " , " << _model->get_name() << ")";
+    ss << "( " << _port_name << " , " << (_model?_model->get_name():"<>")
+       << ")";
     return ss.str();
 }
 

+ 110 - 0
src/common/Trace.cpp

@@ -0,0 +1,110 @@
+/**
+ * @file Trace.cpp
+ * @author The PARADEVS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * PARADEVS - the multimodeling and simulation environment
+ * This file is a part of the PARADEVS environment
+ *
+ * Copyright (C) 2013 ULCO http://www.univ-litoral.fr
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <common/Trace.hpp>
+
+namespace paradevs { namespace common {
+
+Trace* Trace::_instance = 0;
+
+std::string TraceElements::to_string() const
+{
+    std::ostringstream ss;
+
+    for (const_iterator it = begin(); it != end(); ++it) {
+        ss << "TRACE: " << it->get_model_name() << " at "
+           << it->get_time() << " <";
+        switch (it->get_type())
+        {
+        case NONE: ss << "none"; break;
+        case I_MESSAGE: ss << "i_message"; break;
+        case POST_MESSAGE:  ss << "post_message"; break;
+        case S_MESSAGE: ss << "s_message"; break;
+        case Y_MESSAGE: ss << "y_message"; break;
+        case DELTA_INT: ss << "delta_int"; break;
+        case DELTA_EXT: ss << "delta_ext"; break;
+        case DELTA_CONF:  ss << "delta_conf"; break;
+        case TA: ss << "ta"; break;
+        case LAMBDA: ss << "lambda"; break;
+        case START: ss << "start"; break;
+        };
+        ss << ">";
+        if (not it->get_comment().empty()) {
+            ss << " => " << it->get_comment();
+        }
+        ss << std::endl;
+    }
+    return ss.str();
+}
+
+void Trace::flush()
+{
+    if (_sstream) {
+        _element.set_comment(_sstream->str());
+        delete _sstream;
+        _sstream = 0;
+    }
+    _trace.push_back(_element);
+}
+
+std::ostringstream& Trace::sstream()
+{
+    if (_sstream == 0) {
+        _sstream = new std::ostringstream();
+    }
+    return *_sstream;
+}
+
+Trace& Trace::trace()
+{
+    if (_instance == 0) {
+        _instance = new Trace();
+    }
+    return *_instance;
+}
+
+} } // namespace paradevs common
+
+paradevs::common::Trace& operator<<(paradevs::common::Trace& trace,
+                                    const paradevs::common::TraceElement& e)
+{
+    trace.set_element(e);
+    return trace;
+}
+
+paradevs::common::Trace& operator<<(paradevs::common::Trace& trace,
+                                    const std::string& str)
+{
+    trace.sstream() << str;
+    return trace;
+}
+
+paradevs::common::Trace& operator<<(paradevs::common::Trace& trace,
+                                    paradevs::common::Time t)
+{
+    trace.sstream() << t;
+    return trace;
+}

+ 160 - 0
src/common/Trace.hpp

@@ -0,0 +1,160 @@
+/**
+ * @file Trace.hpp
+ * @author The PARADEVS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * PARADEVS - the multimodeling and simulation environment
+ * This file is a part of the PARADEVS environment
+ *
+ * Copyright (C) 2013 ULCO http://www.univ-litoral.fr
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef COMMON_TRACE
+#define COMMON_TRACE 1
+
+#include <common/Time.hpp>
+
+#include <algorithm>
+#include <iterator>
+#include <sstream>
+#include <string>
+#include <vector>
+
+namespace paradevs { namespace common {
+
+enum TraceType { NONE = 0, I_MESSAGE, POST_MESSAGE, S_MESSAGE, Y_MESSAGE,
+                 DELTA_INT, DELTA_EXT, DELTA_CONF, TA, LAMBDA, START };
+
+class TraceElement
+{
+public:
+    TraceElement() : _time(0), _type(NONE)
+    { }
+    TraceElement(const std::string& model_name, Time time, TraceType type) :
+        _model_name(model_name), _time(time), _type(type)
+    { }
+    virtual ~TraceElement()
+    { }
+
+    const std::string& get_comment() const
+    { return _comment; }
+
+    const std::string& get_model_name() const
+    { return _model_name; }
+
+    Time get_time() const
+    { return _time; }
+
+    TraceType get_type() const
+    { return _type; }
+
+    void set_comment(const std::string& comment)
+    { _comment = comment; }
+
+private:
+    std::string _model_name;
+    Time        _time;
+    TraceType   _type;
+    std::string _comment;
+};
+
+class TraceElements : public std::vector < TraceElement >
+{
+public:
+    TraceElements()
+    { }
+    virtual ~TraceElements()
+    { }
+
+    TraceElements filter_model_name(
+        const std::string& model_name) const
+    {
+        TraceElements result;
+
+        std::copy_if(begin(), end(), std::back_inserter(result),
+                     [model_name](TraceElement const & x)
+                     { return x.get_model_name() == model_name; });
+        return result;
+    }
+
+    TraceElements filter_time(Time time) const
+    {
+        TraceElements result;
+
+        std::copy_if(begin(), end(), std::back_inserter(result),
+                     [time](TraceElement const & x)
+                     { return x.get_time() == time; });
+        return result;
+    }
+
+    TraceElements filter_type(TraceType type) const
+    {
+        TraceElements result;
+
+        std::copy_if(begin(), end(), std::back_inserter(result),
+                     [type](TraceElement const & x)
+                     { return x.get_type() == type; });
+        return result;
+    }
+
+    std::string to_string() const;
+};
+
+class Trace
+{
+public:
+    static Trace& trace();
+
+    const TraceElements& elements() const
+    { return _trace; }
+
+    void flush();
+
+    void set_element(const TraceElement& element)
+    { _element = element; }
+
+    std::ostringstream& sstream();
+
+private:
+    Trace()
+    { _sstream = 0; }
+    virtual ~Trace()
+    {
+        delete _instance;
+        if (_sstream) {
+            delete _sstream;
+        }
+    }
+
+    static Trace* _instance;
+
+    TraceElements       _trace;
+    TraceElement        _element;
+    std::ostringstream* _sstream;
+};
+
+} } // namespace paradevs common
+
+paradevs::common::Trace& operator<<(paradevs::common::Trace& trace,
+                                    const paradevs::common::TraceElement& e);
+paradevs::common::Trace& operator<<(paradevs::common::Trace& trace,
+                                    const std::string& str);
+paradevs::common::Trace& operator<<(paradevs::common::Trace& trace,
+                                    paradevs::common::Time t);
+
+#endif

+ 53 - 26
src/pdevs/Coordinator.cpp

@@ -24,6 +24,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <common/Trace.hpp>
+
 #include <pdevs/Coordinator.hpp>
 #include <pdevs/Simulator.hpp>
 
@@ -44,8 +46,11 @@ Coordinator::~Coordinator()
 common::Time Coordinator::i_message(common::Time t)
 {
 
-    std::cout << "[" << get_name() << "] at " << t << ": BEFORE - i_message => "
-              << "tl = " << _tl << " ; tn = " << _tn << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::I_MESSAGE)
+                           << ": BEFORE => "
+                           << "tl = " << _tl << " ; tn = " << _tn;
+    common::Trace::trace().flush();
 
     assert(_child_list.size() > 0);
 
@@ -57,8 +62,11 @@ common::Time Coordinator::i_message(common::Time t)
     _tl = t;
     _tn = _event_table.get_current_time();
 
-    std::cout << "[" << get_name() << "] at " << t << ": AFTER - i_message => "
-              << "tl = " << _tl << " ; tn = " << _tn << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::I_MESSAGE)
+                           << ": AFTER => "
+                           << "tl = " << _tl << " ; tn = " << _tn;
+    common::Trace::trace().flush();
 
     return _tn;
 }
@@ -75,10 +83,12 @@ common::Time Coordinator::i_message(common::Time t)
 common::Time Coordinator::s_message(common::Time t)
 {
 
-    std::cout << "[" << get_name() << "] at " << t << ": BEFORE - s_message => "
-              << "tl = " << _tl << " ; tn = " << _tn << std::endl;
-    std::cout << "[" << get_name() << "]: " << _event_table.to_string()
-              << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::S_MESSAGE)
+                           << ": BEFORE => "
+                           << "tl = " << _tl << " ; tn = " << _tn
+                           << " ; scheduler = " << _event_table.to_string();
+    common::Trace::trace().flush();
 
     assert(t == _tn);
 
@@ -98,8 +108,10 @@ common::Time Coordinator::s_message(common::Time t)
         }
     }
 
-    std::cout << "[" << get_name() << "] at " << t << ": IMM = "
-              << IMM.to_string() << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::S_MESSAGE)
+                           << ": IMM = " << IMM.to_string();
+    common::Trace::trace().flush();
 
     for (Models::const_iterator it = IMM.begin(); it != IMM.end(); ++it) {
         common::Time tn = (*it)->s_message(_tn);
@@ -124,19 +136,23 @@ common::Time Coordinator::s_message(common::Time t)
         _tn = _event_table.get_current_time();
     }
 
-    std::cout << "[" << get_name() << "] at " << t << ": AFTER - s_message => "
-              << "tl = " << _tl << " ; tn = " << _tn << std::endl;
-    std::cout << "[" << get_name() << "]: " << _event_table.to_string()
-              << std::endl;
-    std::cout << "**************" << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::S_MESSAGE)
+                           << ": AFTER => "
+                           << "tl = " << _tl << " ; tn = " << _tn
+                           << " ; scheduler = " << _event_table.to_string();
+    common::Trace::trace().flush();
 
     return _tn;
 }
 
-void Coordinator::post_message(const common::Message& message)
+void Coordinator::post_message(common::Time t, const common::Message& message)
 {
 
-    std::cout << "[" << get_name() << "]: post_message" << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::POST_MESSAGE)
+                           << ": BEFORE => " << message.to_string();
+    common::Trace::trace().flush();
 
     std::pair < common::Links::iterator, common::Links::iterator > result =
         _link_list.equal_range(common::Node(message.get_port_name(), this));
@@ -145,18 +161,26 @@ void Coordinator::post_message(const common::Message& message)
          it_r != result.second; ++it_r) {
         Model* model = dynamic_cast < Model* >((*it_r).second.get_model());
 
-        model->post_message(common::Message(it_r->second.get_port_name(),
-                                            model, message.get_content()));
+        model->post_message(t, common::Message(it_r->second.get_port_name(),
+                                               model, message.get_content()));
     }
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::POST_MESSAGE)
+                           << ": AFTER => " << message.to_string();
+    common::Trace::trace().flush();
+
 }
 
 common::Time Coordinator::y_message(common::Messages messages, common::Time t)
 {
 
-    std::cout << "[" << get_name() << "] at " << t << ": BEFORE - y_message => "
-              << "tl = " << _tl << " ; tn = " << _tn << std::endl;
-    std::cout << "[" << get_name() << "] at " << t << ": "
-              << messages.to_string() << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::Y_MESSAGE)
+                           << ": BEFORE => "
+                           << "tl = " << _tl << " ; tn = " << _tn
+                           << " ; messages = " << messages.to_string();
+    common::Trace::trace().flush();
 
     if (not messages.empty()) {
         while (not messages.empty()) {
@@ -187,14 +211,17 @@ common::Time Coordinator::y_message(common::Messages messages, common::Time t)
                     common::Message message(it->second.get_port_name(),
                                             model, ymsg.get_content());
 
-                    model->post_message(message);
+                    model->post_message(t, message);
                 }
             }
         }
     }
 
-    std::cout << "[" << get_name() << "] at " << t << ": AFTER - y_message => "
-              << "tl = " << _tl << " ; tn = " << _tn << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::Y_MESSAGE)
+                           << ": BEFORE => "
+                           << "tl = " << _tl << " ; tn = " << _tn;
+    common::Trace::trace().flush();
 
     return _tn;
 }

+ 2 - 1
src/pdevs/Coordinator.hpp

@@ -54,7 +54,8 @@ public :
     virtual bool is_atomic() const
     { return false;}
 
-    virtual void post_message(const common::Message& /* message */);
+    virtual void post_message(common::Time /* t */,
+                              const common::Message& /* message */);
 
 // graph methods
     virtual void add_child(Model* child);

+ 1 - 1
src/pdevs/Dynamics.cpp

@@ -34,7 +34,7 @@ Dynamics::Dynamics(const std::string& name) : _name(name)
 Dynamics::~Dynamics()
 { }
 
-common::Messages Dynamics::lambda() const
+common::Messages Dynamics::lambda(common::Time /* time */) const
 { return common::Messages(); }
 
 } } // namespace paradevs pdevs

+ 6 - 6
src/pdevs/Dynamics.hpp

@@ -42,19 +42,19 @@ public:
     Dynamics(const std::string& name);
     virtual ~Dynamics();
 
-    virtual void dconf(const common::Time& /* e */,
+    virtual void dconf(common::Time /* t */, common::Time /* e */,
                        const common::Messages& /* msgs */)
     { }
-    virtual void dint(const common::Time& /* t */)
+    virtual void dint(common::Time /* t */)
     { }
-    virtual void dext(const common::Time& /* e */,
+    virtual void dext(common::Time /* t */, common::Time /* e */,
                       const common::Messages& /* msgs */)
     { }
-    virtual common::Time start()
+    virtual common::Time start(common::Time /* time */)
     { return std::numeric_limits < double >::max(); }
-    virtual common::Time ta() const
+    virtual common::Time ta(common::Time /* time */) const
     { return std::numeric_limits < double >::max(); }
-    virtual common::Messages lambda() const;
+    virtual common::Messages lambda(common::Time /* time */) const;
     virtual void observation(std::ostream& /* file */) const
     { }
 

+ 2 - 1
src/pdevs/Model.hpp

@@ -47,7 +47,8 @@ public:
 
     virtual bool is_atomic() const = 0;
 
-    virtual void post_message(const common::Message& /* message */) = 0;
+    virtual void post_message(common::Time /* t */,
+                              const common::Message& /* message */) = 0;
 };
 
 class Models : public std::vector < Model* >

+ 40 - 14
src/pdevs/Simulator.cpp

@@ -24,6 +24,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <common/Trace.hpp>
+
 #include <pdevs/Coordinator.hpp>
 #include <pdevs/Simulator.hpp>
 
@@ -41,8 +43,22 @@ Simulator::~Simulator()
 
 common::Time Simulator::i_message(common::Time t)
 {
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::I_MESSAGE)
+                           << ": BEFORE => "
+                           << "tl = " << _tl << " ; tn = " << _tn;
+    common::Trace::trace().flush();
+
     _tl = t;
-    _tn = _tl + _dynamics->start();
+    _tn = _tl + _dynamics->start(t);
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::I_MESSAGE)
+                           << ": AFTER => "
+                           << "tl = " << _tl << " ; tn = " << _tn;
+    common::Trace::trace().flush();
+
     return _tn;
 }
 
@@ -65,11 +81,14 @@ common::Time Simulator::i_message(common::Time t)
 common::Time Simulator::s_message(common::Time t)
 {
 
-    std::cout << "[" << get_name() << "] at " << t << ": BEFORE - s_message => "
-              << "tl = " << _tl << " ; tn = " << _tn << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::S_MESSAGE)
+                           << ": BEFORE => "
+                           << "tl = " << _tl << " ; tn = " << _tn;
+    common::Trace::trace().flush();
 
     if(t == _tn) {
-        common::Messages msgs = _dynamics->lambda();
+        common::Messages msgs = _dynamics->lambda(t);
 
         if (not msgs.empty()) {
             for (common::Messages::iterator it = msgs.begin(); it != msgs.end();
@@ -81,17 +100,20 @@ common::Time Simulator::s_message(common::Time t)
         if (message_number() == 0) {
             _dynamics->dint(t);
         } else {
-            _dynamics->dconf(t - _tl, _x_messages);
+            _dynamics->dconf(t, t - _tl, _x_messages);
         }
     } else {
-        _dynamics->dext(t - _tl, _x_messages);
+        _dynamics->dext(t, t - _tl, _x_messages);
     }
-    _tn = t + _dynamics->ta();
+    _tn = t + _dynamics->ta(t);
     _tl = t;
     clear_messages();
 
-    std::cout << "[" << get_name() << "] at " << t << ": AFTER - s_message => "
-              << "tl = " << _tl << " ; tn = " << _tn << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::S_MESSAGE)
+                           << ": AFTER => "
+                           << "tl = " << _tl << " ; tn = " << _tn;
+    common::Trace::trace().flush();
 
     return _tn;
 }
@@ -106,16 +128,20 @@ void Simulator::clear_messages()
     _x_messages.clear();
 }
 
-void Simulator::post_message(const common::Message& message)
+void Simulator::post_message(common::Time t, const common::Message& message)
 {
 
-    std::cout << "[" << get_name() << "]: [BEFORE] post_message => "
-              << message.to_string() << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::POST_MESSAGE)
+                           << ": BEFORE => " << message.to_string();
+    common::Trace::trace().flush();
 
     _x_messages.push_back(message);
 
-    std::cout << "[" << get_name() << "]: [AFTER] post_message => "
-              << _x_messages.to_string() << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::POST_MESSAGE)
+                           << ": AFTER => " << message.to_string();
+    common::Trace::trace().flush();
 
 }
 

+ 2 - 1
src/pdevs/Simulator.hpp

@@ -52,7 +52,8 @@ public :
     { return true;}
 
     virtual void clear_messages();
-    virtual void post_message(const common::Message& /* message */);
+    virtual void post_message(common::Time /* t */,
+                              const common::Message& /* message */);
     virtual bool message_number() const
     { return _x_messages.size(); }
 

+ 256 - 48
src/tests/pdevs_tests.cpp

@@ -25,6 +25,9 @@
  */
 
 #include <tests/pdevs_tests.hpp>
+
+#include <common/Trace.hpp>
+
 #include <pdevs/Coordinator.hpp>
 #include <pdevs/RootCoordinator.hpp>
 
@@ -33,44 +36,56 @@
 
 namespace paradevs { namespace pdevs {
 
-void A::dint(const common::Time& t)
+void A::dint(common::Time t)
 {
 
-    std::cout << "[ model " << get_name() << " ] dint at " << t << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::DELTA_INT);
+    common::Trace::trace().flush();
 
     if (_phase == SEND) {
         _phase = WAIT;
     }
 }
 
-void A::dext(const common::Time& /* e */, const common::Messages& msgs)
+void A::dext(common::Time t, common::Time /* e */, const common::Messages& msgs)
 {
 
-    std::cout << "[ model " << get_name() << " ] dext: "
-              << msgs.to_string() << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::DELTA_EXT)
+                           << "messages = " << msgs.to_string();
+    common::Trace::trace().flush();
 
     _phase = SEND;
 }
 
-void A::dconf(const common::Time& /* e */, const common::Messages& msgs)
+void A::dconf(common::Time t, common::Time /* e */,
+              const common::Messages& msgs)
 {
 
-    std::cout << "[ model " << get_name() << " ] dconf: "
-              << msgs.to_string() << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::DELTA_CONF)
+                           << "messages = " << msgs.to_string();
+    common::Trace::trace().flush();
 
 }
 
-common::Time A::start()
+common::Time A::start(common::Time t)
 {
-
-    std::cout << "[ model " << get_name() << " ] start" << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::START);
+    common::Trace::trace().flush();
 
     _phase = WAIT;
     return 0;
 }
 
-common::Time A::ta() const
+common::Time A::ta(common::Time t) const
 {
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::TA);
+    common::Trace::trace().flush();
+
     if (_phase == WAIT) {
         return 1;
     } else {
@@ -78,59 +93,74 @@ common::Time A::ta() const
     }
 }
 
-common::Messages A::lambda() const
+common::Messages A::lambda(common::Time t) const
 {
-
-    std::cout << "[ model " << get_name() << " ] lambda" << std::endl;
-
     common::Messages msgs;
 
     msgs.push_back(common::Message("out", 0, true));
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::LAMBDA)
+                           << "messages = " << msgs.to_string();
+    common::Trace::trace().flush();
+
     return msgs;
 }
 
 void A::observation(std::ostream& /* file */) const
 { }
 
-void B::dint(const common::Time& t)
+void B::dint(common::Time t)
 {
 
-    std::cout << "[ model " << get_name() << " ] dint at " << t
-              << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::DELTA_INT);
+    common::Trace::trace().flush();
 
     if (_phase == SEND) {
         _phase = WAIT;
     }
 }
 
-void B::dext(const common::Time& /* e */, const common::Messages& msgs)
+void B::dext(common::Time t, common::Time /* e */, const common::Messages& msgs)
 {
 
-    std::cout << "[ model " << get_name() << " ] dext: "
-              << msgs.to_string() << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::DELTA_EXT)
+                           << "messages = " << msgs.to_string();
+    common::Trace::trace().flush();
 
     _phase = SEND;
 }
 
-void B::dconf(const common::Time& /* e */, const common::Messages& msgs)
+void B::dconf(common::Time t, common::Time /* e */,
+              const common::Messages& msgs)
 {
 
-    std::cout << "[ model " << get_name() << " ] dconf: "
-              << msgs.to_string() << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::DELTA_CONF)
+                           << "messages = " << msgs.to_string();
+    common::Trace::trace().flush();
 
 }
 
-common::Time B::start()
+common::Time B::start(common::Time t)
 {
 
-    std::cout << "[ model " << get_name() << " ] start" << std::endl;
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::START);
+    common::Trace::trace().flush();
 
     _phase = WAIT;
-    return 0;
+    return std::numeric_limits < double >::max();
 }
 
-common::Time B::ta() const
+common::Time B::ta(common::Time t) const
 {
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::TA);
+    common::Trace::trace().flush();
+
     if (_phase == WAIT) {
         return std::numeric_limits < double >::max();
     } else {
@@ -138,14 +168,17 @@ common::Time B::ta() const
     }
 }
 
-common::Messages B::lambda() const
+common::Messages B::lambda(common::Time t) const
 {
-
-    std::cout << "[ model " << get_name() << " ] lambda" << std::endl;
-
     common::Messages msgs;
 
     msgs.push_back(common::Message("out", 0, true));
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::LAMBDA)
+                           << "messages = " << msgs.to_string();
+    common::Trace::trace().flush();
+
     return msgs;
 }
 
@@ -212,14 +245,34 @@ common::Model* FlatBuilder::build() const
 
 } } // namespace paradevs pdevs
 
-// TEST_CASE("pdevs/only_one", "run")
-// {
-//     paradevs::pdevs::OnlyOneBuilder builder;
-//     paradevs::pdevs::RootCoordinator rc(0, 10, builder);
+TEST_CASE("pdevs/only_one", "run")
+{
+    paradevs::pdevs::OnlyOneBuilder builder;
+    paradevs::pdevs::RootCoordinator rc(0, 10, builder);
 
-//     rc.run();
-//     REQUIRE(true);
-// }
+    rc.run();
+
+    REQUIRE(paradevs::common::Trace::trace().elements().
+            filter_model_name("a").
+            filter_type(paradevs::common::START).size() == 1);
+    REQUIRE(paradevs::common::Trace::trace().elements().
+            filter_model_name("a").
+            filter_type(paradevs::common::DELTA_EXT).size() == 0);
+    REQUIRE(paradevs::common::Trace::trace().elements().
+            filter_model_name("a").
+            filter_type(paradevs::common::DELTA_CONF).size() == 0);
+    for (unsigned int t = 0; t <= 10; ++t) {
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a").filter_time(t).
+                filter_type(paradevs::common::DELTA_INT).size() == 1);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a").filter_time(t).
+                filter_type(paradevs::common::TA).size() == 1);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a").filter_time(t).
+                filter_type(paradevs::common::LAMBDA).size() == 1);
+    }
+}
 
 TEST_CASE("pdevs/flat", "run")
 {
@@ -227,14 +280,169 @@ TEST_CASE("pdevs/flat", "run")
     paradevs::pdevs::RootCoordinator rc(0, 10, builder);
 
     rc.run();
-    REQUIRE(true);
+
+    REQUIRE(paradevs::common::Trace::trace().elements().
+            filter_model_name("a1").
+            filter_type(paradevs::common::START).size() == 1);
+    REQUIRE(paradevs::common::Trace::trace().elements().
+            filter_model_name("b1").
+            filter_type(paradevs::common::START).size() == 1);
+    REQUIRE(paradevs::common::Trace::trace().elements().
+            filter_model_name("a2").
+            filter_type(paradevs::common::START).size() == 1);
+    REQUIRE(paradevs::common::Trace::trace().elements().
+            filter_model_name("b2").
+            filter_type(paradevs::common::START).size() == 1);
+
+    REQUIRE(paradevs::common::Trace::trace().elements().
+            filter_type(paradevs::common::DELTA_CONF).size() == 0);
+
+    REQUIRE(paradevs::common::Trace::trace().elements().
+            filter_model_name("a1").
+            filter_type(paradevs::common::DELTA_EXT).size() == 0);
+    for (unsigned int t = 0; t <= 10; ++t) {
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a1").filter_time(t).
+                filter_type(paradevs::common::LAMBDA).size() == 1);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a1").filter_time(t).
+                filter_type(paradevs::common::DELTA_INT).size() == 1);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a1").filter_time(t).
+                filter_type(paradevs::common::TA).size() == 1);
+    }
+
+    for (unsigned int t = 0; t <= 10; ++t) {
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b1").filter_time(t).
+                filter_type(paradevs::common::LAMBDA).size() == 1);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b1").filter_time(t).
+                filter_type(paradevs::common::DELTA_INT).size() == 1);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b1").filter_time(t).
+                filter_type(paradevs::common::TA).size() == 2);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b1").filter_time(t).
+                filter_type(paradevs::common::DELTA_EXT).size() == 1);
+    }
+
+    for (unsigned int t = 0; t <= 10; ++t) {
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a2").filter_time(t).
+                filter_type(paradevs::common::LAMBDA).size() == 2);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a2").filter_time(t).
+                filter_type(paradevs::common::DELTA_INT).size() == 2);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a2").filter_time(t).
+                filter_type(paradevs::common::TA).size() == 3);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a2").filter_time(t).
+                filter_type(paradevs::common::DELTA_EXT).size() == 1);
+    }
+
+    for (unsigned int t = 0; t <= 10; ++t) {
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b2").filter_time(t).
+                filter_type(paradevs::common::LAMBDA).size() == 2);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b2").filter_time(t).
+                filter_type(paradevs::common::DELTA_INT).size() == 2);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b2").filter_time(t).
+                filter_type(paradevs::common::TA).size() == 4);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b2").filter_time(t).
+                filter_type(paradevs::common::DELTA_EXT).size() == 2);
+    }
 }
 
-// TEST_CASE("pdevs/hierachical", "run")
-// {
-//     paradevs::pdevs::HierachicalBuilder builder;
-//     paradevs::pdevs::RootCoordinator rc(0, 10, builder);
+TEST_CASE("pdevs/hierachical", "run")
+{
+    paradevs::pdevs::HierachicalBuilder builder;
+    paradevs::pdevs::RootCoordinator rc(0, 10, builder);
+
+    rc.run();
 
-//     rc.run();
-//     REQUIRE(true);
-// }
+    std::cout << paradevs::common::Trace::trace().elements().
+        filter_model_name("b1").
+        filter_type(paradevs::common::I_MESSAGE).to_string()
+              << std::endl;
+
+    REQUIRE(paradevs::common::Trace::trace().elements().
+            filter_model_name("a1").
+            filter_type(paradevs::common::START).size() == 1);
+    REQUIRE(paradevs::common::Trace::trace().elements().
+            filter_model_name("b1").
+            filter_type(paradevs::common::START).size() == 1);
+    REQUIRE(paradevs::common::Trace::trace().elements().
+            filter_model_name("a2").
+            filter_type(paradevs::common::START).size() == 1);
+    REQUIRE(paradevs::common::Trace::trace().elements().
+            filter_model_name("b2").
+            filter_type(paradevs::common::START).size() == 1);
+
+    REQUIRE(paradevs::common::Trace::trace().elements().
+            filter_type(paradevs::common::DELTA_CONF).size() == 0);
+
+    REQUIRE(paradevs::common::Trace::trace().elements().
+            filter_model_name("a1").
+            filter_type(paradevs::common::DELTA_EXT).size() == 0);
+    for (unsigned int t = 0; t <= 10; ++t) {
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a1").filter_time(t).
+                filter_type(paradevs::common::LAMBDA).size() == 1);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a1").filter_time(t).
+                filter_type(paradevs::common::DELTA_INT).size() == 1);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a1").filter_time(t).
+                filter_type(paradevs::common::TA).size() == 1);
+    }
+
+    for (unsigned int t = 0; t <= 10; ++t) {
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b1").filter_time(t).
+                filter_type(paradevs::common::LAMBDA).size() == 1);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b1").filter_time(t).
+                filter_type(paradevs::common::DELTA_INT).size() == 1);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b1").filter_time(t).
+                filter_type(paradevs::common::TA).size() == 2);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b1").filter_time(t).
+                filter_type(paradevs::common::DELTA_EXT).size() == 1);
+    }
+
+    for (unsigned int t = 0; t <= 10; ++t) {
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a2").filter_time(t).
+                filter_type(paradevs::common::LAMBDA).size() == 2);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a2").filter_time(t).
+                filter_type(paradevs::common::DELTA_INT).size() == 2);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a2").filter_time(t).
+                filter_type(paradevs::common::TA).size() == 3);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a2").filter_time(t).
+                filter_type(paradevs::common::DELTA_EXT).size() == 1);
+    }
+
+    for (unsigned int t = 0; t <= 10; ++t) {
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b2").filter_time(t).
+                filter_type(paradevs::common::LAMBDA).size() == 2);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b2").filter_time(t).
+                filter_type(paradevs::common::DELTA_INT).size() == 2);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b2").filter_time(t).
+                filter_type(paradevs::common::TA).size() == 4);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b2").filter_time(t).
+                filter_type(paradevs::common::DELTA_EXT).size() == 2);
+    }
+}

+ 12 - 12
src/tests/pdevs_tests.hpp

@@ -38,14 +38,14 @@ public:
     virtual ~A()
     { }
 
-    virtual void dint(const common::Time& t);
-    virtual void dext(const common::Time& /* e */,
+    virtual void dint(common::Time /* t */);
+    virtual void dext(common::Time /* t */, common::Time /* e */,
                       const common::Messages& /* msgs */);
-    virtual void dconf(const common::Time& /* e */,
+    virtual void dconf(common::Time /* t */, common::Time /* e */,
                        const common::Messages& /* msgs */);
-    virtual common::Time start();
-    virtual common::Time ta() const;
-    virtual common::Messages lambda() const;
+    virtual common::Time start(common::Time /* t */);
+    virtual common::Time ta(common::Time /* t */) const;
+    virtual common::Messages lambda(common::Time /* t */) const;
     virtual void observation(std::ostream& /* file */) const;
 
 private:
@@ -62,14 +62,14 @@ public:
     virtual ~B()
     { }
 
-    virtual void dint(const common::Time& t);
-    virtual void dext(const common::Time& /* e */,
+    virtual void dint(common::Time /* t */);
+    virtual void dext(common::Time /* t */, common::Time /* e */,
                       const common::Messages& /* msgs */);
-    virtual void dconf(const common::Time& /* e */,
+    virtual void dconf(common::Time /* t */, common::Time /* e */,
                        const common::Messages& /* msgs */);
-    virtual common::Time start();
-    virtual common::Time ta() const;
-    virtual common::Messages lambda() const;
+    virtual common::Time start(common::Time /* t */);
+    virtual common::Time ta(common::Time /* t */) const;
+    virtual common::Messages lambda(common::Time /* t */) const;
     virtual void observation(std::ostream& /* file */) const;
 
 private: