mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-16 10:01:47 +00:00
FairMQ: Add plugin mechanism (Plugin and PluginManager classes)
This commit is contained in:
committed by
Mohammad Al-Turany
parent
ac69607250
commit
60d929b0bd
@@ -77,6 +77,58 @@ add_testsuite(FairMQ.Device
|
||||
RUN_SERIAL ON
|
||||
)
|
||||
|
||||
set(VERSION_MAJOR 1)
|
||||
set(VERSION_MINOR 1)
|
||||
set(VERSION_PATCH 0)
|
||||
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/helper/plugins/dummy.h.in ${CMAKE_CURRENT_BINARY_DIR}/helper/plugins/dummy.h)
|
||||
add_testlib(FairMQPlugin_test_dummy
|
||||
SOURCES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/helper/plugins/dummy.h
|
||||
helper/plugins/dummy.cxx
|
||||
|
||||
LINKS FairMQ
|
||||
INCLUDES ${CMAKE_CURRENT_BINARY_DIR}/helper/plugins
|
||||
HIDDEN
|
||||
VERSION ${VERSION}
|
||||
)
|
||||
|
||||
set(VERSION_MAJOR 2)
|
||||
set(VERSION_MINOR 2)
|
||||
set(VERSION_PATCH 0)
|
||||
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/helper/plugins/dummy2.h.in ${CMAKE_CURRENT_BINARY_DIR}/helper/plugins/dummy2.h)
|
||||
add_testlib(FairMQPlugin_test_dummy2
|
||||
SOURCES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/helper/plugins/dummy2.h
|
||||
helper/plugins/dummy2.cxx
|
||||
|
||||
LINKS FairMQ
|
||||
INCLUDES ${CMAKE_CURRENT_BINARY_DIR}/helper/plugins
|
||||
HIDDEN
|
||||
VERSION ${VERSION}
|
||||
)
|
||||
|
||||
add_testsuite(FairMQ.Plugins
|
||||
SOURCES
|
||||
plugins/runner.cxx
|
||||
plugins/_plugin.cxx
|
||||
plugins/_plugin_manager.cxx
|
||||
|
||||
LINKS FairMQ
|
||||
DEPENDS FairMQPlugin_test_dummy FairMQPlugin_test_dummy2
|
||||
TIMEOUT 10
|
||||
)
|
||||
|
||||
add_testsuite(FairMQ.PluginsStatic
|
||||
SOURCES
|
||||
plugins/runner.cxx
|
||||
plugins/_plugin_manager_static.cxx
|
||||
|
||||
LINKS FairMQ FairMQPlugin_test_dummy FairMQPlugin_test_dummy2
|
||||
TIMEOUT 10
|
||||
)
|
||||
|
||||
##############################
|
||||
# Aggregate all test targets #
|
||||
##############################
|
||||
|
9
fairmq/test/helper/plugins/dummy.cxx
Normal file
9
fairmq/test/helper/plugins/dummy.cxx
Normal file
@@ -0,0 +1,9 @@
|
||||
/********************************************************************************
|
||||
* 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 <dummy.h>
|
62
fairmq/test/helper/plugins/dummy.h.in
Normal file
62
fairmq/test/helper/plugins/dummy.h.in
Normal file
@@ -0,0 +1,62 @@
|
||||
/********************************************************************************
|
||||
* 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" *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef FAIR_MQ_TEST_PLUGIN_DUMMY
|
||||
#define FAIR_MQ_TEST_PLUGIN_DUMMY
|
||||
|
||||
#include <fairmq/Plugin.h>
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
|
||||
class DummyPlugin : public fair::mq::Plugin
|
||||
{
|
||||
public:
|
||||
|
||||
DummyPlugin(const std::string name, const Version version, const std::string maintainer, const std::string homepage)
|
||||
: Plugin(name, version, maintainer, homepage)
|
||||
{
|
||||
}
|
||||
|
||||
}; /* class DummyPlugin */
|
||||
|
||||
auto DummyPluginProgramOptions() -> const boost::optional<boost::program_options::options_description>
|
||||
{
|
||||
using namespace boost::program_options;
|
||||
using std::string;
|
||||
|
||||
auto plugin_options = options_description{"Dummy Plugin"};
|
||||
plugin_options.add_options()
|
||||
("custom-dummy-option", value<string>(), "Cool custom option.");
|
||||
("custom-dummy-option2", value<string>(), "Another cool custom option.");
|
||||
return plugin_options;
|
||||
}
|
||||
|
||||
REGISTER_FAIRMQ_PLUGIN(
|
||||
DummyPlugin, // Class name
|
||||
test_dummy, // Plugin name (string, lower case chars only)
|
||||
(fair::mq::Plugin::Version{@VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@}), // Version
|
||||
"Mr. Dummy <dummy@test.net>", // Maintainer
|
||||
"https://git.test.net/dummy.git", // Homepage
|
||||
fair::mq::test::DummyPluginProgramOptions // Free function which declares custom program options for the plugin
|
||||
// signature: () -> boost::optional<boost::program_options::options_description>
|
||||
)
|
||||
|
||||
} /* namespace test */
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
|
||||
#endif /* FAIR_MQ_TEST_PLUGIN_DUMMY */
|
9
fairmq/test/helper/plugins/dummy2.cxx
Normal file
9
fairmq/test/helper/plugins/dummy2.cxx
Normal file
@@ -0,0 +1,9 @@
|
||||
/********************************************************************************
|
||||
* 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 <dummy2.h>
|
44
fairmq/test/helper/plugins/dummy2.h.in
Normal file
44
fairmq/test/helper/plugins/dummy2.h.in
Normal file
@@ -0,0 +1,44 @@
|
||||
/********************************************************************************
|
||||
* 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" *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef FAIR_MQ_TEST_PLUGIN_DUMMY2
|
||||
#define FAIR_MQ_TEST_PLUGIN_DUMMY2
|
||||
|
||||
#include <fairmq/Plugin.h>
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
|
||||
class Dummy2Plugin : public fair::mq::Plugin
|
||||
{
|
||||
public:
|
||||
|
||||
Dummy2Plugin(const std::string name, const Version version, const std::string maintainer, const std::string homepage)
|
||||
: Plugin(name, version, maintainer, homepage)
|
||||
{
|
||||
}
|
||||
}; /* class Dummy2Plugin */
|
||||
|
||||
REGISTER_FAIRMQ_PLUGIN(
|
||||
Dummy2Plugin,
|
||||
test_dummy2,
|
||||
(Plugin::Version{@VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@}),
|
||||
"Mr. Dummy <dummy@test.net>",
|
||||
"https://git.test.net/dummy.git",
|
||||
fair::mq::Plugin::NoProgramOptions
|
||||
)
|
||||
|
||||
} /* namespace test */
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
|
||||
#endif /* FAIR_MQ_TEST_PLUGIN_DUMMY */
|
52
fairmq/test/plugins/_plugin.cxx
Normal file
52
fairmq/test/plugins/_plugin.cxx
Normal file
@@ -0,0 +1,52 @@
|
||||
/********************************************************************************
|
||||
* 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 <gtest/gtest.h>
|
||||
#include <fairmq/Plugin.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
using namespace std;
|
||||
using fair::mq::Plugin;
|
||||
|
||||
TEST(Plugin, Operators)
|
||||
{
|
||||
auto p1 = Plugin{"dds", {1, 0, 0}, "Foo Bar <foo.bar@test.net>", "https://git.test.net/dds.git"};
|
||||
auto p2 = Plugin{"dds", {1, 0, 0}, "Foo Bar <foo.bar@test.net>", "https://git.test.net/dds.git"};
|
||||
auto p3 = Plugin{"file", {1, 0, 0}, "Foo Bar <foo.bar@test.net>", "https://git.test.net/file.git"};
|
||||
EXPECT_EQ(p1, p2);
|
||||
EXPECT_NE(p1, p3);
|
||||
}
|
||||
|
||||
TEST(Plugin, OstreamOperators)
|
||||
{
|
||||
auto p1 = Plugin{"dds", {1, 0, 0}, "Foo Bar <foo.bar@test.net>", "https://git.test.net/dds.git"};
|
||||
stringstream ss;
|
||||
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'"});
|
||||
}
|
||||
|
||||
TEST(PluginVersion, Operators)
|
||||
{
|
||||
struct Plugin::Version v1{1, 0, 0};
|
||||
struct Plugin::Version v2{1, 0, 0};
|
||||
struct Plugin::Version v3{1, 2, 0};
|
||||
EXPECT_EQ(v1, v2);
|
||||
EXPECT_NE(v1, v3);
|
||||
EXPECT_GT(v3, v2);
|
||||
EXPECT_LT(v1, v3);
|
||||
EXPECT_GE(v3, v2);
|
||||
EXPECT_GE(v2, v1);
|
||||
EXPECT_LE(v1, v2);
|
||||
EXPECT_LE(v2, v3);
|
||||
}
|
||||
|
||||
} /* namespace */
|
103
fairmq/test/plugins/_plugin_manager.cxx
Normal file
103
fairmq/test/plugins/_plugin_manager.cxx
Normal file
@@ -0,0 +1,103 @@
|
||||
/********************************************************************************
|
||||
* 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 <gtest/gtest.h>
|
||||
#include <fairmq/PluginManager.h>
|
||||
#include <FairMQLogger.h>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
using namespace fair::mq;
|
||||
using namespace boost::filesystem;
|
||||
using namespace boost::program_options;
|
||||
using namespace std;
|
||||
|
||||
TEST(PluginManager, LoadPlugin)
|
||||
{
|
||||
auto mgr = PluginManager{};
|
||||
mgr.PrependSearchPath("./lib");
|
||||
|
||||
ASSERT_NO_THROW(mgr.LoadPlugin("test_dummy"));
|
||||
ASSERT_NO_THROW(mgr.LoadPlugin("test_dummy2"));
|
||||
|
||||
// check order
|
||||
auto expected = vector<string>{"test_dummy", "test_dummy2"};
|
||||
auto actual = vector<string>{};
|
||||
mgr.ForEachPlugin([&](Plugin& plugin){ actual.push_back(plugin.GetName()); });
|
||||
ASSERT_TRUE(actual == expected);
|
||||
|
||||
// program options
|
||||
auto count = 0;
|
||||
mgr.ForEachPluginProgOptions([&count](const options_description& d){ ++count; });
|
||||
ASSERT_EQ(count, 1);
|
||||
}
|
||||
|
||||
TEST(PluginManager, Factory)
|
||||
{
|
||||
const auto args = vector<string>{"-l", "debug", "--help", "-S", ">/lib", "</home/user/lib", "/usr/local/lib", "/usr/lib"};
|
||||
auto mgr = PluginManager::MakeFromCommandLineOptions(args);
|
||||
const auto path1 = path{"/home/user/lib"};
|
||||
const auto path2 = path{"/usr/local/lib"};
|
||||
const auto path3 = path{"/usr/lib"};
|
||||
const auto path4 = path{"/lib"};
|
||||
const auto expected = vector<path>{path1, path2, path3, path4};
|
||||
ASSERT_TRUE(static_cast<bool>(mgr));
|
||||
ASSERT_TRUE(mgr->SearchPaths() == expected);
|
||||
}
|
||||
|
||||
TEST(PluginManager, SearchPathValidation)
|
||||
{
|
||||
const auto path1 = path{"/tmp/test1"};
|
||||
const auto path2 = path{"/tmp/test2"};
|
||||
const auto path3 = path{"/tmp/test3"};
|
||||
auto mgr = PluginManager{};
|
||||
|
||||
mgr.SetSearchPaths({path1, path2});
|
||||
auto expected = vector<path>{path1, path2};
|
||||
ASSERT_EQ(mgr.SearchPaths(), expected);
|
||||
|
||||
mgr.AppendSearchPath(path3);
|
||||
expected = vector<path>{path1, path2, path3};
|
||||
ASSERT_EQ(mgr.SearchPaths(), expected);
|
||||
|
||||
mgr.PrependSearchPath(path3);
|
||||
expected = vector<path>{path3, path1, path2, path3};
|
||||
ASSERT_EQ(mgr.SearchPaths(), expected);
|
||||
}
|
||||
|
||||
TEST(PluginManager, SearchPaths)
|
||||
{
|
||||
const auto temp = temp_directory_path() / unique_path();
|
||||
create_directories(temp);
|
||||
const auto non_existing_dir = temp / "non-existing-dir";
|
||||
const auto existing_dir = temp / "existing-dir";
|
||||
create_directories(existing_dir);
|
||||
const auto existing_file = temp / "existing-file.so";
|
||||
std::fstream fs;
|
||||
fs.open(existing_file.string(), std::fstream::out);
|
||||
fs.close();
|
||||
const auto empty_path = path{""};
|
||||
|
||||
auto mgr = PluginManager{};
|
||||
ASSERT_NO_THROW(mgr.AppendSearchPath(non_existing_dir));
|
||||
ASSERT_NO_THROW(mgr.AppendSearchPath(existing_dir));
|
||||
ASSERT_THROW(mgr.AppendSearchPath(existing_file), PluginManager::BadSearchPath);
|
||||
ASSERT_NO_THROW(mgr.PrependSearchPath(non_existing_dir));
|
||||
ASSERT_NO_THROW(mgr.PrependSearchPath(existing_dir));
|
||||
ASSERT_THROW(mgr.PrependSearchPath(existing_file), PluginManager::BadSearchPath);
|
||||
ASSERT_NO_THROW(mgr.SetSearchPaths({non_existing_dir, existing_dir}));
|
||||
ASSERT_THROW(mgr.SetSearchPaths({non_existing_dir, existing_file}), PluginManager::BadSearchPath);
|
||||
ASSERT_THROW(mgr.SetSearchPaths({non_existing_dir, empty_path}), PluginManager::BadSearchPath);
|
||||
|
||||
remove_all(temp);
|
||||
}
|
||||
|
||||
} /* namespace */
|
28
fairmq/test/plugins/_plugin_manager_static.cxx
Normal file
28
fairmq/test/plugins/_plugin_manager_static.cxx
Normal file
@@ -0,0 +1,28 @@
|
||||
/********************************************************************************
|
||||
* 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 <gtest/gtest.h>
|
||||
#include <fairmq/PluginManager.h>
|
||||
#include <FairMQLogger.h>
|
||||
#include <vector>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
using namespace fair::mq;
|
||||
using namespace std;
|
||||
|
||||
TEST(PluginManager, LoadPluginStatic)
|
||||
{
|
||||
auto mgr = PluginManager{};
|
||||
|
||||
ASSERT_NO_THROW(mgr.LoadPlugin("s:test_dummy"));
|
||||
ASSERT_NO_THROW(mgr.LoadPlugin("s:test_dummy2"));
|
||||
}
|
||||
|
||||
} /* namespace */
|
16
fairmq/test/plugins/runner.cxx
Normal file
16
fairmq/test/plugins/runner.cxx
Normal file
@@ -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 <gtest/gtest.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
::testing::FLAGS_gtest_death_test_style = "threadsafe";
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
Reference in New Issue
Block a user