Add ReportManager and Report unit tests

Introduced ReportFactory to seperate Report and ReportManager
unit tests. Implemented mocks for Report, ReportManager and
ReportFactory classes. Added tests for DBus Properties and Methods
provided by telemetry service.

Tested:
 - Ran unit-tests with success

Change-Id: I1860e280d26ee4becc52de98dd65e5697d26b376
Signed-off-by: Wludzik, Jozef <jozef.wludzik@intel.com>
diff --git a/src/interfaces/report.hpp b/src/interfaces/report.hpp
new file mode 100644
index 0000000..98421be
--- /dev/null
+++ b/src/interfaces/report.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <string>
+
+namespace interfaces
+{
+
+class Report
+{
+  public:
+    virtual ~Report() = default;
+
+    virtual std::string getName() const = 0;
+    virtual std::string getPath() const = 0;
+};
+} // namespace interfaces
diff --git a/src/interfaces/report_factory.hpp b/src/interfaces/report_factory.hpp
new file mode 100644
index 0000000..9273d03
--- /dev/null
+++ b/src/interfaces/report_factory.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "interfaces/report.hpp"
+#include "interfaces/report_manager.hpp"
+#include "interfaces/types.hpp"
+
+#include <chrono>
+#include <memory>
+
+class ReportManager;
+
+namespace interfaces
+{
+
+class ReportFactory
+{
+  public:
+    virtual ~ReportFactory() = default;
+
+    virtual std::unique_ptr<interfaces::Report>
+        make(const std::string& name, const std::string& reportingType,
+             bool emitsReadingsSignal, bool logToMetricReportsCollection,
+             std::chrono::milliseconds period,
+             const ReadingParameters& metricParams,
+             ReportManager& reportManager) const = 0;
+};
+
+} // namespace interfaces
diff --git a/src/interfaces/report_manager.hpp b/src/interfaces/report_manager.hpp
new file mode 100644
index 0000000..80e0c82
--- /dev/null
+++ b/src/interfaces/report_manager.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "interfaces/report.hpp"
+
+namespace interfaces
+{
+
+class ReportManager
+{
+  public:
+    virtual ~ReportManager() = default;
+
+    virtual void removeReport(const interfaces::Report* report) = 0;
+};
+
+} // namespace interfaces
diff --git a/src/interfaces/types.hpp b/src/interfaces/types.hpp
new file mode 100644
index 0000000..09a75cd
--- /dev/null
+++ b/src/interfaces/types.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <sdbusplus/message/types.hpp>
+
+#include <string>
+#include <tuple>
+#include <vector>
+
+using ReadingParameters =
+    std::vector<std::tuple<std::vector<sdbusplus::message::object_path>,
+                           std::string, std::string, std::string>>;
diff --git a/src/report.cpp b/src/report.cpp
index 45639aa..81e3b05 100644
--- a/src/report.cpp
+++ b/src/report.cpp
@@ -2,9 +2,9 @@
 
 #include "report_manager.hpp"
 
-constexpr const char* reportIfaceName = "xyz.openbmc_project.Telemetry.Report";
-constexpr const char* reportPath = "/xyz/openbmc_project/Telemetry/Reports/";
-constexpr const char* deleteIfaceName = "xyz.openbmc_project.Object.Delete";
+using Readings = std::tuple<
+    uint64_t,
+    std::vector<std::tuple<std::string, std::string, double, uint64_t>>>;
 
 Report::Report(boost::asio::io_context& ioc,
                const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
@@ -13,9 +13,9 @@
                const bool logToMetricReportsCollection,
                const std::chrono::milliseconds period,
                const ReadingParameters& metricParams,
-               ReportManager& reportManager) :
+               interfaces::ReportManager& reportManager) :
     name{reportName},
