diff --git a/Tests/BlackBoxTests/Fixtures/FixturePetriNet.cpp b/Tests/BlackBoxTests/Fixtures/FixturePetriNet.cpp index 9f1339b..9242d5d 100644 --- a/Tests/BlackBoxTests/Fixtures/FixturePetriNet.cpp +++ b/Tests/BlackBoxTests/Fixtures/FixturePetriNet.cpp @@ -137,3 +137,36 @@ void FixturePetriNet::testWeightedState(const size_t expectedTokens[s_numberOfWe } } + + +void FixturePetriNet::testInhibitedState(const size_t expectedTokens[s_numberOfInhibitedNetPlaces]) +{ + if(!m_dispatcher) + { + throw runtime_error("No dispatcher available"); + } + + size_t tokens[s_numberOfInhibitedNetPlaces]; + + //TODO + //Dangerous(ugly) cast necessary only for testing. This does not need to exist within a normal use case. + //Nonetheless it would be nice to fix it. + Dispatcher::IDispatcherPetriNet *dispatcherPetriNet = m_dispatcher->m_pPetriNet.get(); + + if(Dispatcher::InhibitedPetriNet* weightedPetriNet = dynamic_cast(dispatcherPetriNet)) + { + tokens[0] = weightedPetriNet->getNumberOfTokens("InputWaitPackage"); + tokens[1] = weightedPetriNet->getNumberOfTokens("P1"); + tokens[2] = weightedPetriNet->getNumberOfTokens("P2"); + tokens[3] = weightedPetriNet->getNumberOfTokens("P3"); + tokens[4] = weightedPetriNet->getNumberOfTokens("P4"); + tokens[5] = weightedPetriNet->getNumberOfTokens("P5"); + } + + for(size_t i = 0; i < s_numberOfInhibitedNetPlaces; ++i ) + { + size_t a = expectedTokens[i]; + EXPECT_EQ(a, tokens[i]); + } + +} diff --git a/Tests/BlackBoxTests/Fixtures/FixturePetriNet.h b/Tests/BlackBoxTests/Fixtures/FixturePetriNet.h index 8123dae..3e5dc6b 100644 --- a/Tests/BlackBoxTests/Fixtures/FixturePetriNet.h +++ b/Tests/BlackBoxTests/Fixtures/FixturePetriNet.h @@ -39,6 +39,9 @@ class FixturePetriNet: public ::testing::Test //! Total number of places in the net. const static size_t s_numberOfWeightedPlaces = 4; + //! Total number of places in the net. + const static size_t s_numberOfInhibitedNetPlaces = 6; + //! Constructor. FixturePetriNet(); @@ -60,6 +63,12 @@ class FixturePetriNet: public ::testing::Test */ void testWeightedState(const size_t expectedTokens[s_numberOfWeightedPlaces]); + /*! + * Tests the number of tokens in all places of the net. + * \param expectedTokens Expected number of tokens in each place. + */ + void testInhibitedState(const size_t expectedTokens[s_numberOfInhibitedNetPlaces]); + //! Controller containing the PTN Engine net. std::shared_ptr m_dispatcher; diff --git a/Tests/BlackBoxTests/Mocks/Dispatcher.cpp b/Tests/BlackBoxTests/Mocks/Dispatcher.cpp index d2af3b0..56cdd64 100755 --- a/Tests/BlackBoxTests/Mocks/Dispatcher.cpp +++ b/Tests/BlackBoxTests/Mocks/Dispatcher.cpp @@ -120,20 +120,28 @@ void Dispatcher::setRoundRobinMode() { m_pPetriNet = move( PtrRoundRobinPetriNet(new RoundRobinPetriNet(shared_from_this())) - ); + ); } void Dispatcher::setFreeChoiceMode() { m_pPetriNet = move( - PtrFreeChoicePetriNet(new FreeChoicePetriNet(shared_from_this())) - ); + PtrFreeChoicePetriNet(new FreeChoicePetriNet(shared_from_this())) + ); } void Dispatcher::setWeightedPN() { m_pPetriNet = move( - PtrWeightedPetriNet(new WeightedPetriNet(shared_from_this())) - ); + PtrWeightedPetriNet(new WeightedPetriNet(shared_from_this())) + ); } +void Dispatcher::setInhibitedPN() +{ + m_pPetriNet = move( + PtrInhibitedPetriNet(new InhibitedPetriNet(shared_from_this())) + ); +} + + diff --git a/Tests/BlackBoxTests/Mocks/Dispatcher.h b/Tests/BlackBoxTests/Mocks/Dispatcher.h index bbfd3dc..ff76942 100755 --- a/Tests/BlackBoxTests/Mocks/Dispatcher.h +++ b/Tests/BlackBoxTests/Mocks/Dispatcher.h @@ -47,6 +47,9 @@ class Dispatcher: public std::enable_shared_from_this //! Petri net using weighted arcs. class WeightedPetriNet; + //! Petri net using inhibitor arcs. + class InhibitedPetriNet; + //! For testing purposes only friend class FixturePetriNet; @@ -89,7 +92,7 @@ class Dispatcher: public std::enable_shared_from_this using PtrRoundRobinPetriNet = std::unique_ptr; using PtrFreeChoicePetriNet = std::unique_ptr; using PtrWeightedPetriNet = std::unique_ptr; - + using PtrInhibitedPetriNet = std::unique_ptr; //! Petri net that defines and controls the dispatcher business logic. std::unique_ptr m_pPetriNet; @@ -143,6 +146,9 @@ class Dispatcher: public std::enable_shared_from_this //! Select weighted Petri net. void setWeightedPN(); + //! Select inhibited Petri net. + void setInhibitedPN(); + }; template class ptne::Action; @@ -154,3 +160,4 @@ using DispatcherFireCondition = ptne::ActivationCondition; #include "Mocks/RoundRobinPetriNet.h" #include "Mocks/FreeChoicePetriNet.h" #include "Mocks/WeightedPetriNet.h" +#include "Mocks/InhibitedPetriNet.h" diff --git a/Tests/BlackBoxTests/Mocks/InhibitedPetriNet.cpp b/Tests/BlackBoxTests/Mocks/InhibitedPetriNet.cpp new file mode 100755 index 0000000..9a5623c --- /dev/null +++ b/Tests/BlackBoxTests/Mocks/InhibitedPetriNet.cpp @@ -0,0 +1,77 @@ +/* + * This file is part of PTN Engine + * + * Copyright (c) 2017 Eduardo Valgôde + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Mocks/InhibitedPetriNet.h" +#include "PTN_Engine/Place.h" + + +using namespace ptne; +using namespace std; + +Dispatcher::InhibitedPetriNet::InhibitedPetriNet(shared_ptr ptrDispatcher): + PTN_Engine{} +{ + + //Places + addPlace("InputWaitPackage", 0, nullptr, nullptr, true); + + addPlace("P1",1, nullptr, nullptr); + addPlace("P2",1, nullptr, nullptr); + addPlace("P3",1, nullptr, nullptr); + addPlace("P4",0, nullptr, nullptr); + addPlace("P5",0, nullptr, nullptr); + + //Transitions + + + createTransition( + {"InputWaitPackage", "P1", "P3"}, //activation + {"P4"}, //destination + {} //additional conditions + ); + + + createTransition( + {"P2"}, //activation + {"P5"}, //destination + {}, //additional conditions + {"P3"} //inhibitor arc + ); + + + createTransition( + {"InputWaitPackage", "P4"}, //activation + {"P1", "P3"}, //destination + {} //additional conditions + ); + + + createTransition( + {"P5"}, //activation + {"P2"}, //destination + {}, //additional conditions + {"P4"} //inhibitor arc + ); + +} + +void Dispatcher::InhibitedPetriNet::dispatch() +{ + incrementInputPlace("InputWaitPackage"); + execute(); +} diff --git a/Tests/BlackBoxTests/Mocks/InhibitedPetriNet.h b/Tests/BlackBoxTests/Mocks/InhibitedPetriNet.h new file mode 100644 index 0000000..d719888 --- /dev/null +++ b/Tests/BlackBoxTests/Mocks/InhibitedPetriNet.h @@ -0,0 +1,47 @@ +/* + * This file is part of PTN Engine + * + * Copyright (c) 2017 Eduardo Valgôde + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "Mocks/Dispatcher.h" +#include "Mocks/IDispatcherPetriNet.h" +#include "PTN_Engine/PTN_Engine.h" + +//! Implements PTN Engine net with a Petri net that uses the inhibitor arc. +/*! + * The behaviour is defined in the constructor. + */ +class Dispatcher::InhibitedPetriNet: + public IDispatcherPetriNet, + private ptne::PTN_Engine +{ + //For testing purposes. + friend class FixturePetriNet; + +public: + + /*! + * Constructor. + * \param ptrDispatcher Shared pointer to the dispatcher. + */ + InhibitedPetriNet(std::shared_ptr ptrDispatcher); + + //! Trigger the dispatch process. + void dispatch() override; + +}; diff --git a/Tests/BlackBoxTests/Tests/TestPetriNet.cpp b/Tests/BlackBoxTests/Tests/TestPetriNet.cpp index 96ac889..9331be7 100644 --- a/Tests/BlackBoxTests/Tests/TestPetriNet.cpp +++ b/Tests/BlackBoxTests/Tests/TestPetriNet.cpp @@ -104,3 +104,25 @@ TEST_F(FixturePetriNet, Weights_1) } +TEST_F(FixturePetriNet, Inhibited_1) +{ + if(!m_dispatcher) + { + throw std::runtime_error("No dispatcher available"); + } + + m_dispatcher->setResetCounter(true); + m_dispatcher->setInhibitedPN(); + + m_dispatcher->dispatch(); + + size_t expectedState[6] = {0,0,0,0,1,1}; + testInhibitedState(expectedState); + + m_dispatcher->dispatch(); + + size_t expectedState_[6] = {0,1,1,1,0,0}; + testInhibitedState(expectedState_); + +} +