mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-13 00:31:14 +00:00
test: Consolidate some device control logic
This commit is contained in:
parent
435d07eaf9
commit
84de22f80b
|
@ -1,11 +1,13 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2017-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
* copied verbatim in the file "LICENSE" *
|
* copied verbatim in the file "LICENSE" *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
|
#include "../helper/ControlDevice.h"
|
||||||
|
|
||||||
#include <fairmq/Device.h>
|
#include <fairmq/Device.h>
|
||||||
#include <fairmq/DeviceRunner.h>
|
#include <fairmq/DeviceRunner.h>
|
||||||
#include <fairmq/ProgOptions.h>
|
#include <fairmq/ProgOptions.h>
|
||||||
|
@ -21,51 +23,14 @@ namespace _config
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace fair::mq;
|
using namespace fair::mq;
|
||||||
|
|
||||||
void control(Device& device)
|
|
||||||
{
|
|
||||||
device.ChangeState(Transition::InitDevice);
|
|
||||||
device.WaitForState(State::InitializingDevice);
|
|
||||||
device.ChangeState(Transition::CompleteInit);
|
|
||||||
device.WaitForState(State::Initialized);
|
|
||||||
device.ChangeState(Transition::Bind);
|
|
||||||
device.WaitForState(State::Bound);
|
|
||||||
device.ChangeState(Transition::Connect);
|
|
||||||
device.WaitForState(State::DeviceReady);
|
|
||||||
device.ChangeState(Transition::InitTask);
|
|
||||||
device.WaitForState(State::Ready);
|
|
||||||
|
|
||||||
device.ChangeState(Transition::Run);
|
|
||||||
device.WaitForState(State::Ready);
|
|
||||||
|
|
||||||
device.ChangeState(Transition::ResetTask);
|
|
||||||
device.WaitForState(State::DeviceReady);
|
|
||||||
device.ChangeState(Transition::ResetDevice);
|
|
||||||
device.WaitForState(State::Idle);
|
|
||||||
|
|
||||||
device.ChangeState(Transition::End);
|
|
||||||
}
|
|
||||||
|
|
||||||
class TestDevice : public Device
|
class TestDevice : public Device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TestDevice(const string& transport)
|
TestDevice(const string& transport)
|
||||||
|
: fDeviceThread(&Device::RunStateMachine, this)
|
||||||
{
|
{
|
||||||
fDeviceThread = thread(&Device::RunStateMachine, this);
|
|
||||||
|
|
||||||
SetTransport(transport);
|
SetTransport(transport);
|
||||||
|
test::Control(*this, test::Cycle::ToRun);
|
||||||
ChangeState(Transition::InitDevice);
|
|
||||||
WaitForState(State::InitializingDevice);
|
|
||||||
ChangeState(Transition::CompleteInit);
|
|
||||||
WaitForState(State::Initialized);
|
|
||||||
ChangeState(Transition::Bind);
|
|
||||||
WaitForState(State::Bound);
|
|
||||||
ChangeState(Transition::Connect);
|
|
||||||
WaitForState(State::DeviceReady);
|
|
||||||
ChangeState(Transition::InitTask);
|
|
||||||
WaitForState(State::Ready);
|
|
||||||
|
|
||||||
ChangeState(Transition::Run);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TestDevice(const TestDevice&) = delete;
|
TestDevice(const TestDevice&) = delete;
|
||||||
|
@ -75,16 +40,7 @@ class TestDevice : public Device
|
||||||
|
|
||||||
~TestDevice() override
|
~TestDevice() override
|
||||||
{
|
{
|
||||||
WaitForState(State::Running);
|
test::Control(*this, test::Cycle::ReadyToEnd);
|
||||||
ChangeState(Transition::Stop);
|
|
||||||
WaitForState(State::Ready);
|
|
||||||
ChangeState(Transition::ResetTask);
|
|
||||||
WaitForState(State::DeviceReady);
|
|
||||||
ChangeState(Transition::ResetDevice);
|
|
||||||
WaitForState(State::Idle);
|
|
||||||
|
|
||||||
ChangeState(Transition::End);
|
|
||||||
|
|
||||||
if (fDeviceThread.joinable()) {
|
if (fDeviceThread.joinable()) {
|
||||||
fDeviceThread.join();
|
fDeviceThread.join();
|
||||||
}
|
}
|
||||||
|
@ -118,7 +74,7 @@ class Config : public ::testing::Test
|
||||||
channel.UpdateAddress("tcp://localhost:5558");
|
channel.UpdateAddress("tcp://localhost:5558");
|
||||||
device.AddChannel("data", std::move(channel));
|
device.AddChannel("data", std::move(channel));
|
||||||
|
|
||||||
thread t(control, ref(device));
|
thread t([&]() { test::Control(device); });
|
||||||
|
|
||||||
device.RunStateMachine();
|
device.RunStateMachine();
|
||||||
|
|
||||||
|
@ -156,7 +112,7 @@ class Config : public ::testing::Test
|
||||||
channel.UpdateAddress("tcp://localhost:5558");
|
channel.UpdateAddress("tcp://localhost:5558");
|
||||||
device.AddChannel("data", std::move(channel));
|
device.AddChannel("data", std::move(channel));
|
||||||
|
|
||||||
thread t(control, ref(device));
|
thread t([&]() { test::Control(device); });
|
||||||
|
|
||||||
device.RunStateMachine();
|
device.RunStateMachine();
|
||||||
|
|
||||||
|
@ -189,7 +145,7 @@ class Config : public ::testing::Test
|
||||||
|
|
||||||
thread t(&Device::RunStateMachine, &device);
|
thread t(&Device::RunStateMachine, &device);
|
||||||
|
|
||||||
control(device);
|
test::Control(device);
|
||||||
|
|
||||||
if (t.joinable()) {
|
if (t.joinable()) {
|
||||||
t.join();
|
t.join();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,6 +9,8 @@
|
||||||
#include "TestSender.h"
|
#include "TestSender.h"
|
||||||
#include "TestReceiver.h"
|
#include "TestReceiver.h"
|
||||||
|
|
||||||
|
#include "../helper/ControlDevice.h"
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -23,28 +25,7 @@ using namespace fair::mq;
|
||||||
|
|
||||||
void control(Device& device)
|
void control(Device& device)
|
||||||
{
|
{
|
||||||
thread t([&] {
|
thread t([&]() { test::Control(device); });
|
||||||
device.ChangeState(Transition::InitDevice);
|
|
||||||
device.WaitForState(State::InitializingDevice);
|
|
||||||
device.ChangeState(Transition::CompleteInit);
|
|
||||||
device.WaitForState(State::Initialized);
|
|
||||||
device.ChangeState(Transition::Bind);
|
|
||||||
device.WaitForState(State::Bound);
|
|
||||||
device.ChangeState(Transition::Connect);
|
|
||||||
device.WaitForState(State::DeviceReady);
|
|
||||||
device.ChangeState(Transition::InitTask);
|
|
||||||
device.WaitForState(State::Ready);
|
|
||||||
|
|
||||||
device.ChangeState(Transition::Run);
|
|
||||||
device.WaitForState(State::Ready);
|
|
||||||
|
|
||||||
device.ChangeState(Transition::ResetTask);
|
|
||||||
device.WaitForState(State::DeviceReady);
|
|
||||||
device.ChangeState(Transition::ResetDevice);
|
|
||||||
device.WaitForState(State::Idle);
|
|
||||||
|
|
||||||
device.ChangeState(Transition::End);
|
|
||||||
});
|
|
||||||
|
|
||||||
device.RunStateMachine();
|
device.RunStateMachine();
|
||||||
|
|
||||||
|
@ -55,8 +36,6 @@ void control(Device& device)
|
||||||
|
|
||||||
class MultipleDevices : public ::testing::Test {
|
class MultipleDevices : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
MultipleDevices() {}
|
|
||||||
|
|
||||||
bool TestFirst()
|
bool TestFirst()
|
||||||
{
|
{
|
||||||
test::Sender sender("data");
|
test::Sender sender("data");
|
||||||
|
|
66
test/helper/ControlDevice.h
Normal file
66
test/helper/ControlDevice.h
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (C) 2023 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_CONTROL_H
|
||||||
|
#define FAIR_MQ_TEST_CONTROL_H
|
||||||
|
|
||||||
|
#include <fairmq/Device.h>
|
||||||
|
|
||||||
|
namespace fair::mq::test
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class Cycle {
|
||||||
|
FullNoStop,
|
||||||
|
ToDeviceReadyAndBack,
|
||||||
|
ToRun,
|
||||||
|
ReadyToEnd
|
||||||
|
};
|
||||||
|
|
||||||
|
inline auto Control(Device& device, Cycle cycle = Cycle::FullNoStop)
|
||||||
|
{
|
||||||
|
if( cycle == Cycle::FullNoStop
|
||||||
|
|| cycle == Cycle::ToDeviceReadyAndBack
|
||||||
|
|| cycle == Cycle::ToRun)
|
||||||
|
{
|
||||||
|
device.ChangeStateOrThrow(Transition::InitDevice);
|
||||||
|
device.WaitForState(State::InitializingDevice);
|
||||||
|
device.ChangeStateOrThrow(Transition::CompleteInit);
|
||||||
|
device.WaitForState(State::Initialized);
|
||||||
|
device.ChangeStateOrThrow(Transition::Bind);
|
||||||
|
device.WaitForState(State::Bound);
|
||||||
|
device.ChangeStateOrThrow(Transition::Connect);
|
||||||
|
device.WaitForState(State::DeviceReady);
|
||||||
|
}
|
||||||
|
if( cycle == Cycle::FullNoStop
|
||||||
|
|| cycle == Cycle::ToRun)
|
||||||
|
{
|
||||||
|
device.ChangeStateOrThrow(Transition::InitTask);
|
||||||
|
device.WaitForState(State::Ready);
|
||||||
|
device.ChangeStateOrThrow(Transition::Run);
|
||||||
|
device.WaitForState(State::Running);
|
||||||
|
}
|
||||||
|
if( cycle == Cycle::FullNoStop
|
||||||
|
|| cycle == Cycle::ReadyToEnd)
|
||||||
|
{
|
||||||
|
device.WaitForState(State::Ready);
|
||||||
|
device.ChangeStateOrThrow(Transition::ResetTask);
|
||||||
|
device.WaitForState(State::DeviceReady);
|
||||||
|
}
|
||||||
|
if( cycle == Cycle::FullNoStop
|
||||||
|
|| cycle == Cycle::ToDeviceReadyAndBack
|
||||||
|
|| cycle == Cycle::ReadyToEnd)
|
||||||
|
{
|
||||||
|
device.ChangeStateOrThrow(Transition::ResetDevice);
|
||||||
|
device.WaitForState(State::Idle);
|
||||||
|
device.ChangeStateOrThrow(Transition::End);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FAIR_MQ_TEST_CONTROL_H
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2017-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,6 +9,8 @@
|
||||||
#ifndef FAIR_MQ_TEST_FIXTURE
|
#ifndef FAIR_MQ_TEST_FIXTURE
|
||||||
#define FAIR_MQ_TEST_FIXTURE
|
#define FAIR_MQ_TEST_FIXTURE
|
||||||
|
|
||||||
|
#include "../helper/ControlDevice.h"
|
||||||
|
|
||||||
#include <fairmq/PluginServices.h>
|
#include <fairmq/PluginServices.h>
|
||||||
#include <fairmq/Device.h>
|
#include <fairmq/Device.h>
|
||||||
#include <fairmq/ProgOptions.h>
|
#include <fairmq/ProgOptions.h>
|
||||||
|
@ -21,22 +23,6 @@
|
||||||
namespace fair::mq::test
|
namespace fair::mq::test
|
||||||
{
|
{
|
||||||
|
|
||||||
inline auto control(fair::mq::Device& device) -> void
|
|
||||||
{
|
|
||||||
device.ChangeState(fair::mq::Transition::InitDevice);
|
|
||||||
device.WaitForState(fair::mq::State::InitializingDevice);
|
|
||||||
device.ChangeState(fair::mq::Transition::CompleteInit);
|
|
||||||
device.WaitForState(fair::mq::State::Initialized);
|
|
||||||
device.ChangeState(fair::mq::Transition::Bind);
|
|
||||||
device.WaitForState(fair::mq::State::Bound);
|
|
||||||
device.ChangeState(fair::mq::Transition::Connect);
|
|
||||||
device.WaitForState(fair::mq::State::DeviceReady);
|
|
||||||
device.ChangeState(fair::mq::Transition::ResetDevice);
|
|
||||||
device.WaitForState(fair::mq::State::Idle);
|
|
||||||
|
|
||||||
device.ChangeState(fair::mq::Transition::End);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PluginServices : ::testing::Test {
|
struct PluginServices : ::testing::Test {
|
||||||
PluginServices()
|
PluginServices()
|
||||||
: mConfig()
|
: mConfig()
|
||||||
|
@ -48,17 +34,19 @@ struct PluginServices : ::testing::Test {
|
||||||
mDevice.SetTransport("zeromq");
|
mDevice.SetTransport("zeromq");
|
||||||
}
|
}
|
||||||
|
|
||||||
~PluginServices()
|
~PluginServices() override
|
||||||
{
|
{
|
||||||
if (mDevice.GetCurrentState() == fair::mq::State::Idle) control(mDevice);
|
if (mDevice.GetCurrentState() == State::Idle) {
|
||||||
|
Control(mDevice, Cycle::ToDeviceReadyAndBack);
|
||||||
|
}
|
||||||
if (fRunStateMachineThread.joinable()) {
|
if (fRunStateMachineThread.joinable()) {
|
||||||
fRunStateMachineThread.join();
|
fRunStateMachineThread.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fair::mq::ProgOptions mConfig;
|
ProgOptions mConfig;
|
||||||
fair::mq::Device mDevice;
|
Device mDevice;
|
||||||
fair::mq::PluginServices mServices;
|
mq::PluginServices mServices;
|
||||||
std::thread fRunStateMachineThread;
|
std::thread fRunStateMachineThread;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2017-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
* copied verbatim in the file "LICENSE" *
|
* copied verbatim in the file "LICENSE" *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include "../helper/ControlDevice.h"
|
||||||
|
|
||||||
#include <fairmq/Plugin.h>
|
#include <fairmq/Plugin.h>
|
||||||
#include <fairmq/PluginServices.h>
|
#include <fairmq/PluginServices.h>
|
||||||
#include <fairmq/tools/Version.h>
|
#include <fairmq/tools/Version.h>
|
||||||
#include <fairmq/Device.h>
|
#include <fairmq/Device.h>
|
||||||
#include <fairmq/ProgOptions.h>
|
#include <fairmq/ProgOptions.h>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -27,19 +31,7 @@ using namespace fair::mq;
|
||||||
auto control(Device& device) -> void
|
auto control(Device& device) -> void
|
||||||
{
|
{
|
||||||
device.SetTransport("zeromq");
|
device.SetTransport("zeromq");
|
||||||
|
test::Control(device, test::Cycle::ToDeviceReadyAndBack);
|
||||||
device.ChangeState(Transition::InitDevice);
|
|
||||||
device.WaitForState(State::InitializingDevice);
|
|
||||||
device.ChangeState(Transition::CompleteInit);
|
|
||||||
device.WaitForState(State::Initialized);
|
|
||||||
device.ChangeState(Transition::Bind);
|
|
||||||
device.WaitForState(State::Bound);
|
|
||||||
device.ChangeState(Transition::Connect);
|
|
||||||
device.WaitForState(State::DeviceReady);
|
|
||||||
device.ChangeState(Transition::ResetDevice);
|
|
||||||
device.WaitForState(State::Idle);
|
|
||||||
|
|
||||||
device.ChangeState(Transition::End);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Plugin, Operators)
|
TEST(Plugin, Operators)
|
||||||
|
@ -52,7 +44,7 @@ TEST(Plugin, Operators)
|
||||||
Plugin p3{"file", {1, 0, 0}, "Foo Bar <foo.bar@test.net>", "https://git.test.net/file.git", &services};
|
Plugin p3{"file", {1, 0, 0}, "Foo Bar <foo.bar@test.net>", "https://git.test.net/file.git", &services};
|
||||||
EXPECT_EQ(p1, p2);
|
EXPECT_EQ(p1, p2);
|
||||||
EXPECT_NE(p1, p3);
|
EXPECT_NE(p1, p3);
|
||||||
thread t(control, std::ref(device));
|
thread t([&]() { control(device); });
|
||||||
device.RunStateMachine();
|
device.RunStateMachine();
|
||||||
if (t.joinable()) {
|
if (t.joinable()) {
|
||||||
t.join();
|
t.join();
|
||||||
|
@ -68,7 +60,7 @@ TEST(Plugin, OstreamOperators)
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << p1;
|
ss << p1;
|
||||||
EXPECT_EQ(ss.str(), string{"'dds', version '1.0.0', maintainer 'Foo Bar <foo.bar@test.net>', homepage 'https://git.test.net/dds.git'"});
|
EXPECT_EQ(ss.str(), string{"'dds', version '1.0.0', maintainer 'Foo Bar <foo.bar@test.net>', homepage 'https://git.test.net/dds.git'"});
|
||||||
thread t(control, std::ref(device));
|
thread t([&]() { control(device); });
|
||||||
device.RunStateMachine();
|
device.RunStateMachine();
|
||||||
if (t.joinable()) {
|
if (t.joinable()) {
|
||||||
t.join();
|
t.join();
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2017-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
* copied verbatim in the file "LICENSE" *
|
* copied verbatim in the file "LICENSE" *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include "../helper/ControlDevice.h"
|
||||||
|
|
||||||
#include <fairmq/PluginManager.h>
|
#include <fairmq/PluginManager.h>
|
||||||
#include <fairmq/PluginServices.h>
|
#include <fairmq/PluginServices.h>
|
||||||
#include <fairmq/Device.h>
|
#include <fairmq/Device.h>
|
||||||
#include <fairmq/ProgOptions.h>
|
#include <fairmq/ProgOptions.h>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <fairlogger/Logger.h>
|
#include <fairlogger/Logger.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -28,19 +33,7 @@ using namespace std;
|
||||||
auto control(Device& device) -> void
|
auto control(Device& device) -> void
|
||||||
{
|
{
|
||||||
device.SetTransport("zeromq");
|
device.SetTransport("zeromq");
|
||||||
|
test::Control(device, test::Cycle::ToDeviceReadyAndBack);
|
||||||
device.ChangeState(Transition::InitDevice);
|
|
||||||
device.WaitForState(State::InitializingDevice);
|
|
||||||
device.ChangeState(Transition::CompleteInit);
|
|
||||||
device.WaitForState(State::Initialized);
|
|
||||||
device.ChangeState(Transition::Bind);
|
|
||||||
device.WaitForState(State::Bound);
|
|
||||||
device.ChangeState(Transition::Connect);
|
|
||||||
device.WaitForState(State::DeviceReady);
|
|
||||||
device.ChangeState(Transition::ResetDevice);
|
|
||||||
device.WaitForState(State::Idle);
|
|
||||||
|
|
||||||
device.ChangeState(Transition::End);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PluginManager, LoadPluginDynamic)
|
TEST(PluginManager, LoadPluginDynamic)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user