-    path{reportPath + name}, interval{period}, objServer(objServer)
+    path{reportDir + name}, interval{period}, objServer(objServer)
 {
     reportIface = objServer->add_unique_interface(
         path, reportIfaceName,
diff --git a/src/report.hpp b/src/report.hpp
index 7f74d49..fb40614 100644
--- a/src/report.hpp
+++ b/src/report.hpp
@@ -1,30 +1,26 @@
 #pragma once
 
+#include "interfaces/report.hpp"
+#include "interfaces/report_manager.hpp"
+#include "interfaces/types.hpp"
+
 #include <boost/asio/io_context.hpp>
 #include <sdbusplus/asio/object_server.hpp>
 
 #include <chrono>
 #include <memory>
 
-using Readings = std::tuple<
-    uint64_t,
-    std::vector<std::tuple<std::string, std::string, double, uint64_t>>>;
-using ReadingParameters =
-    std::vector<std::tuple<std::vector<sdbusplus::message::object_path>,
-                           std::string, std::string, std::string>>;
-
-class ReportManager;
-
-class Report
+class Report : public interfaces::Report
 {
   public:
     Report(boost::asio::io_context& ioc,
            const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
-           const std::string& name, const std::string& reportingType,
+           const std::string& reportName, const std::string& reportingType,
            const bool emitsReadingsSignal,
            const bool logToMetricReportsCollection,
            const std::chrono::milliseconds period,
-           const ReadingParameters& metricParams, ReportManager& reportManager);
+           const ReadingParameters& metricParams,
+           interfaces::ReportManager& reportManager);
     ~Report() = default;
 
     Report(Report&) = delete;
@@ -32,12 +28,29 @@
     Report& operator=(Report&) = delete;
     Report& operator=(Report&&) = delete;
 
-    const std::string name;
-    const std::string path;
+    std::string getName() const override
+    {
+        return name;
+    }
+
+    std::string getPath() const override
+    {
+        return path;
+    }
 
   private:
+    const std::string name;
+    const std::string path;
     std::chrono::milliseconds interval;
     std::shared_ptr<sdbusplus::asio::object_server> objServer;
     std::unique_ptr<sdbusplus::asio::dbus_interface> reportIface;
     std::unique_ptr<sdbusplus::asio::dbus_interface> deleteIface;
+
+  public:
+    static constexpr const char* reportIfaceName =
+        "xyz.openbmc_project.Telemetry.Report";
+    static constexpr const char* reportDir =
+        "/xyz/openbmc_project/Telemetry/Reports/";
+    static constexpr const char* deleteIfaceName =
+        "xyz.openbmc_project.Object.Delete";
 };
diff --git a/src/report_factory.cpp b/src/report_factory.cpp
new file mode 100644
index 0000000..9f51db5
--- /dev/null
+++ b/src/report_factory.cpp
@@ -0,0 +1,21 @@
+#include "report_factory.hpp"
+
+#include "report.hpp"
+
+ReportFactory::ReportFactory(
+    boost::asio::io_context& ioc,
+    const std::shared_ptr<sdbusplus::asio::object_server>& objServer) :
+    ioc(ioc),
+    objServer(objServer)
+{}
+
+std::unique_ptr<interfaces::Report> ReportFactory::make(
+    const std::string& name, const std::string& reportingType,
+    bool emitsReadingsSignal, bool logToMetricReportsCollection,
+    std::chrono::milliseconds period, const ReadingParameters& metricParams,
+    interfaces::ReportManager& reportManager) const
+{
+    return std::make_unique<Report>(
+        ioc, objServer, name, reportingType, emitsReadingsSignal,
+        logToMetricReportsCollection, period, metricParams, reportManager);
+}
diff --git a/src/report_factory.hpp b/src/report_factory.hpp
new file mode 100644
index 0000000..775ea45
--- /dev/null
+++ b/src/report_factory.hpp
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "interfaces/report_factory.hpp"
+
+#include <boost/asio/io_context.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+class ReportFactory : public interfaces::ReportFactory
+{
+  public:
+    ReportFactory(
+        boost::asio::io_context& ioc,
+        const std::shared_ptr<sdbusplus::asio::object_server>& objServer);
+
+    std::unique_ptr<interfaces::Report>
+        make(const std::string& name, const std::string& reportingType,
+             bool emitsReadingsSignal, bool logToMetricReportsCollection,
+             std::chrono::milliseconds period,
+             const ReadingParameters& metricParams,
+             interfaces::ReportManager& reportManager) const override;
+
+  private:
+    boost::asio::io_context& ioc;
+    std::shared_ptr<sdbusplus::asio::object_server> objServer;
+};
diff --git a/src/report_manager.cpp b/src/report_manager.cpp
index f2cbe94..5944fa9 100644
--- a/src/report_manager.cpp
+++ b/src/report_manager.cpp
@@ -4,21 +4,16 @@
 
 #include <system_error>
 
-constexpr const char* reportManagerIfaceName =
-    "xyz.openbmc_project.Telemetry.ReportManager";
-constexpr const char* reportManagerPath =
-    "/xyz/openbmc_project/Telemetry/Reports";
-
 ReportManager::ReportManager(
-    const std::shared_ptr<sdbusplus::asio::connection>& bus,
+    std::unique_ptr<interfaces::ReportFactory> reportFactoryIn,
     const std::shared_ptr<sdbusplus::asio::object_server>& objServerIn) :
+    reportFactory(std::move(reportFactoryIn)),
     objServer(objServerIn)
 {
     reports.reserve(maxReports);
 
     reportManagerIface = objServer->add_unique_interface(
-        reportManagerPath, reportManagerIfaceName,
-        [this, &ioc = bus->get_io_context()](auto& dbusIface) {
+        reportManagerPath, reportManagerIfaceName, [this](auto& dbusIface) {
             dbusIface.register_property_r(
                 "MaxReports", uint32_t{}, sdbusplus::vtable::property_::const_,
                 [](const auto&) { return maxReports; });
@@ -27,13 +22,12 @@
                 [](const auto&) -> uint64_t { return minInterval.count(); });
 
             dbusIface.register_method(
-                "AddReport",
-                [this, &ioc](const std::string& reportName,
-                             const std::string& reportingType,
-                             const bool emitsReadingsUpdate,
-                             const bool logToMetricReportsCollection,
-                             const uint64_t interval,
-                             const ReadingParameters& metricParams) {
+                "AddReport", [this](const std::string& reportName,
+                                    const std::string& reportingType,
+                                    const bool emitsReadingsUpdate,
+                                    const bool logToMetricReportsCollection,
+                                    const uint64_t interval,
+                                    const ReadingParameters& metricParams) {
                     if (reports.size() >= maxReports)
                     {
                         throw sdbusplus::exception::SdBusError(
@@ -43,7 +37,7 @@
 
                     for (const auto& report : reports)
                     {
-                        if (report->name == reportName)
+                        if (report->getName() == reportName)
                         {
                             throw sdbusplus::exception::SdBusError(
                                 static_cast<int>(std::errc::file_exists),
@@ -59,16 +53,16 @@
                             "Invalid interval");
                     }
 
-                    reports.emplace_back(std::make_unique<Report>(
-                        ioc, objServer, reportName, reportingType,
-                        emitsReadingsUpdate, logToMetricReportsCollection,
-                        std::move(reportInterval), metricParams, *this));
-                    return reports.back()->path;
+                    reports.emplace_back(reportFactory->make(
+                        reportName, reportingType, emitsReadingsUpdate,
+                        logToMetricReportsCollection, std::move(reportInterval),
+                        metricParams, *this));
+                    return reports.back()->getPath();
                 });
         });
 }
 
-void ReportManager::removeReport(const Report* report)
+void ReportManager::removeReport(const interfaces::Report* report)
 {
     reports.erase(
         std::remove_if(reports.begin(), reports.end(),
diff --git a/src/report_manager.hpp b/src/report_manager.hpp
index 177a03c..2427b76 100644
--- a/src/report_manager.hpp
+++ b/src/report_manager.hpp
@@ -1,6 +1,8 @@
 #pragma once
 
-#include "report.hpp"
+#include "interfaces/report.hpp"
+#include "interfaces/report_factory.hpp"
+#include "interfaces/report_manager.hpp"
 
 #include <sdbusplus/asio/object_server.hpp>
 
@@ -8,11 +10,11 @@
 #include <memory>
 #include <vector>
 
-class ReportManager
+class ReportManager : public interfaces::ReportManager
 {
   public:
     ReportManager(
-        const std::shared_ptr<sdbusplus::asio::connection>& bus,
+        std::unique_ptr<interfaces::ReportFactory> reportFactory,
         const std::shared_ptr<sdbusplus::asio::object_server>& objServer);
     ~ReportManager() = default;
 
@@ -21,15 +23,20 @@
     ReportManager& operator=(ReportManager&) = delete;
     ReportManager& operator=(ReportManager&&) = delete;
 
+    void removeReport(const interfaces::Report* report) override;
     static bool verifyScanPeriod(const uint64_t scanPeriod);
-    void removeReport(const Report* report);
 
   private:
+    std::unique_ptr<interfaces::ReportFactory> reportFactory;
     std::shared_ptr<sdbusplus::asio::object_server> objServer;
     std::unique_ptr<sdbusplus::asio::dbus_interface> reportManagerIface;
-    std::vector<std::unique_ptr<Report>> reports;
+    std::vector<std::unique_ptr<interfaces::Report>> reports;
 
   public:
     static constexpr uint32_t maxReports{20};
     static constexpr std::chrono::milliseconds minInterval{1000};
+    static constexpr const char* reportManagerIfaceName =
+        "xyz.openbmc_project.Telemetry.ReportManager";
+    static constexpr const char* reportManagerPath =
+        "/xyz/openbmc_project/Telemetry/Reports";
 };
diff --git a/src/telemetry.hpp b/src/telemetry.hpp
index efdebaa..bfcc99a 100644
--- a/src/telemetry.hpp
+++ b/src/telemetry.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include "report_factory.hpp"
 #include "report_manager.hpp"
 
 #include <sdbusplus/asio/connection.hpp>
@@ -12,7 +13,9 @@
   public:
     Telemetry(std::shared_ptr<sdbusplus::asio::connection> bus) :
         objServer(std::make_shared<sdbusplus::asio::object_server>(bus)),
-        reportManager(bus, objServer)
+        reportManager(
+            std::make_unique<ReportFactory>(bus->get_io_context(), objServer),
+            objServer)
     {}
 
   private: