-
Notifications
You must be signed in to change notification settings - Fork 6
Keep plugins in scope after loading #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b587d66
fe165bf
3bb1341
02fe44a
544333e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,11 +37,12 @@ | |
| #include <boost_plugin_loader/plugin_loader.h> | ||
| #include <boost_plugin_loader/plugin_loader.hpp> | ||
| #include "test_plugin.h" | ||
| #include "../examples/shape/shape.h" | ||
|
|
||
| TEST(BoostPluginLoaderUnit, Utils) // NOLINT | ||
| { | ||
| using namespace boost_plugin_loader; | ||
| const std::string lib_name = std::string(PLUGINS_MULTIPLY); | ||
| const std::string lib_name = std::string(PLUGIN_LIBRARY_MULTIPLY); | ||
| const std::string lib_dir = std::string(PLUGIN_DIR); | ||
|
|
||
| { | ||
|
|
@@ -172,7 +173,7 @@ TEST(BoostPluginLoaderUnit, LoadTestPlugin) // NOLINT | |
| { | ||
| PluginLoader plugin_loader; | ||
| plugin_loader.search_paths.insert(std::string(PLUGIN_DIR)); | ||
| plugin_loader.search_libraries.insert(std::string(PLUGINS_MULTIPLY)); | ||
| plugin_loader.search_libraries.insert(std::string(PLUGIN_LIBRARY_MULTIPLY)); | ||
|
|
||
| EXPECT_TRUE(plugin_loader.isPluginAvailable(getSymbolName())); | ||
| auto plugin = plugin_loader.createInstance<TestPluginMultiply>(getSymbolName()); | ||
|
|
@@ -197,7 +198,8 @@ TEST(BoostPluginLoaderUnit, LoadTestPlugin) // NOLINT | |
|
|
||
| { // Use full path | ||
| PluginLoader plugin_loader; | ||
| const std::string full_path = boost_plugin_loader::decorate(std::string(PLUGINS_MULTIPLY), std::string(PLUGIN_DIR)); | ||
| const std::string full_path = | ||
| boost_plugin_loader::decorate(std::string(PLUGIN_LIBRARY_MULTIPLY), std::string(PLUGIN_DIR)); | ||
| plugin_loader.search_libraries.insert(full_path); | ||
|
|
||
| EXPECT_TRUE(plugin_loader.isPluginAvailable(getSymbolName())); | ||
|
|
@@ -227,7 +229,7 @@ TEST(BoostPluginLoaderUnit, LoadTestPlugin) // NOLINT | |
| PluginLoader plugin_loader; | ||
| EXPECT_EQ(plugin_loader.count(), 0); | ||
| EXPECT_TRUE(plugin_loader.empty()); | ||
| plugin_loader.search_libraries.insert(std::string(PLUGINS_MULTIPLY)); | ||
| plugin_loader.search_libraries.insert(std::string(PLUGIN_LIBRARY_MULTIPLY)); | ||
| EXPECT_EQ(plugin_loader.count(), 1); | ||
| EXPECT_FALSE(plugin_loader.empty()); | ||
|
|
||
|
|
@@ -243,7 +245,7 @@ TEST(BoostPluginLoaderUnit, LoadTestPlugin) // NOLINT | |
| PluginLoader plugin_loader; | ||
| plugin_loader.search_system_folders = false; | ||
| plugin_loader.search_paths.insert("does_not_exist"); | ||
| plugin_loader.search_libraries.insert(std::string(PLUGINS_MULTIPLY)); | ||
| plugin_loader.search_libraries.insert(std::string(PLUGIN_LIBRARY_MULTIPLY)); | ||
|
|
||
| EXPECT_FALSE(plugin_loader.isPluginAvailable(getSymbolName())); | ||
| // Behavior change: used to return nullptr but now throws exception | ||
|
|
@@ -255,7 +257,7 @@ TEST(BoostPluginLoaderUnit, LoadTestPlugin) // NOLINT | |
| { | ||
| PluginLoader plugin_loader; | ||
| plugin_loader.search_system_folders = false; | ||
| plugin_loader.search_libraries.insert(std::string(PLUGINS_MULTIPLY)); | ||
| plugin_loader.search_libraries.insert(std::string(PLUGIN_LIBRARY_MULTIPLY)); | ||
|
|
||
| { | ||
| EXPECT_FALSE(plugin_loader.isPluginAvailable("does_not_exist")); | ||
|
|
@@ -299,7 +301,7 @@ TEST(BoostPluginLoaderUnit, LoadTestPlugin) // NOLINT | |
| { | ||
| PluginLoader plugin_loader; | ||
| plugin_loader.search_system_folders = false; | ||
| plugin_loader.search_libraries.insert(std::string(PLUGINS_MULTIPLY)); | ||
| plugin_loader.search_libraries.insert(std::string(PLUGIN_LIBRARY_MULTIPLY)); | ||
|
|
||
| // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto) | ||
| const std::vector<std::string> plugins = plugin_loader.getAvailablePlugins(TestPluginMultiply::getSection()); | ||
|
|
@@ -309,7 +311,7 @@ TEST(BoostPluginLoaderUnit, LoadTestPlugin) // NOLINT | |
| { | ||
| PluginLoader plugin_loader; | ||
| plugin_loader.search_system_folders = true; | ||
| plugin_loader.search_libraries.insert(std::string(PLUGINS_MULTIPLY)); | ||
| plugin_loader.search_libraries.insert(std::string(PLUGIN_LIBRARY_MULTIPLY)); | ||
|
|
||
| const std::vector<std::string> plugins = plugin_loader.getAvailablePlugins(TestPluginMultiply::getSection()); | ||
| EXPECT_EQ(plugins.size(), 1); | ||
|
|
@@ -362,7 +364,7 @@ TEST(BoostPluginLoaderUnit, LoadTestPluginsSameSymbolDifferentSections) // NOLI | |
| // Try to load an instance of `TestPluginAddImpl` from the library in which `TestPluginMultiplyImpl` was defined | ||
| { | ||
| PluginLoader plugin_loader; | ||
| plugin_loader.search_libraries.insert(PLUGINS_MULTIPLY); | ||
| plugin_loader.search_libraries.insert(PLUGIN_LIBRARY_MULTIPLY); | ||
| plugin_loader.search_paths.insert(PLUGIN_DIR); | ||
|
|
||
| // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto) | ||
|
|
@@ -372,7 +374,7 @@ TEST(BoostPluginLoaderUnit, LoadTestPluginsSameSymbolDifferentSections) // NOLI | |
| // Try to load an instance of `TestPluginMultiplyImpl` from the library in which `TestPluginAddImpl` was defined | ||
| { | ||
| PluginLoader plugin_loader; | ||
| plugin_loader.search_libraries.insert(PLUGINS_ADD); | ||
| plugin_loader.search_libraries.insert(PLUGIN_LIBRARY_ADD); | ||
| plugin_loader.search_paths.insert(PLUGIN_DIR); | ||
|
|
||
| // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto) | ||
|
|
@@ -382,8 +384,8 @@ TEST(BoostPluginLoaderUnit, LoadTestPluginsSameSymbolDifferentSections) // NOLI | |
| // Given both libraries, correctly load and use each plugin, even though they share the same symbol name | ||
| { | ||
| PluginLoader plugin_loader; | ||
| plugin_loader.search_libraries.insert(PLUGINS_ADD); | ||
| plugin_loader.search_libraries.insert(PLUGINS_MULTIPLY); | ||
| plugin_loader.search_libraries.insert(PLUGIN_LIBRARY_ADD); | ||
| plugin_loader.search_libraries.insert(PLUGIN_LIBRARY_MULTIPLY); | ||
| plugin_loader.search_paths.insert(PLUGIN_DIR); | ||
|
|
||
| // Load and use a multiply plugin | ||
|
|
@@ -406,6 +408,41 @@ TEST(BoostPluginLoaderUnit, LoadTestPluginsSameSymbolDifferentSections) // NOLI | |
| } | ||
| } | ||
|
|
||
| TEST(BoostPluginLoaderUnit, TestPluginLoaderScope) // NOLINT | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Levi-Armstrong this unit test appears to work whether or not the internal cache introduced in this PR exists. According to Any idea why this would work without holding onto the pointer to the plugin internally?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't the plugin_loader object which holds the pointer to the plugin (triangle factory)? So I think what you want is to place the creation of the plugin_loader object inside the brackets and have it go out of scope. Another option, if the method exist would be to remove the triangle factory from the plugin loader also.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, this PR introduces this feature. However, the unit test still succeeds without the addition of this feature. If this unit test is run after removing b587d66 it should fail because the library should be unloaded when the plugin (i.e., |
||
| { | ||
| using boost_plugin_loader::PluginLoader; | ||
| using boost_plugin_loader::Shape; | ||
| using boost_plugin_loader::ShapeFactory; | ||
|
|
||
| // Create a plugin loader | ||
| PluginLoader plugin_loader; | ||
|
|
||
| // Configure the plugin loader to be able to find the shape plugins from the example subdirectory | ||
| plugin_loader.search_libraries.insert(PLUGIN_LIBRARY_EXAMPLES); | ||
| plugin_loader.search_paths.insert(PLUGIN_DIR); | ||
|
|
||
| // Create an instance of a triangle shape using a plugin that goes out of scope | ||
| Shape::Ptr triangle; | ||
| { | ||
| ShapeFactory::Ptr triangle_factory; | ||
| // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto) | ||
| ASSERT_NO_THROW(triangle_factory = plugin_loader.createInstance<ShapeFactory>("Triangle")); | ||
| // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto) | ||
| ASSERT_NO_THROW(triangle = triangle_factory->create(std::make_tuple<double, double>(2.0, 4.0))); | ||
|
|
||
| // The plugin factory goes out of scope here, but the plugin loader maintains a pointer to it internally, keeping | ||
| // the plugin library loaded | ||
| } | ||
|
|
||
| // Use an object created by a plugin whose local instance has gone out of scope but is still maintained in-scope by | ||
| // the plugin loader | ||
| // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto) | ||
| double area; | ||
| EXPECT_NO_THROW(area = triangle->area()); | ||
| // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto) | ||
| EXPECT_NEAR(area, 4.0, 1.0e-6); | ||
| } | ||
|
|
||
| int main(int argc, char** argv) | ||
| { | ||
| testing::InitGoogleTest(&argc, argv); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.