Parcourir la source

Add mixed tests (pdevs + dtss)

Eric Ramat il y a 11 ans
Parent
commit
2c6cbd44a8
5 fichiers modifiés avec 486 ajouts et 3 suppressions
  1. 7 2
      src/common/Model.cpp
  2. 1 1
      src/common/Model.hpp
  3. 11 0
      src/tests/CMakeLists.txt
  4. 347 0
      src/tests/mixed_tests.cpp
  5. 120 0
      src/tests/mixed_tests.hpp

+ 7 - 2
src/common/Model.cpp

@@ -49,8 +49,13 @@ void Model::add_event(const common::ExternalEvent& message)
     _inputs->push_back(message);
 }
 
-const common::Bag& Model::get_bag() const
-{ return *_inputs; }
+const common::Bag& Model::get_bag()
+{
+    if (_inputs == 0) {
+        _inputs = new Bag;
+    }
+    return *_inputs;
+}
 
 void Model::clear_bag()
 {

+ 1 - 1
src/common/Model.hpp

@@ -63,7 +63,7 @@ public:
 
     void add_event(const common::ExternalEvent& event);
     void clear_bag();
-    const common::Bag& get_bag() const;
+    const common::Bag& get_bag();
     unsigned int event_number() const;
 
 protected:

+ 11 - 0
src/tests/CMakeLists.txt

@@ -30,3 +30,14 @@ TARGET_LINK_LIBRARIES(dtss-tests
   ${LIBXML_LIBRARIES}
   ${GTHREAD_LIBRARIES}
   ${Boost_FILESYSTEM_LIBRARY})
+
+# mixed tests
+ADD_EXECUTABLE(mixed-tests mixed_tests.hpp mixed_tests.cpp)
+SET_TARGET_PROPERTIES(mixed-tests PROPERTIES ${PARADEVS_APP_PROPERTIES})
+
+TARGET_LINK_LIBRARIES(mixed-tests
+  common dtss pdevs
+  ${GLIBMM_LIBRARIES}
+  ${LIBXML_LIBRARIES}
+  ${GTHREAD_LIBRARIES}
+  ${Boost_FILESYSTEM_LIBRARY})

+ 347 - 0
src/tests/mixed_tests.cpp

@@ -0,0 +1,347 @@
+/**
+ * @file examples.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 <tests/mixed_tests.hpp>
+
+#include <common/RootCoordinator.hpp>
+#include <common/Trace.hpp>
+
+#include <dtss/Coordinator.hpp>
+#include <pdevs/Coordinator.hpp>
+
+#define CATCH_CONFIG_MAIN
+#include "catch.hpp"
+
+namespace paradevs {
+
+void A1::dint(common::Time t)
+{
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::DELTA_INT);
+    common::Trace::trace().flush();
+
+    if (_phase == SEND) {
+        _phase = WAIT;
+    }
+}
+
+void A1::dext(common::Time t, common::Time /* e */, const common::Bag& msgs)
+{
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::DELTA_EXT)
+                           << "messages = " << msgs.to_string();
+    common::Trace::trace().flush();
+
+    _phase = SEND;
+}
+
+void A1::dconf(common::Time t, common::Time /* e */,
+              const common::Bag& msgs)
+{
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::DELTA_CONF)
+                           << "messages = " << msgs.to_string();
+    common::Trace::trace().flush();
+
+}
+
+common::Time A1::start(common::Time t)
+{
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::START);
+    common::Trace::trace().flush();
+
+    _phase = WAIT;
+    return 0;
+}
+
+common::Time A1::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 {
+        return 0;
+    }
+}
+
+common::Bag A1::lambda(common::Time t) const
+{
+    common::Bag msgs;
+
+    msgs.push_back(common::ExternalEvent("out", 0, true));
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::LAMBDA)
+                           << "messages = " << msgs.to_string();
+    common::Trace::trace().flush();
+
+    return msgs;
+}
+
+void B1::dint(common::Time t)
+{
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::DELTA_INT);
+    common::Trace::trace().flush();
+
+    if (_phase == SEND) {
+        _phase = WAIT;
+    }
+}
+
+void B1::dext(common::Time t, common::Time /* e */, const common::Bag& msgs)
+{
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::DELTA_EXT)
+                           << "messages = " << msgs.to_string();
+    common::Trace::trace().flush();
+
+    _phase = SEND;
+}
+
+void B1::dconf(common::Time t, common::Time /* e */,
+              const common::Bag& msgs)
+{
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::DELTA_CONF)
+                           << "messages = " << msgs.to_string();
+    common::Trace::trace().flush();
+
+}
+
+common::Time B1::start(common::Time t)
+{
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::START);
+    common::Trace::trace().flush();
+
+    _phase = WAIT;
+    return std::numeric_limits < double >::max();
+}
+
+common::Time B1::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 {
+        return 0;
+    }
+}
+
+common::Bag B1::lambda(common::Time t) const
+{
+    common::Bag msgs;
+
+    msgs.push_back(common::ExternalEvent("out", 0, true));
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::LAMBDA)
+                           << "messages = " << msgs.to_string();
+    common::Trace::trace().flush();
+
+    return msgs;
+}
+
+void A2::transition(const common::Bag& x, common::Time t)
+{
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::DELTA_INT)
+                           << "x = " << x.to_string();
+    common::Trace::trace().flush();
+}
+
+common::Time A2::start(common::Time t)
+{
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::START);
+    common::Trace::trace().flush();
+
+    return 0;
+}
+
+common::Bag A2::lambda(common::Time t) const
+{
+    common::Bag msgs;
+
+    msgs.push_back(common::ExternalEvent("out", 0, true));
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::LAMBDA)
+                           << "messages = " << msgs.to_string();
+    common::Trace::trace().flush();
+
+    return msgs;
+}
+
+void B2::transition(const common::Bag& x, common::Time t)
+{
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::DELTA_INT)
+                           << "x = " << x.to_string();
+    common::Trace::trace().flush();
+}
+
+common::Time B2::start(common::Time t)
+{
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::START);
+    common::Trace::trace().flush();
+
+    return 0;
+}
+
+common::Bag B2::lambda(common::Time t) const
+{
+    common::Bag msgs;
+
+    msgs.push_back(common::ExternalEvent("out", 0, true));
+
+    common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                   common::LAMBDA)
+                           << "messages = " << msgs.to_string();
+    common::Trace::trace().flush();
+
+    return msgs;
+}
+
+common::Model* HierachicalBuilder::build() const
+{
+    pdevs::Coordinator* root = new pdevs::Coordinator("root");
+
+    pdevs::Coordinator* S1 = new pdevs::Coordinator("S1");
+    {
+        pdevs::Simulator* a = new pdevs::Simulator(new A1("a1"));
+        pdevs::Simulator* b = new pdevs::Simulator(new B1("b1"));
+
+        S1->add_child(a);
+        S1->add_child(b);
+        S1->add_link(common::Node("out", a), common::Node("in", b));
+        S1->add_link(common::Node("out", b), common::Node("out", S1));
+    }
+
+    dtss::Coordinator* S2 = new dtss::Coordinator("S2", 1);
+    {
+        dtss::Simulator* a = new dtss::Simulator(new A2("a2"), 1);
+        dtss::Simulator* b = new dtss::Simulator(new B2("b2"), 1);
+
+        S2->add_child(a);
+        S2->add_child(b);
+        S2->add_link(common::Node("out", a), common::Node("in", b));
+        S2->add_link(common::Node("in", S2), common::Node("in", a));
+    }
+    root->add_child(S1);
+    root->add_child(S2);
+    root->add_link(common::Node("out", S1), common::Node("in", S2));
+    return root;
+}
+
+} // namespace paradevs
+
+TEST_CASE("mixed/hierachical", "run")
+{
+    paradevs::HierachicalBuilder builder;
+    paradevs::common::RootCoordinator rc(0, 10, builder);
+
+    paradevs::common::Trace::trace().clear();
+    rc.run();
+
+    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_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() == 1);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("a2").filter_time(t).
+                filter_type(paradevs::common::DELTA_INT).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() == 1);
+        REQUIRE(paradevs::common::Trace::trace().elements().
+                filter_model_name("b2").filter_time(t).
+                filter_type(paradevs::common::DELTA_INT).size() == 1);
+    }
+}

