lg2: commit: add methods for new sdbusplus events

Add implementations and test cases for the `lg2::commit` functions.

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I25a87fd65738e4debbe98f3473709f77d51777e9
diff --git a/test/basic_event_commit.cpp b/test/basic_event_commit.cpp
deleted file mode 100644
index fc454d9..0000000
--- a/test/basic_event_commit.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <phosphor-logging/commit.hpp>
-#include <xyz/openbmc_project/Logging/event.hpp>
-
-#include <gtest/gtest.h>
-
-namespace phosphor::logging::test
-{
-
-using LoggingCleared = sdbusplus::event::xyz::openbmc_project::Logging::Cleared;
-
-TEST(TestBasicEventCommit, GenerateSimpleEvent)
-{
-    EXPECT_THROW(
-        { throw LoggingCleared("NUMBER_OF_LOGS", 1); }, LoggingCleared);
-    return;
-}
-
-TEST(TestBasicEventCommit, CallCommit)
-{
-    lg2::commit(LoggingCleared("NUMBER_OF_LOGS", 3));
-}
-
-} // namespace phosphor::logging::test
diff --git a/test/log_manager_dbus_tests.cpp b/test/log_manager_dbus_tests.cpp
new file mode 100644
index 0000000..ac33ded
--- /dev/null
+++ b/test/log_manager_dbus_tests.cpp
@@ -0,0 +1,153 @@
+#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
diff --git a/test/meson.build b/test/meson.build
index bdf3cdb..822a4f8 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -24,8 +24,8 @@
 endif
 
 tests = [
-    'basic_event_commit',
     'extensions_test',
+    'log_manager_dbus_tests',
     'remote_logging_test_address',
     'remote_logging_test_config',
     'remote_logging_test_port',