mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-13 08:41:16 +00:00
- Split INITIALIZING state into Init+Bind+Connect - Remove PAUSE state - Convert state/transitions to enum classes (CamelCase) - Transition to a state only once previous handler is complete - Add CompleteInit transition to notify Initializing state that config updates are complete - Deprecate WaitForEndOfState(transition) in favor of WaitForState(state)/WaitForNextState() - Update tests/plugins to new APIs - Deprecate CheckCurrentState() in favor of NewStatePending()
149 lines
6.8 KiB
C++
149 lines
6.8 KiB
C++
/********************************************************************************
|
|
* 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 "Fixture.h"
|
|
#include <condition_variable>
|
|
#include <mutex>
|
|
|
|
namespace
|
|
{
|
|
|
|
using namespace std;
|
|
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.TakeDeviceControl("foo"));
|
|
ASSERT_NO_THROW(mServices.ChangeDeviceState("foo", DeviceStateTransition::InitDevice));
|
|
EXPECT_EQ(mServices.GetDeviceController(), string{"foo"});
|
|
|
|
mDevice.WaitForState(fair::mq::State::InitializingDevice);
|
|
mServices.ChangeDeviceState("foo", DeviceStateTransition::CompleteInit);
|
|
mDevice.WaitForState(fair::mq::State::Initialized);
|
|
mServices.ChangeDeviceState("foo", DeviceStateTransition::Bind);
|
|
mDevice.WaitForState(fair::mq::State::Bound);
|
|
mServices.ChangeDeviceState("foo", DeviceStateTransition::Connect);
|
|
|
|
// park device
|
|
mDevice.WaitForState(fair::mq::State::DeviceReady);
|
|
mServices.ChangeDeviceState("foo", DeviceStateTransition::ResetDevice);
|
|
mDevice.WaitForState(fair::mq::State::Idle);
|
|
mServices.ChangeDeviceState("foo", DeviceStateTransition::End);
|
|
mDevice.WaitForState(fair::mq::State::Exiting);
|
|
}
|
|
|
|
TEST_F(PluginServices, Control)
|
|
{
|
|
ASSERT_EQ(mServices.GetCurrentDeviceState(), DeviceState::Idle);
|
|
ASSERT_NO_THROW(mServices.TakeDeviceControl("foo"));
|
|
ASSERT_NO_THROW(mServices.ChangeDeviceState("foo", DeviceStateTransition::InitDevice));
|
|
|
|
DeviceState nextState;
|
|
condition_variable cv;
|
|
mutex cv_m;
|
|
mServices.SubscribeToDeviceStateChange("test", [&](DeviceState newState){
|
|
ASSERT_NE(newState, DeviceState::ResettingDevice); // check UnsubscribeFromDeviceStateChange
|
|
|
|
lock_guard<mutex> lock{cv_m};
|
|
nextState = newState;
|
|
if (newState == DeviceState::DeviceReady)
|
|
{
|
|
cv.notify_one();
|
|
mServices.UnsubscribeFromDeviceStateChange("test");
|
|
}
|
|
});
|
|
|
|
mDevice.WaitForState(fair::mq::State::InitializingDevice);
|
|
mServices.ChangeDeviceState("foo", DeviceStateTransition::CompleteInit);
|
|
mDevice.WaitForState(fair::mq::State::Initialized);
|
|
mServices.ChangeDeviceState("foo", DeviceStateTransition::Bind);
|
|
mDevice.WaitForState(fair::mq::State::Bound);
|
|
mServices.ChangeDeviceState("foo", DeviceStateTransition::Connect);
|
|
mDevice.WaitForState(fair::mq::State::DeviceReady);
|
|
|
|
unique_lock<mutex> lock{cv_m};
|
|
cv.wait(lock, [&]{ return nextState == DeviceState::DeviceReady; });
|
|
|
|
ASSERT_EQ(mServices.GetCurrentDeviceState(), DeviceState::DeviceReady);
|
|
|
|
mServices.ChangeDeviceState("foo", DeviceStateTransition::ResetDevice);
|
|
mDevice.WaitForState(fair::mq::State::Idle);
|
|
mServices.ChangeDeviceState("foo", DeviceStateTransition::End);
|
|
mDevice.WaitForState(fair::mq::State::Exiting);
|
|
}
|
|
|
|
TEST_F(PluginServices, ControlStateConversions)
|
|
{
|
|
EXPECT_NO_THROW(mServices.ToDeviceState("OK"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceState("ERROR"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceState("IDLE"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceState("INITIALIZING DEVICE"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceState("BINDING"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceState("CONNECTING"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceState("DEVICE READY"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceState("INITIALIZING TASK"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceState("READY"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceState("RUNNING"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceState("RESETTING TASK"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceState("RESETTING DEVICE"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceState("EXITING"));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceState::Ok));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceState::Error));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceState::Idle));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceState::InitializingDevice));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceState::Binding));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceState::Connecting));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceState::DeviceReady));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceState::InitializingTask));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceState::Ready));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceState::Running));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceState::ResettingTask));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceState::ResettingDevice));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceState::Exiting));
|
|
}
|
|
|
|
TEST_F(PluginServices, ControlStateTransitionConversions)
|
|
{
|
|
EXPECT_NO_THROW(mServices.ToDeviceStateTransition("INIT DEVICE"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceStateTransition("COMPLETE INIT"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceStateTransition("INIT TASK"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceStateTransition("RUN"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceStateTransition("STOP"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceStateTransition("RESET TASK"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceStateTransition("RESET DEVICE"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceStateTransition("END"));
|
|
EXPECT_NO_THROW(mServices.ToDeviceStateTransition("ERROR FOUND"));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceStateTransition::InitDevice));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceStateTransition::CompleteInit));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceStateTransition::InitTask));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceStateTransition::Run));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceStateTransition::Stop));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceStateTransition::ResetTask));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceStateTransition::ResetDevice));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceStateTransition::End));
|
|
EXPECT_NO_THROW(mServices.ToStr(DeviceStateTransition::ErrorFound));
|
|
}
|
|
|
|
} /* namespace */
|