+ 120 - 0
src/tests/mixed_tests.hpp

@@ -0,0 +1,120 @@
+/**
+ * @file mixed_examples.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/>.
+ */
+
+#include <common/Builder.hpp>
+
+#include <dtss/Dynamics.hpp>
+#include <dtss/Simulator.hpp>
+
+#include <pdevs/Dynamics.hpp>
+#include <pdevs/Simulator.hpp>
+
+namespace paradevs {
+
+class A1 : public paradevs::pdevs::Dynamics
+{
+public:
+    A1(const std::string& name) : paradevs::pdevs::Dynamics(name)
+    { }
+    virtual ~A1()
+    { }
+
+    virtual void dint(common::Time /* t */);
+    virtual void dext(common::Time /* t */, common::Time /* e */,
+                      const common::Bag& /* msgs */);
+    virtual void dconf(common::Time /* t */, common::Time /* e */,
+                       const common::Bag& /* msgs */);
+    virtual common::Time start(common::Time /* t */);
+    virtual common::Time ta(common::Time /* t */) const;
+    virtual common::Bag lambda(common::Time /* t */) const;
+
+private:
+    enum Phase { WAIT, SEND };
+
+    Phase _phase;
+};
+
+class B1 : public paradevs::pdevs::Dynamics
+{
+public:
+    B1(const std::string& name) : paradevs::pdevs::Dynamics(name)
+    { }
+    virtual ~B1()
+    { }
+
+    virtual void dint(common::Time /* t */);
+    virtual void dext(common::Time /* t */, common::Time /* e */,
+                      const common::Bag& /* msgs */);
+    virtual void dconf(common::Time /* t */, common::Time /* e */,
+                       const common::Bag& /* msgs */);
+    virtual common::Time start(common::Time /* t */);
+    virtual common::Time ta(common::Time /* t */) const;
+    virtual common::Bag lambda(common::Time /* t */) const;
+
+private:
+    enum Phase { WAIT, SEND };
+
+    Phase _phase;
+};
+
+class A2 : public paradevs::dtss::Dynamics
+{
+public:
+    A2(const std::string& name) : paradevs::dtss::Dynamics(name)
+    { }
+    virtual ~A2()
+    { }
+
+    virtual void transition(const common::Bag& /* x */, common::Time /* t */);
+    virtual common::Time start(common::Time /* t */);
+    virtual common::Bag lambda(common::Time /* t */) const;
+};
+
+class B2 : public paradevs::dtss::Dynamics
+{
+public:
+    B2(const std::string& name) : paradevs::dtss::Dynamics(name)
+    { }
+    virtual ~B2()
+    { }
+
+    virtual void transition(const common::Bag& /* x */, common::Time /* t */);
+    virtual common::Time start(common::Time /* t */);
+    virtual common::Bag lambda(common::Time /* t */) const;
+};
+
+class HierachicalBuilder : public common::Builder
+{
+public:
+    HierachicalBuilder()
+    { }
+    virtual ~HierachicalBuilder()
+    { }
+
+    virtual common::Model* build() const;
+};
+
+} // namespace paradevs