FairMQ: Implement Take/ReleaseDeviceControl plugin API

The main function of this API is to make sure only one plugin is
controlling the device state transitions at a time. The
ReleaseDeviceControl() signal is used to implement a function
WaitForPluginsToReleaseDeviceControl() which is used to block the main
thread if a control plugin is used.
This commit is contained in:
Dennis Klein
2017-09-13 21:34:50 +02:00
committed by Mohammad Al-Turany
parent dfb2bac4bc
commit 2af3ae99eb
5 changed files with 143 additions and 16 deletions

View File

@@ -9,7 +9,6 @@
#include "Fixture.h"
#include <condition_variable>
#include <mutex>
// #include <thread>
namespace
{
@@ -19,10 +18,36 @@ using fair::mq::test::PluginServices;
using DeviceState = fair::mq::PluginServices::DeviceState;
using DeviceStateTransition = fair::mq::PluginServices::DeviceStateTransition;
TEST_F(PluginServices, OnlySingleController)
{
ASSERT_NO_THROW(mServices.TakeDeviceControl("foo"));
ASSERT_NO_THROW(mServices.TakeDeviceControl("foo")); // noop
ASSERT_THROW( // no control for bar
mServices.ChangeDeviceState("bar", DeviceStateTransition::InitDevice),
fair::mq::PluginServices::DeviceControlError
);
ASSERT_THROW( // no control for bar
mServices.ReleaseDeviceControl("bar"),
fair::mq::PluginServices::DeviceControlError
);
ASSERT_NO_THROW(mServices.ReleaseDeviceControl("foo"));
ASSERT_FALSE(mServices.GetDeviceController());
// take control implicitely
ASSERT_NO_THROW(mServices.ChangeDeviceState("foo", DeviceStateTransition::InitDevice));
EXPECT_EQ(mServices.GetDeviceController(), string{"foo"});
// park device
mDevice->WaitForEndOfState(FairMQDevice::DEVICE_READY);
mServices.ChangeDeviceState("foo", DeviceStateTransition::ResetDevice);
mDevice->WaitForEndOfState(FairMQDevice::RESET_DEVICE);
mServices.ChangeDeviceState("foo", DeviceStateTransition::End);
}
TEST_F(PluginServices, Control)
{
ASSERT_EQ(mServices.GetCurrentDeviceState(), DeviceState::Idle);
ASSERT_NO_THROW(mServices.ChangeDeviceState(DeviceStateTransition::InitDevice));
ASSERT_NO_THROW(mServices.ChangeDeviceState("foo", DeviceStateTransition::InitDevice));
DeviceState nextState;
condition_variable cv;
@@ -38,16 +63,15 @@ TEST_F(PluginServices, Control)
mServices.UnsubscribeFromDeviceStateChange("test");
}
});
{
unique_lock<mutex> lock{cv_m};
cv.wait(lock);
}
unique_lock<mutex> lock{cv_m};
cv.wait(lock);
ASSERT_EQ(mServices.GetCurrentDeviceState(), DeviceState::DeviceReady);
mServices.ChangeDeviceState(DeviceStateTransition::ResetDevice);
mServices.ChangeDeviceState("foo", DeviceStateTransition::ResetDevice);
mDevice->WaitForEndOfState(FairMQDevice::RESET_DEVICE);
mServices.ChangeDeviceState(DeviceStateTransition::End);
mServices.ChangeDeviceState("foo", DeviceStateTransition::End);
}
TEST_F(PluginServices, ControlStateConversions)