Pull file path into elog Entry constructor

The path property on the FilePath interfaces was previously being set
after the entry object was created, sending a properties changed signal
after the interfaces added signal.

Since the path can be known at the time the entry is constructed, pass
it into the constructor instead so no extra signal will be sent.

Change-Id: I1150236d23cecb1df78e3fb4ae641c75b488af37
diff --git a/elog_entry.hpp b/elog_entry.hpp
index db9d9da..38c4e84 100644
--- a/elog_entry.hpp
+++ b/elog_entry.hpp
@@ -51,7 +51,7 @@
      *         Defer signal registration (pass true for deferSignal to the
      *         base class) until after the properties are set.
      *  @param[in] bus - Bus to attach to.
-     *  @param[in] path - Path to attach at.
+     *  @param[in] objectPath - Path to attach at.
      *  @param[in] idErr - The error entry id.
      *  @param[in] timestampErr - The commit timestamp.
      *  @param[in] severityErr - The severity of the error.
@@ -59,14 +59,15 @@
      *  @param[in] additionalDataErr - The error metadata.
      *  @param[in] objects - The list of associations.
      *  @param[in] fwVersion - The BMC code version.
+     *  @param[in] filePath - Serialization path
      *  @param[in] parent - The error's parent.
      */
-    Entry(sdbusplus::bus::bus& bus, const std::string& path, uint32_t idErr,
-          uint64_t timestampErr, Level severityErr, std::string&& msgErr,
-          std::vector<std::string>&& additionalDataErr,
+    Entry(sdbusplus::bus::bus& bus, const std::string& objectPath,
+          uint32_t idErr, uint64_t timestampErr, Level severityErr,
+          std::string&& msgErr, std::vector<std::string>&& additionalDataErr,
           AssociationList&& objects, const std::string& fwVersion,
-          internal::Manager& parent) :
-        EntryIfaces(bus, path.c_str(), true),
+          const std::string& filePath, internal::Manager& parent) :
+        EntryIfaces(bus, objectPath.c_str(), true),
         parent(parent)
     {
         id(idErr, true);
@@ -83,6 +84,7 @@
 
         version(fwVersion, true);
         purpose(VersionPurpose::BMC, true);
+        path(filePath, true);
 
         // Emit deferred signal.
         this->emit_object_added();
diff --git a/elog_serialize.cpp b/elog_serialize.cpp
index 3538bd8..087ef40 100644
--- a/elog_serialize.cpp
+++ b/elog_serialize.cpp
@@ -103,9 +103,14 @@
     e.resolution(resolution, true);
 }
 
+fs::path getEntrySerializePath(uint32_t id, const fs::path& dir)
+{
+    return dir / std::to_string(id);
+}
+
 fs::path serialize(const Entry& e, const fs::path& dir)
 {
-    auto path = dir / std::to_string(e.id());
+    auto path = getEntrySerializePath(e.id(), dir);
     std::ofstream os(path.c_str(), std::ios::binary);
     cereal::BinaryOutputArchive oarchive(os);
     oarchive(e);
diff --git a/elog_serialize.hpp b/elog_serialize.hpp
index 9a2d984..720c816 100644
--- a/elog_serialize.hpp
+++ b/elog_serialize.hpp
@@ -32,5 +32,15 @@
  */
 bool deserialize(const fs::path& path, Entry& e);
 
+/** @brief Return the path to serialize a log entry to
+ *  @param[in] id - log entry ID
+ *  @param[in] dir - pathname of directory where the serialized error will
+ *                   be placed.
+ *  @return fs::path - pathname of persisted error file
+ */
+fs::path
+    getEntrySerializePath(uint32_t id,
+                          const fs::path& dir = fs::path(ERRLOG_PERSIST_PATH));
+
 } // namespace logging
 } // namespace phosphor
diff --git a/log_manager.cpp b/log_manager.cpp
index 6513bd9..d12630a 100644
--- a/log_manager.cpp
+++ b/log_manager.cpp
@@ -234,13 +234,13 @@
     AssociationList objects{};
     processMetadata(errMsg, additionalData, objects);
 
-    auto e = std::make_unique<Entry>(busLog, objPath, entryId,
-                                     ms, // Milliseconds since 1970
-                                     errLvl, std::move(errMsg),
-                                     std::move(additionalData),
-                                     std::move(objects), fwVersion, *this);
-    auto path = serialize(*e);
-    e->path(path);
+    auto e = std::make_unique<Entry>(
+        busLog, objPath, entryId,
+        ms, // Milliseconds since 1970
+        errLvl, std::move(errMsg), std::move(additionalData),
+        std::move(objects), fwVersion, getEntrySerializePath(entryId), *this);
+
+    serialize(*e);
 
     if (isQuiesceOnErrorEnabled() && isCalloutPresent(*e))
     {
diff --git a/test/elog_quiesce_test.cpp b/test/elog_quiesce_test.cpp
index ac78974..a80cb91 100644
--- a/test/elog_quiesce_test.cpp
+++ b/test/elog_quiesce_test.cpp
@@ -38,6 +38,7 @@
     uint64_t timestamp{100};
     std::string message{"test error"};
     std::string fwLevel{"level42"};
+    std::string path{"/tmp/99"};
     std::vector<std::string> testData{"no", "callout"};
     phosphor::logging::AssociationList associations{};
 
@@ -50,6 +51,7 @@
                std::move(testData),
                std::move(associations),
                fwLevel,
+               path,
                manager};
 
     EXPECT_EQ(manager.isCalloutPresent(elog), false);
@@ -62,6 +64,7 @@
     uint64_t timestamp{100};
     std::string message{"test error"};
     std::string fwLevel{"level42"};
+    std::string path{"/tmp/99"};
     std::vector<std::string> testData{
         "CALLOUT_INVENTORY_PATH=/xyz/openbmc_project/inventory/system/chassis/"
         "motherboard/powersupply0/"};
@@ -76,6 +79,7 @@
                std::move(testData),
                std::move(associations),
                fwLevel,
+               path,
                manager};
 
     EXPECT_EQ(manager.isCalloutPresent(elog), true);
@@ -88,6 +92,7 @@
     uint64_t timestamp{100};
     std::string message{"test error"};
     std::string fwLevel{"level42"};
+    std::string path{"/tmp/99"};
     std::vector<std::string> testData{
         "CALLOUT_INVENTORY_PATH=/xyz/openbmc_project/inventory/system/chassis/"
         "motherboard/powersupply0/"};
@@ -113,6 +118,7 @@
                std::move(testData),
                std::move(associations),
                fwLevel,
+               path,
                manager};
 
     manager.quiesceOnError(id);
@@ -143,6 +149,7 @@
     uint64_t timestamp{100};
     std::string message{"test error"};
     std::string fwLevel{"level42"};
+    std::string path{"/tmp/99"};
     std::vector<std::string> testData{
         "CALLOUT_INVENTORY_PATH=/xyz/openbmc_project/inventory/system/chassis/"
         "motherboard/powersupply0/"};
@@ -168,6 +175,7 @@
                std::move(testData),
                std::move(associations),
                fwLevel,
+               path,
                manager};
 
     manager.quiesceOnError(id);
@@ -200,6 +208,7 @@
     uint64_t timestamp{100};
     std::string message{"test error"};
     std::string fwLevel{"level42"};
+    std::string path{"/tmp/99"};
     std::vector<std::string> testData{
         "CALLOUT_INVENTORY_PATH=/xyz/openbmc_project/inventory/system/chassis/"
         "motherboard/powersupply0/"};
@@ -225,6 +234,7 @@
                std::move(testData),
                std::move(associations),
                fwLevel,
+               path,
                manager};
 
     manager.quiesceOnError(id);
diff --git a/test/elog_update_ts_test.cpp b/test/elog_update_ts_test.cpp
index 65b1328..d04da04 100644
--- a/test/elog_update_ts_test.cpp
+++ b/test/elog_update_ts_test.cpp
@@ -48,6 +48,7 @@
     uint64_t timestamp{100};
     std::string message{"test error"};
     std::string fwLevel{"level42"};
+    std::string path{"/tmp/99"};
     std::vector<std::string> testData{"additional", "data"};
     phosphor::logging::AssociationList associations{};
 
@@ -60,6 +61,7 @@
                std::move(testData),
                std::move(associations),
                fwLevel,
+               path,
                manager};
 
     EXPECT_EQ(elog.timestamp(), elog.updateTimestamp());
diff --git a/test/serialization_test_properties.cpp b/test/serialization_test_properties.cpp
index 6e99d5a..2c83f1e 100644
--- a/test/serialization_test_properties.cpp
+++ b/test/serialization_test_properties.cpp
@@ -17,11 +17,13 @@
     uint64_t timestamp{100};
     std::string message{"test error"};
     std::string fwLevel{"level42"};
+    std::string inputPath = getEntrySerializePath(id, TestSerialization::dir);
     auto input = std::make_unique<Entry>(
         bus, std::string(OBJ_ENTRY) + '/' + std::to_string(id), id, timestamp,
         Entry::Level::Informational, std::move(message), std::move(testData),
-        std::move(assocations), fwLevel, manager);
+        std::move(assocations), fwLevel, inputPath, manager);
     auto path = serialize(*input, TestSerialization::dir);
+    EXPECT_EQ(path, inputPath);
 
     auto idStr = path.filename();
     id = std::stol(idStr.c_str());