| #include "config.h" |
| |
| #include "log_manager.hpp" |
| #include "paths.hpp" |
| |
| #include <phosphor-logging/commit.hpp> |
| #include <sdbusplus/async.hpp> |
| #include <sdbusplus/server/manager.hpp> |
| #include <xyz/openbmc_project/Logging/Entry/client.hpp> |
| #include <xyz/openbmc_project/Logging/event.hpp> |
| |
| #include <thread> |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| namespace phosphor::logging::test |
| { |
| using LoggingCleared = sdbusplus::event::xyz::openbmc_project::Logging::Cleared; |
| using LoggingEntry = sdbusplus::client::xyz::openbmc_project::logging::Entry<>; |
| |
| // Fixture to spawn the log-manager for dbus-based testing. |
| class TestLogManagerDbus : public ::testing::Test |
| { |
| protected: |
| // Create the daemon and sdbusplus::async::contexts. |
| void SetUp() override |
| { |
| // The daemon requires directories to be created first. |
| std::filesystem::create_directories(phosphor::logging::paths::error()); |
| |
| data = std::make_unique<fixture_data>(); |
| } |
| |
| // Stop the daemon, etc. |
| void TearDown() override |
| { |
| data.reset(); |
| } |
| |
| /** Run a client task, wait for it to complete, and stop daemon. */ |
| template <typename T> |
| void run(T&& t) |
| { |
| data->client_ctx.spawn(std::move(t) | stdexec::then([this]() { |
| data->stop(data->client_ctx); |
| })); |
| data->client_ctx.run(); |
| } |
| |
| // Data for the fixture. |
| struct fixture_data |
| { |
| fixture_data() : |
| client_ctx(), server_ctx(), objManager(server_ctx, OBJ_LOGGING), |
| iMgr(server_ctx, OBJ_INTERNAL), mgr(server_ctx, OBJ_LOGGING, iMgr) |
| { |
| // Create a thread for the daemon. |
| task = std::thread([this]() { |
| server_ctx.request_name(BUSNAME_LOGGING); |
| server_ctx.run(); |
| }); |
| } |
| |
| ~fixture_data() |
| { |
| // Stop the server and wait for the thread to exit. |
| stop(server_ctx); |
| task.join(); |
| } |
| |
| // Spawn a task to gracefully shutdown an sdbusplus::async::context |
| static void stop(sdbusplus::async::context& ctx) |
| { |
| ctx.spawn(stdexec::just() | |
| stdexec::then([&ctx]() { ctx.request_stop(); })); |
| } |
| |
| sdbusplus::async::context client_ctx; |
| sdbusplus::async::context server_ctx; |
| sdbusplus::server::manager_t objManager; |
| internal::Manager iMgr; |
| Manager mgr; |
| std::thread task; |
| }; |
| |
| std::unique_ptr<fixture_data> data; |
| }; |
| |
| // Ensure we can successfully create and throw an sdbusplus event. |
| TEST_F(TestLogManagerDbus, GenerateSimpleEvent) |
| { |
| EXPECT_THROW( |
| { throw LoggingCleared("NUMBER_OF_LOGS", 1); }, LoggingCleared); |
| return; |
| } |
| |
| // Call the synchronous version of the commit function and verify that the |
| // daemon gives us a path. |
| TEST_F(TestLogManagerDbus, CallCommitSync) |
| { |
| auto path = lg2::commit(LoggingCleared("NUMBER_OF_LOGS", 3)); |
| ASSERT_FALSE(path.str.empty()); |
| EXPECT_THAT(path.str, |
| ::testing::StartsWith( |
| std::filesystem::path(LoggingEntry::namespace_path::value) / |
| LoggingEntry::namespace_path::entry)); |
| } |
| |
| // Call the asynchronous version of the commit function and verify that the |
| // metadata is saved correctly. |
| TEST_F(TestLogManagerDbus, CallCommitAsync) |
| { |
| sdbusplus::message::object_path path{}; |
| std::string log_count{}; |
| |
| auto create_log = [this, &path, &log_count]() -> sdbusplus::async::task<> { |
| // Log an event. |
| path = co_await lg2::commit(data->client_ctx, |
| LoggingCleared("NUMBER_OF_LOGS", 6)); |
| |
| // Grab the additional data. |
| auto additionalData = co_await LoggingEntry(data->client_ctx) |
| .service(Entry::default_service) |
| .path(path.str) |
| .additional_data(); |
| |
| // Extract the NUMBER_OF_LOGS. |
| for (const auto& value : additionalData) |
| { |
| if (value.starts_with("NUMBER_OF_LOGS=")) |
| { |
| log_count = value.substr(value.find_first_of('=') + 1); |
| } |
| } |
| |
| co_return; |
| }; |
| |
| run(create_log()); |
| |
| ASSERT_FALSE(path.str.empty()); |
| ASSERT_FALSE(log_count.empty()); |
| |
| EXPECT_THAT(path.str, |
| ::testing::StartsWith( |
| std::filesystem::path(LoggingEntry::namespace_path::value) / |
| LoggingEntry::namespace_path::entry)); |
| |
| EXPECT_EQ(log_count, "6"); |
| } |
| |
| } // namespace phosphor::logging::test |