[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/QuantStack/xplugin/main/test/test_xplugin.cpp [Back]  [Original]

#include 

#include 
#include 

#include 
#include 

#include 

#ifndef XPLUGIN_NO_THREADS
#include 
#endif

#include 

using base_type = plugin::PluginBase;
using factory_base_type = xp::xfactory_base;
using plugin_registry_type = xp::xplugin_registry;

void test_xplugin_impl(plugin_registry_type& registry)
{
    CHECK_EQ(registry.size(), 3);

    auto factory_01 = registry["plugin_01"];
    auto factory_02 = registry["plugin_02"];
    auto factory_03 = registry["plugin_03"];

    auto plugin_01 = factory_01->create(1, "a");
    auto plugin_02 = factory_02->create(2, "b");
    auto plugin_03 = factory_03->create(3, "c");

    CHECK(plugin_01);
    CHECK(plugin_02);
    CHECK(plugin_03);

    CHECK_EQ(plugin_01->name(), "Plugin01");
    CHECK_EQ(plugin_02->name(), "Plugin02");
    CHECK_EQ(plugin_03->name(), "Plugin03");

    CHECK_EQ(plugin_01->greet(), "hello from Plugin01");
    CHECK_EQ(plugin_02->greet(), "hello from Plugin02");
    CHECK_EQ(plugin_03->greet(), "hello from Plugin03");

    // // iterate over plugins
    SUBCASE("begin_end")
    {
        std::cout greet();
            plugin_names.insert(p.first);
        }

        CHECK_EQ(plugin_names.size(), 3);
        CHECK(plugin_names.count("plugin_01"));
        CHECK(plugin_names.count("plugin_02"));
        CHECK(plugin_names.count("plugin_03"));
    }
    SUBCASE("iterator-values-ref")
    {
        std::set plugin_names;
        for (auto &p : registry)
        {
            p.second->create(1, "a")->greet();
            plugin_names.insert(p.first);
        }

        CHECK_EQ(plugin_names.size(), 3);
        CHECK(plugin_names.count("plugin_01"));
        CHECK(plugin_names.count("plugin_02"));
        CHECK(plugin_names.count("plugin_03"));
    }
    SUBCASE("iterator-unpack")
    {
        std::set plugin_names;
        for (auto [name, factory] : registry)
        {
            factory->create(1, "a")->greet();
            plugin_names.insert(name);
        }
        CHECK_EQ(plugin_names.size(), 3);
        CHECK(plugin_names.count("plugin_01"));
        CHECK(plugin_names.count("plugin_02"));
        CHECK(plugin_names.count("plugin_03"));
    }
}

namespace
{
    std::string get_default_extension()
    {
 #ifdef _WIN32
        return ".dll";
#elif __APPLE__
        return ".dylib";
#else
        return ".so";
#endif
    }   
}
TEST_CASE("test_xplugin")
{
    std::filesystem::path path("testplugin_a");
    plugin_registry_type registry(path);
    test_xplugin_impl(registry);

    std::vector plugin_list;
    for (const auto &entry : std::filesystem::directory_iterator(path))
    {
        if (entry.path().extension() == get_default_extension())
        {
            plugin_list.push_back(entry.path());
        }
    }
    
    plugin_registry_type registry2(std::move(plugin_list));
    test_xplugin_impl(registry2);
}

TEST_CASE("test_xregistry_getter")
{

    using base_type = plugin::PluginBase;
    using factory_base_type = xp::xfactory_base;
    using plugin_registry_type = xp::xplugin_registry;
    plugin_registry_type registry("testplugin_a");

    CHECK_EQ(registry.size(), 3);
    auto factory_01 = registry["plugin_01"];
    auto factory_02 = registry["plugin_02"];
    auto factory_03 = registry["plugin_03"];

    auto plugin_01 = factory_01->create(1, "a");
    auto plugin_02 = factory_02->create(2, "b");
    auto plugin_03 = factory_03->create(3, "c");

    CHECK(plugin_01);
    CHECK(plugin_02);
    CHECK(plugin_03);

    CHECK_EQ(plugin_01->name(), "Plugin01");
    CHECK_EQ(plugin_02->name(), "Plugin02");
    CHECK_EQ(plugin_03->name(), "Plugin03");

    CHECK_EQ(plugin_01->greet(), "hello from Plugin01");
    CHECK_EQ(plugin_02->greet(), "hello from Plugin02");
    CHECK_EQ(plugin_03->greet(), "hello from Plugin03");
}

TEST_CASE("test_xregistry_open_same_lib_multiple_times")
{
    using base_type = plugin::PluginBase;
    using factory_base_type = xp::xfactory_base;
    using plugin_registry_type = xp::xplugin_registry;

    std::vector registries(1000);
    for (auto ®istry : registries)
    {
        registry = new plugin_registry_type("testplugin_a");
    }

    for (auto ®istry : registries)
    {
        CHECK_EQ(registry->size(), 3);

        auto factory_01 = registry->operator[]("plugin_01");
        auto factory_02 = registry->operator[]("plugin_02");
        auto factory_03 = registry->operator[]("plugin_03");

        auto plugin_01 = factory_01->create(1, "a");
        auto plugin_02 = factory_02->create(2, "b");
        auto plugin_03 = factory_03->create(3, "c");

        CHECK(plugin_01);
        CHECK(plugin_02);
        CHECK(plugin_03);

        CHECK_EQ(plugin_01->name(), "Plugin01");
        CHECK_EQ(plugin_02->name(), "Plugin02");
        CHECK_EQ(plugin_03->name(), "Plugin03");
    }

    for (auto ®istry : registries)
    {
        delete registry;
    }
}

#ifndef XPLUGIN_NO_THREADS
TEST_CASE("parallel_access")
{
    using base_type = plugin::PluginBase;
    using factory_base_type = xp::xfactory_base;
    using plugin_registry_type = xp::xthread_save_plugin_registry;

    for (std::size_t i = 0; i < 1000; ++i)
    {
        plugin_registry_type registry("testplugin_a");
        auto f = [&]() {
            auto factory_01 = registry["plugin_01"];
            auto factory_02 = registry["plugin_02"];
            auto factory_03 = registry["plugin_03"];

            auto plugin_01 = factory_01->create(1, "a");
            auto plugin_02 = factory_02->create(2, "b");
            auto plugin_03 = factory_03->create(3, "c");

            CHECK(plugin_01);
            CHECK(plugin_02);
            CHECK(plugin_03);

            CHECK_EQ(plugin_01->name(), "Plugin01");
            CHECK_EQ(plugin_02->name(), "Plugin02");
            CHECK_EQ(plugin_03->name(), "Plugin03");
        };
        std::thread thread1(f);
        std::thread thread2(f);
        thread1.join();
        thread2.join();
    }
}
#endif // XPLUGIN_NO_THREADS

#ifndef XPLUGIN_NO_THREADS
TEST_CASE("parallel_iterator_access")
{
    using base_type = plugin::PluginBase;
    using factory_base_type = xp::xfactory_base;
    using plugin_registry_type = xp::xthread_save_plugin_registry;

    for (std::size_t i = 0; i < 1000; ++i)
    {
        plugin_registry_type registry("testplugin_a");
        auto f = [®istry]() {
            for (auto name_factory : registry)
            {
                auto name = name_factory.first;
                auto factory = name_factory.second;

                CHECK(name[0] == 'p');
                CHECK(factory);
                auto plugin = factory->create(1, "a");
                CHECK(plugin);
                CHECK_EQ(plugin->name()[0], 'P');
            }
        };
        std::thread thread1(f);
        std::thread thread2(f);
        thread1.join();
        thread2.join();
    }
}
#endif // XPLUGIN_NO_THREADS

Web Proxy Viewer  |  New URL  |  Original Page