2026-01-22 14:56:51 -05:00
|
|
|
#include <gtest/gtest.h>
|
2026-04-07 14:05:04 -04:00
|
|
|
#include "logos_core.h"
|
2026-01-22 14:56:51 -05:00
|
|
|
#include "plugin_manager.h"
|
2026-03-27 12:33:38 -04:00
|
|
|
#include "plugin_registry.h"
|
2026-04-07 14:05:04 -04:00
|
|
|
#include <cstdlib>
|
2026-01-22 14:56:51 -05:00
|
|
|
#include <cstring>
|
2026-03-26 18:53:05 -03:00
|
|
|
#include <fstream>
|
2026-04-07 14:05:04 -04:00
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
|
#include <set>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <filesystem>
|
2026-01-22 14:56:51 -05:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
static void clearPluginState()
|
|
|
|
|
{
|
2026-03-27 12:33:38 -04:00
|
|
|
PluginManager::terminateAll();
|
|
|
|
|
PluginManager::registry().clear();
|
|
|
|
|
}
|
2026-02-23 15:32:58 -03:00
|
|
|
|
2026-01-22 14:56:51 -05:00
|
|
|
class PluginManagerTest : public ::testing::Test {
|
|
|
|
|
protected:
|
2026-04-07 14:05:04 -04:00
|
|
|
void SetUp() override
|
|
|
|
|
{
|
2026-03-27 12:33:38 -04:00
|
|
|
clearPluginState();
|
2026-01-22 14:56:51 -05:00
|
|
|
}
|
2026-03-23 13:55:48 -04:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
void TearDown() override
|
|
|
|
|
{
|
2026-03-27 12:33:38 -04:00
|
|
|
clearPluginState();
|
2026-01-22 14:56:51 -05:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, GetLoadedPlugins_ReturnsEmptyList)
|
|
|
|
|
{
|
|
|
|
|
EXPECT_TRUE(PluginManager::registry().loadedPluginNames().empty());
|
2026-01-22 14:56:51 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, GetKnownPlugins_ReturnsEmptyList)
|
|
|
|
|
{
|
|
|
|
|
EXPECT_TRUE(PluginManager::registry().knownPluginNames().empty());
|
2026-01-22 14:56:51 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, GetKnownPlugins_ReturnsCorrectEntries)
|
|
|
|
|
{
|
2026-03-27 12:33:38 -04:00
|
|
|
PluginManager::registry().registerPlugin("plugin1", "/path/to/plugin1.dylib");
|
|
|
|
|
PluginManager::registry().registerPlugin("plugin2", "/path/to/plugin2.dylib");
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
ASSERT_EQ(PluginManager::registry().knownPluginNames().size(), 2u);
|
|
|
|
|
EXPECT_EQ(PluginManager::registry().pluginPath("plugin1"), "/path/to/plugin1.dylib");
|
|
|
|
|
EXPECT_EQ(PluginManager::registry().pluginPath("plugin2"), "/path/to/plugin2.dylib");
|
2026-01-22 14:56:51 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, IsPluginLoaded_ReturnsFalseForUnloaded)
|
|
|
|
|
{
|
2026-01-22 14:56:51 -05:00
|
|
|
EXPECT_FALSE(PluginManager::isPluginLoaded("nonexistent_plugin"));
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, IsPluginKnown_ReturnsFalseForUnknown)
|
|
|
|
|
{
|
2026-03-27 12:33:38 -04:00
|
|
|
EXPECT_FALSE(PluginManager::registry().isKnown("nonexistent_plugin"));
|
2026-01-22 14:56:51 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, IsPluginKnown_ReturnsTrueForKnown)
|
|
|
|
|
{
|
2026-03-27 12:33:38 -04:00
|
|
|
PluginManager::registry().registerPlugin("test_plugin", "/path/to/plugin");
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-03-27 12:33:38 -04:00
|
|
|
EXPECT_TRUE(PluginManager::registry().isKnown("test_plugin"));
|
2026-01-22 14:56:51 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, GetLoadedPluginsCStr_ReturnsNullTerminatedArrayWhenEmpty)
|
|
|
|
|
{
|
2026-01-22 14:56:51 -05:00
|
|
|
char** result = PluginManager::getLoadedPluginsCStr();
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-01-22 14:56:51 -05:00
|
|
|
ASSERT_NE(result, nullptr);
|
|
|
|
|
EXPECT_EQ(result[0], nullptr);
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-01-22 14:56:51 -05:00
|
|
|
delete[] result;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, GetKnownPluginsCStr_ReturnsNullTerminatedArrayWhenEmpty)
|
|
|
|
|
{
|
2026-01-22 14:56:51 -05:00
|
|
|
char** result = PluginManager::getKnownPluginsCStr();
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-01-22 14:56:51 -05:00
|
|
|
ASSERT_NE(result, nullptr);
|
|
|
|
|
EXPECT_EQ(result[0], nullptr);
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-01-22 14:56:51 -05:00
|
|
|
delete[] result;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, GetKnownPluginsCStr_ReturnsCorrectArray)
|
|
|
|
|
{
|
2026-03-27 12:33:38 -04:00
|
|
|
PluginManager::registry().registerPlugin("plugin1", "/path/to/plugin1");
|
|
|
|
|
PluginManager::registry().registerPlugin("plugin2", "/path/to/plugin2");
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-01-22 14:56:51 -05:00
|
|
|
char** result = PluginManager::getKnownPluginsCStr();
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-01-22 14:56:51 -05:00
|
|
|
ASSERT_NE(result, nullptr);
|
|
|
|
|
ASSERT_NE(result[0], nullptr);
|
|
|
|
|
ASSERT_NE(result[1], nullptr);
|
2026-03-25 21:09:59 -04:00
|
|
|
EXPECT_EQ(result[2], nullptr);
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
std::set<std::string> plugins;
|
|
|
|
|
plugins.insert(result[0]);
|
|
|
|
|
plugins.insert(result[1]);
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
EXPECT_TRUE(plugins.count("plugin1"));
|
|
|
|
|
EXPECT_TRUE(plugins.count("plugin2"));
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-01-22 14:56:51 -05:00
|
|
|
delete[] result[0];
|
|
|
|
|
delete[] result[1];
|
|
|
|
|
delete[] result;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, LoadPlugin_ReturnsFalseForUnknownPlugin)
|
|
|
|
|
{
|
2026-01-22 14:56:51 -05:00
|
|
|
bool result = PluginManager::loadPlugin("nonexistent_plugin");
|
|
|
|
|
EXPECT_FALSE(result);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, UnloadPlugin_ReturnsFalseForNotLoaded)
|
|
|
|
|
{
|
2026-01-22 14:56:51 -05:00
|
|
|
bool result = PluginManager::unloadPlugin("nonexistent_plugin");
|
|
|
|
|
EXPECT_FALSE(result);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, ResolveDependencies_ReturnsEmptyForEmptyInput)
|
|
|
|
|
{
|
|
|
|
|
std::vector<std::string> result = PluginManager::resolveDependencies({});
|
|
|
|
|
EXPECT_TRUE(result.empty());
|
2026-02-03 11:29:38 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, ResolveDependencies_ReturnsEmptyForUnknownPlugin)
|
|
|
|
|
{
|
|
|
|
|
std::vector<std::string> requested = {"unknown_plugin"};
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
std::vector<std::string> result = PluginManager::resolveDependencies(requested);
|
|
|
|
|
EXPECT_TRUE(result.empty());
|
2026-02-03 11:29:38 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, ResolveDependencies_ReturnsSinglePluginWithNoDeps)
|
|
|
|
|
{
|
2026-03-27 12:33:38 -04:00
|
|
|
PluginManager::registry().registerPlugin("plugin_a", "/path/to/plugin_a");
|
2026-03-27 14:22:00 -04:00
|
|
|
PluginManager::registry().registerDependencies("plugin_a", {});
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
std::vector<std::string> requested = {"plugin_a"};
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
std::vector<std::string> result = PluginManager::resolveDependencies(requested);
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
ASSERT_EQ(result.size(), 1u);
|
|
|
|
|
EXPECT_EQ(result[0], "plugin_a");
|
2026-02-03 11:29:38 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, ResolveDependencies_ReturnsCorrectOrder)
|
|
|
|
|
{
|
2026-03-27 12:33:38 -04:00
|
|
|
PluginManager::registry().registerPlugin("plugin_a", "/path/to/plugin_a");
|
|
|
|
|
PluginManager::registry().registerPlugin("plugin_b", "/path/to/plugin_b");
|
2026-03-27 14:22:00 -04:00
|
|
|
PluginManager::registry().registerDependencies("plugin_a", {"plugin_b"});
|
|
|
|
|
PluginManager::registry().registerDependencies("plugin_b", {});
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
std::vector<std::string> requested = {"plugin_a"};
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
std::vector<std::string> result = PluginManager::resolveDependencies(requested);
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
ASSERT_EQ(result.size(), 2u);
|
|
|
|
|
EXPECT_EQ(result[0], "plugin_b");
|
|
|
|
|
EXPECT_EQ(result[1], "plugin_a");
|
2026-02-03 11:29:38 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, ResolveDependencies_HandlesTransitiveDeps)
|
|
|
|
|
{
|
2026-03-27 12:33:38 -04:00
|
|
|
PluginManager::registry().registerPlugin("plugin_a", "/path/to/plugin_a");
|
|
|
|
|
PluginManager::registry().registerPlugin("plugin_b", "/path/to/plugin_b");
|
|
|
|
|
PluginManager::registry().registerPlugin("plugin_c", "/path/to/plugin_c");
|
2026-03-27 14:22:00 -04:00
|
|
|
PluginManager::registry().registerDependencies("plugin_a", {"plugin_b"});
|
|
|
|
|
PluginManager::registry().registerDependencies("plugin_b", {"plugin_c"});
|
|
|
|
|
PluginManager::registry().registerDependencies("plugin_c", {});
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
std::vector<std::string> requested = {"plugin_a"};
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
std::vector<std::string> result = PluginManager::resolveDependencies(requested);
|
2026-03-25 21:09:59 -04:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
ASSERT_EQ(result.size(), 3u);
|
|
|
|
|
EXPECT_EQ(result[0], "plugin_c");
|
|
|
|
|
EXPECT_EQ(result[1], "plugin_b");
|
|
|
|
|
EXPECT_EQ(result[2], "plugin_a");
|
2026-02-03 11:29:38 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, LoadPluginWithDependencies_AbortsForNull)
|
|
|
|
|
{
|
2026-03-25 09:31:06 -04:00
|
|
|
EXPECT_DEATH(logos_core_load_plugin_with_dependencies(nullptr), "");
|
2026-02-03 11:29:38 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, LoadPluginWithDependencies_ReturnsZeroForUnknown)
|
|
|
|
|
{
|
2026-02-03 11:29:38 -05:00
|
|
|
int result = logos_core_load_plugin_with_dependencies("unknown_plugin");
|
|
|
|
|
EXPECT_EQ(result, 0);
|
|
|
|
|
}
|
2026-02-03 16:37:59 -05:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, SetPluginsDir_SetsFirstDirectory)
|
|
|
|
|
{
|
2026-03-26 18:53:05 -03:00
|
|
|
PluginManager::setPluginsDir("/tmp/test_plugins");
|
2026-04-07 14:05:04 -04:00
|
|
|
ASSERT_EQ(PluginManager::registry().pluginsDirs().size(), 1u);
|
|
|
|
|
EXPECT_EQ(PluginManager::registry().pluginsDirs()[0], "/tmp/test_plugins");
|
2026-03-26 18:53:05 -03:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, AddPluginsDir_AppendsDirectory)
|
|
|
|
|
{
|
2026-03-26 18:53:05 -03:00
|
|
|
PluginManager::setPluginsDir("/tmp/dir1");
|
|
|
|
|
PluginManager::addPluginsDir("/tmp/dir2");
|
|
|
|
|
PluginManager::addPluginsDir("/tmp/dir3");
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
ASSERT_EQ(PluginManager::registry().pluginsDirs().size(), 3u);
|
|
|
|
|
EXPECT_EQ(PluginManager::registry().pluginsDirs()[0], "/tmp/dir1");
|
|
|
|
|
EXPECT_EQ(PluginManager::registry().pluginsDirs()[1], "/tmp/dir2");
|
|
|
|
|
EXPECT_EQ(PluginManager::registry().pluginsDirs()[2], "/tmp/dir3");
|
2026-03-26 18:53:05 -03:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, GetPluginsDirs_ReturnsEmptyAfterClear)
|
|
|
|
|
{
|
2026-03-26 18:53:05 -03:00
|
|
|
PluginManager::setPluginsDir("/tmp/dir1");
|
2026-03-27 12:33:38 -04:00
|
|
|
clearPluginState();
|
2026-04-07 14:05:04 -04:00
|
|
|
EXPECT_TRUE(PluginManager::registry().pluginsDirs().empty());
|
2026-03-26 18:53:05 -03:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
static std::string make_temp_dir()
|
|
|
|
|
{
|
|
|
|
|
static int counter = 0;
|
|
|
|
|
auto base = std::filesystem::temp_directory_path() / ("logos_pm_test_" + std::to_string(counter++));
|
|
|
|
|
std::filesystem::create_directories(base);
|
|
|
|
|
return base.string();
|
|
|
|
|
}
|
2026-03-26 18:53:05 -03:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
static void createFakeModule(const std::string& parentDir,
|
|
|
|
|
const std::string& moduleName,
|
|
|
|
|
const std::string& mainFile,
|
|
|
|
|
const std::string& type = "core")
|
|
|
|
|
{
|
|
|
|
|
const auto modDir = std::filesystem::path(parentDir) / moduleName;
|
|
|
|
|
std::filesystem::create_directories(modDir);
|
2026-03-26 18:53:05 -03:00
|
|
|
|
2026-03-27 12:33:38 -04:00
|
|
|
nlohmann::json manifest;
|
2026-04-07 14:05:04 -04:00
|
|
|
manifest["name"] = moduleName;
|
2026-03-26 18:53:05 -03:00
|
|
|
manifest["version"] = "1.0.0";
|
2026-04-07 14:05:04 -04:00
|
|
|
manifest["type"] = type;
|
|
|
|
|
manifest["main"] = mainFile;
|
2026-03-26 18:53:05 -03:00
|
|
|
manifest["description"] = "Fake test module";
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
std::ofstream mf(modDir / "manifest.json");
|
2026-03-27 12:33:38 -04:00
|
|
|
mf << manifest.dump();
|
2026-03-26 18:53:05 -03:00
|
|
|
mf.close();
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
std::ofstream bf(modDir / mainFile);
|
2026-03-26 18:53:05 -03:00
|
|
|
bf << "fake";
|
|
|
|
|
bf.close();
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, DiscoverInstalledModules_DoesNotCrashWithEmptyDir)
|
|
|
|
|
{
|
|
|
|
|
std::string tmpDir = make_temp_dir();
|
2026-03-26 18:53:05 -03:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
PluginManager::setPluginsDir(tmpDir.c_str());
|
2026-03-26 18:53:05 -03:00
|
|
|
PluginManager::discoverInstalledModules();
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
EXPECT_TRUE(PluginManager::registry().knownPluginNames().empty());
|
2026-03-26 18:53:05 -03:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, DiscoverInstalledModules_DoesNotCrashWithNonexistentDir)
|
|
|
|
|
{
|
2026-03-26 18:53:05 -03:00
|
|
|
PluginManager::setPluginsDir("/tmp/nonexistent_dir_12345");
|
|
|
|
|
PluginManager::discoverInstalledModules();
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
EXPECT_TRUE(PluginManager::registry().knownPluginNames().empty());
|
2026-03-26 18:53:05 -03:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, DiscoverInstalledModules_FindsFakeModulesWithoutCrash)
|
|
|
|
|
{
|
|
|
|
|
std::string tmpDir = make_temp_dir();
|
2026-03-26 18:53:05 -03:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
createFakeModule(tmpDir, "fake_module_a", "fake_module_a_plugin.so");
|
|
|
|
|
createFakeModule(tmpDir, "fake_module_b", "fake_module_b_plugin.so");
|
2026-03-26 18:53:05 -03:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
PluginManager::setPluginsDir(tmpDir.c_str());
|
2026-03-26 18:53:05 -03:00
|
|
|
PluginManager::discoverInstalledModules();
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
EXPECT_TRUE(PluginManager::registry().knownPluginNames().empty());
|
2026-03-26 18:53:05 -03:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, DiscoverInstalledModules_IgnoresModulesWithoutManifest)
|
|
|
|
|
{
|
|
|
|
|
std::string tmpDir = make_temp_dir();
|
2026-03-26 18:53:05 -03:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
const auto modDir = std::filesystem::path(tmpDir) / "no_manifest_module";
|
|
|
|
|
std::filesystem::create_directories(modDir);
|
|
|
|
|
std::ofstream bf(modDir / "plugin.so");
|
2026-03-26 18:53:05 -03:00
|
|
|
bf << "fake";
|
|
|
|
|
bf.close();
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
PluginManager::setPluginsDir(tmpDir.c_str());
|
2026-03-26 18:53:05 -03:00
|
|
|
PluginManager::discoverInstalledModules();
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
EXPECT_TRUE(PluginManager::registry().knownPluginNames().empty());
|
2026-03-26 18:53:05 -03:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, DiscoverInstalledModules_IgnoresUiTypeModules)
|
|
|
|
|
{
|
|
|
|
|
std::string tmpDir = make_temp_dir();
|
2026-03-26 18:53:05 -03:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
createFakeModule(tmpDir, "ui_module", "ui_module_plugin.so", "ui");
|
2026-03-26 18:53:05 -03:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
PluginManager::setPluginsDir(tmpDir.c_str());
|
2026-03-26 18:53:05 -03:00
|
|
|
PluginManager::discoverInstalledModules();
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
EXPECT_TRUE(PluginManager::registry().knownPluginNames().empty());
|
2026-03-26 18:53:05 -03:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, DiscoverInstalledModules_MultipleDirectories)
|
|
|
|
|
{
|
|
|
|
|
std::string tmpDir1 = make_temp_dir();
|
|
|
|
|
std::string tmpDir2 = make_temp_dir();
|
2026-03-26 18:53:05 -03:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
createFakeModule(tmpDir1, "module_in_dir1", "module_in_dir1_plugin.so");
|
|
|
|
|
createFakeModule(tmpDir2, "module_in_dir2", "module_in_dir2_plugin.so");
|
2026-03-26 18:53:05 -03:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
PluginManager::setPluginsDir(tmpDir1.c_str());
|
|
|
|
|
PluginManager::addPluginsDir(tmpDir2.c_str());
|
2026-03-26 18:53:05 -03:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
ASSERT_EQ(PluginManager::registry().pluginsDirs().size(), 2u);
|
2026-03-26 18:53:05 -03:00
|
|
|
|
|
|
|
|
PluginManager::discoverInstalledModules();
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
EXPECT_TRUE(PluginManager::registry().knownPluginNames().empty());
|
2026-03-26 18:53:05 -03:00
|
|
|
}
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
TEST_F(PluginManagerTest, DiscoverInstalledModules_InvalidManifestJson)
|
|
|
|
|
{
|
|
|
|
|
std::string tmpDir = make_temp_dir();
|
2026-03-26 18:53:05 -03:00
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
const auto modDir = std::filesystem::path(tmpDir) / "bad_manifest_module";
|
|
|
|
|
std::filesystem::create_directories(modDir);
|
|
|
|
|
std::ofstream mf(modDir / "manifest.json");
|
2026-03-26 18:53:05 -03:00
|
|
|
mf << "{ this is not valid json }}}";
|
|
|
|
|
mf.close();
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
PluginManager::setPluginsDir(tmpDir.c_str());
|
2026-03-26 18:53:05 -03:00
|
|
|
PluginManager::discoverInstalledModules();
|
|
|
|
|
|
2026-04-07 14:05:04 -04:00
|
|
|
EXPECT_TRUE(PluginManager::registry().knownPluginNames().empty());
|
2026-03-26 18:53:05 -03:00
|
|
|
}
|