mirror of
https://github.com/logos-co/logos-liblogos.git
synced 2026-08-27 12:51:10 +00:00
175 lines
5.9 KiB
C++
175 lines
5.9 KiB
C++
#include <gtest/gtest.h>
|
|
#include "logos_core.h"
|
|
#include "qt_test_adapter.h"
|
|
#include <cstring>
|
|
#include <string>
|
|
|
|
static void clearModuleState() {
|
|
logos_core_terminate_all();
|
|
logos_core_clear();
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
logos_core_init(argc, argv);
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
int result = RUN_ALL_TESTS();
|
|
logos_core_cleanup();
|
|
return result;
|
|
}
|
|
|
|
class AppLifecycleTest : public ::testing::Test {
|
|
protected:
|
|
void SetUp() override {
|
|
clearModuleState();
|
|
}
|
|
|
|
void TearDown() override {
|
|
clearModuleState();
|
|
}
|
|
};
|
|
|
|
// =============================================================================
|
|
// Initialization Tests
|
|
// =============================================================================
|
|
|
|
TEST_F(AppLifecycleTest, Init_LibraryIsUsableAfterInit) {
|
|
EXPECT_EQ(logos_core_get_modules_dirs_count(), 0);
|
|
}
|
|
|
|
// =============================================================================
|
|
// Module Directory Tests
|
|
// =============================================================================
|
|
|
|
TEST_F(AppLifecycleTest, AddModulesDir_SetsDirectory) {
|
|
const char* testDir = "/test/modules";
|
|
|
|
logos_core_add_modules_dir(testDir);
|
|
|
|
ASSERT_EQ(logos_core_get_modules_dirs_count(), 1);
|
|
char* dir = logos_core_get_modules_dir_at(0);
|
|
ASSERT_NE(dir, nullptr);
|
|
EXPECT_EQ(std::string(dir), std::string(testDir));
|
|
delete[] dir;
|
|
}
|
|
|
|
TEST_F(AppLifecycleTest, AddModulesDir_AppendsDirectory) {
|
|
logos_core_add_modules_dir("/dir1");
|
|
logos_core_add_modules_dir("/dir2");
|
|
|
|
ASSERT_EQ(logos_core_get_modules_dirs_count(), 2);
|
|
|
|
char* d0 = logos_core_get_modules_dir_at(0);
|
|
char* d1 = logos_core_get_modules_dir_at(1);
|
|
ASSERT_NE(d0, nullptr);
|
|
ASSERT_NE(d1, nullptr);
|
|
EXPECT_EQ(std::string(d0), "/dir1");
|
|
EXPECT_EQ(std::string(d1), "/dir2");
|
|
delete[] d0;
|
|
delete[] d1;
|
|
}
|
|
|
|
TEST_F(AppLifecycleTest, AddModulesDir_NoDuplicates) {
|
|
logos_core_add_modules_dir("/test");
|
|
logos_core_add_modules_dir("/test");
|
|
|
|
EXPECT_EQ(logos_core_get_modules_dirs_count(), 1);
|
|
}
|
|
|
|
// =============================================================================
|
|
// Cleanup Tests
|
|
// =============================================================================
|
|
|
|
TEST_F(AppLifecycleTest, Cleanup_ClearsGlobals) {
|
|
logos_core_register_module("test", "/path/to/test");
|
|
logos_core_add_modules_dir("/test");
|
|
|
|
clearModuleState();
|
|
|
|
char** loaded = logos_core_get_loaded_modules();
|
|
ASSERT_NE(loaded, nullptr);
|
|
EXPECT_EQ(loaded[0], nullptr);
|
|
delete[] loaded;
|
|
|
|
char** known = logos_core_get_known_modules();
|
|
ASSERT_NE(known, nullptr);
|
|
EXPECT_EQ(known[0], nullptr);
|
|
delete[] known;
|
|
}
|
|
|
|
TEST_F(AppLifecycleTest, Cleanup_ClearsState) {
|
|
EXPECT_TRUE(true) << "Cleanup behavior is tested indirectly through integration tests";
|
|
}
|
|
|
|
// =============================================================================
|
|
// Start Function Tests
|
|
// =============================================================================
|
|
|
|
TEST_F(AppLifecycleTest, Start_UsesCustomModulesDirs) {
|
|
logos_core_add_modules_dir("/custom/modules");
|
|
|
|
logos_core_start();
|
|
|
|
ASSERT_EQ(logos_core_get_modules_dirs_count(), 1);
|
|
char* dir = logos_core_get_modules_dir_at(0);
|
|
ASSERT_NE(dir, nullptr);
|
|
EXPECT_EQ(std::string(dir), "/custom/modules");
|
|
delete[] dir;
|
|
}
|
|
|
|
// =============================================================================
|
|
// Access Policy Tests
|
|
// =============================================================================
|
|
//
|
|
// logos_core_set_access_policy stores the policy; core parses it and
|
|
// registers the concrete per-target restrictions with capability_module
|
|
// once that module loads (inside logos_core_start). The parser is unit-
|
|
// tested in test_access_policy.cpp, and the enforcement (deny token
|
|
// issuance for a disallowed caller) is tested in capability_module's own
|
|
// suite. Here we only pin the C-API setter contract that holds without a
|
|
// running capability_module: the call accepts a well-formed policy, an
|
|
// empty string, and NULL (the documented "clear" signal) without crashing
|
|
// or aborting, and without disturbing unrelated core state.
|
|
|
|
TEST_F(AppLifecycleTest, SetAccessPolicy_AcceptsValidPolicyWithoutCrashing) {
|
|
const char* policy =
|
|
"{\"version\":1,\"mode\":\"enforce\",\"restrictions\":{"
|
|
"\"package_manager\":{\"allowedCallers\":[\"package_manager_ui\"]},"
|
|
"\"package_downloader\":{\"allowedCallers\":[\"package_manager_ui\"]}}}";
|
|
|
|
// No-op today: the only contract is "doesn't crash, doesn't throw".
|
|
EXPECT_NO_THROW(logos_core_set_access_policy(policy));
|
|
}
|
|
|
|
TEST_F(AppLifecycleTest, SetAccessPolicy_AcceptsEmptyStringAsClear) {
|
|
EXPECT_NO_THROW(logos_core_set_access_policy(""));
|
|
}
|
|
|
|
TEST_F(AppLifecycleTest, SetAccessPolicy_AcceptsNullAsClear) {
|
|
// Unlike the module-name setters, this one must NOT abort on NULL —
|
|
// NULL is the documented "clear the policy" signal.
|
|
EXPECT_NO_THROW(logos_core_set_access_policy(nullptr));
|
|
}
|
|
|
|
TEST_F(AppLifecycleTest, SetAccessPolicy_IsIdempotentAcrossRepeatedCalls) {
|
|
// Setting then clearing then re-setting must be safe in any order.
|
|
EXPECT_NO_THROW(logos_core_set_access_policy("{\"version\":1}"));
|
|
EXPECT_NO_THROW(logos_core_set_access_policy(nullptr));
|
|
EXPECT_NO_THROW(logos_core_set_access_policy(""));
|
|
EXPECT_NO_THROW(logos_core_set_access_policy("{\"version\":1}"));
|
|
}
|
|
|
|
TEST_F(AppLifecycleTest, SetAccessPolicy_DoesNotDisturbModulesDirs) {
|
|
logos_core_add_modules_dir("/custom/modules");
|
|
ASSERT_EQ(logos_core_get_modules_dirs_count(), 1);
|
|
|
|
logos_core_set_access_policy(
|
|
"{\"version\":1,\"mode\":\"enforce\",\"restrictions\":{}}");
|
|
|
|
// The policy setter touches nothing else in core state.
|
|
EXPECT_EQ(logos_core_get_modules_dirs_count(), 1);
|
|
char* dir = logos_core_get_modules_dir_at(0);
|
|
ASSERT_NE(dir, nullptr);
|
|
EXPECT_EQ(std::string(dir), "/custom/modules");
|
|
delete[] dir;
|
|
}
|