diff --git a/fairmq/docs/Device.md b/fairmq/docs/Device.md index 305b2c22..4c093179 100644 --- a/fairmq/docs/Device.md +++ b/fairmq/docs/Device.md @@ -45,4 +45,8 @@ Without the interactive mode, for example for a run in background, two other con - static (`--control static`) - device goes through a simple init -> run -> reset -> exit chain. - dds (`--control dds`) - device is controled by external command, in this case using dds commands (fairmq-dds-command-ui). +## 1.4 Multiple devices in the same process + +Technically one can create two or more devices within the same process without any conflicts. However the configuration (FairMQProgOptions) currently assumes the supplied configuration values are for one device/process. + ← [Back](../README.md) diff --git a/fairmq/test/CMakeLists.txt b/fairmq/test/CMakeLists.txt index 45b559dc..22ef519f 100644 --- a/fairmq/test/CMakeLists.txt +++ b/fairmq/test/CMakeLists.txt @@ -64,6 +64,19 @@ add_testsuite(FairMQ.Parts TIMEOUT 5 ) +add_testsuite(FairMQ.Device + SOURCES + device/TestSender.h + device/TestReceiver.h + device/runner.cxx + device/_multiple_devices.cxx + + LINKS FairMQ + INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/device + TIMEOUT 5 + RUN_SERIAL ON +) + ############################## # Aggregate all test targets # ############################## diff --git a/fairmq/test/device/TestReceiver.h b/fairmq/test/device/TestReceiver.h new file mode 100644 index 00000000..a00eabd5 --- /dev/null +++ b/fairmq/test/device/TestReceiver.h @@ -0,0 +1,62 @@ +/******************************************************************************** + * Copyright (C) 2015-2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * + * * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence (LGPL) version 3, * + * copied verbatim in the file "LICENSE" * + ********************************************************************************/ + +#ifndef FAIR_MQ_TEST_TESTRECEIVER_H +#define FAIR_MQ_TEST_TESTRECEIVER_H + +#include +#include + +#include + +namespace fair +{ +namespace mq +{ +namespace test +{ + +class Receiver : public FairMQDevice +{ + public: + Receiver(const std::string& channelName) + : fChannelName(channelName) + {} + + protected: + auto Init() -> void override + { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + + auto Reset() -> void override + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + auto Run() -> void override + { + auto msg = FairMQMessagePtr{NewMessage()}; + if (Receive(msg, fChannelName) >= 0) + { + LOG(INFO) << "received empty message"; + } + else + { + LOG(ERROR) << "fair::mq::test::Receiver::Run(): Receive(msg, fChannelName) < 0"; + } + }; + + std::string fChannelName; +}; + +} // namespace test +} // namespace mq +} // namespace fair + +#endif // FAIR_MQ_TEST_TESTRECEIVER_H diff --git a/fairmq/test/device/TestSender.h b/fairmq/test/device/TestSender.h new file mode 100644 index 00000000..d1ca44b3 --- /dev/null +++ b/fairmq/test/device/TestSender.h @@ -0,0 +1,62 @@ +/******************************************************************************** + * Copyright (C) 2015-2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * + * * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence (LGPL) version 3, * + * copied verbatim in the file "LICENSE" * + ********************************************************************************/ + +#ifndef FAIR_MQ_TEST_TESTSENDER_H +#define FAIR_MQ_TEST_TESTSENDER_H + +#include +#include + +#include + +namespace fair +{ +namespace mq +{ +namespace test +{ + +class Sender : public FairMQDevice +{ + public: + Sender(const std::string& channelName) + : fChannelName(channelName) + {} + + protected: + auto Init() -> void override + { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + + auto Reset() -> void override + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + auto Run() -> void override + { + auto msg = FairMQMessagePtr{NewMessage()}; + if (Send(msg, fChannelName) >= 0) + { + LOG(INFO) << "sent empty message"; + } + else + { + LOG(ERROR) << "fair::mq::test::Sender::Run(): Send(msg, fChannelName) < 0"; + } + }; + + std::string fChannelName; +}; + +} // namespace test +} // namespace mq +} // namespace fair + +#endif // FAIR_MQ_TEST_TESTSENDER_H diff --git a/fairmq/test/device/_multiple_devices.cxx b/fairmq/test/device/_multiple_devices.cxx new file mode 100644 index 00000000..af3269a2 --- /dev/null +++ b/fairmq/test/device/_multiple_devices.cxx @@ -0,0 +1,96 @@ +/******************************************************************************** + * Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * + * * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence (LGPL) version 3, * + * copied verbatim in the file "LICENSE" * + ********************************************************************************/ + +#include "TestSender.h" +#include "TestReceiver.h" + +#include + +#include +#include // std::async, std::future + +namespace +{ + +using namespace std; + +class MultipleDevices : public ::testing::Test { + public: + MultipleDevices() + {} + + bool TestFirst() + { + fair::mq::test::Sender sender("data"); + + sender.SetTransport("zeromq"); + + FairMQChannel channel("push", "connect", "ipc://multiple-devices-test"); + channel.UpdateRateLogging(0); + sender.fChannels["data"].push_back(channel); + + sender.ChangeState("INIT_DEVICE"); + sender.WaitForEndOfState("INIT_DEVICE"); + sender.ChangeState("INIT_TASK"); + sender.WaitForEndOfState("INIT_TASK"); + + sender.ChangeState("RUN"); + sender.WaitForEndOfState("RUN"); + + sender.ChangeState("RESET_TASK"); + sender.WaitForEndOfState("RESET_TASK"); + sender.ChangeState("RESET_DEVICE"); + sender.WaitForEndOfState("RESET_DEVICE"); + + sender.ChangeState("END"); + + return true; + } + + bool TestSecond() + { + fair::mq::test::Receiver receiver("data"); + + receiver.SetTransport("zeromq"); + + FairMQChannel channel("pull", "bind", "ipc://multiple-devices-test"); + channel.UpdateRateLogging(0); + receiver.fChannels["data"].push_back(channel); + + receiver.ChangeState("INIT_DEVICE"); + receiver.WaitForEndOfState("INIT_DEVICE"); + receiver.ChangeState("INIT_TASK"); + receiver.WaitForEndOfState("INIT_TASK"); + + receiver.ChangeState("RUN"); + receiver.WaitForEndOfState("RUN"); + + receiver.ChangeState("RESET_TASK"); + receiver.WaitForEndOfState("RESET_TASK"); + receiver.ChangeState("RESET_DEVICE"); + receiver.WaitForEndOfState("RESET_DEVICE"); + + receiver.ChangeState("END"); + + return true; + } +}; + +TEST_F(MultipleDevices, TwoInSameProcess) +{ + std::future fut1 = std::async(std::launch::async, &MultipleDevices::TestFirst, this); + std::future fut2 = std::async(std::launch::async, &MultipleDevices::TestSecond, this); + + bool first = fut1.get(); + bool second = fut2.get(); + + ASSERT_EQ(first, true); + ASSERT_EQ(second, true); +} + +} // namespace diff --git a/fairmq/test/device/runner.cxx b/fairmq/test/device/runner.cxx new file mode 100644 index 00000000..5442845e --- /dev/null +++ b/fairmq/test/device/runner.cxx @@ -0,0 +1,16 @@ +/******************************************************************************** + * Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * + * * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence (LGPL) version 3, * + * copied verbatim in the file "LICENSE" * + ********************************************************************************/ + +#include + +auto main(int argc, char** argv) -> int +{ + ::testing::InitGoogleTest(&argc, argv); + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + return RUN_ALL_TESTS(); +}