test: add callout-test

Add test program which can create callouts based on an input device
path. It creates an error, with callouts, with name TestCallout.

Change-Id: I96b66b73ae4a9c00daff06222841a13747c07408
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index 40f780d..c9aa9f8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -21,9 +21,10 @@
 	$(SDBUSPLUS_CFLAGS)
 
 # Application test which runs in obmc env (qemu, real hardware)
-bin_PROGRAMS = logging-test
+bin_PROGRAMS = logging-test callout-test
 logging_test_SOURCES = logging_test.cpp
 logging_test_LDADD = libphosphor_logging.la
+callout_test_SOURCES = callouts/callout_test.cpp
 
 sbin_PROGRAMS = phosphor-log-manager
 
@@ -56,6 +57,9 @@
 # systemd required for journal interfaces
 logging_test_LDFLAGS = $(SYSTEMD_LIBS) $(SDBUSPLUS_LIBS)
 logging_test_CXXFLAGS = $(SYSTEMD_CFLAGS) $(SDBUSPLUS_CFLAGS)
+callout_test_LDADD = libphosphor_logging.la
+callout_test_LDFLAGS = $(SDBUSPLUS_LIBS) $(PHOSPHOR_DBUS_INTERFACES_LIBS)
+callout_test_CXXFLAGS = $(SDBUSPLUS_CFLAGS) $(PHOSPHOR_DBUS_INTERFACES_CFLAGS)
 phosphor_log_manager_LDFLAGS = \
 		$(SYSTEMD_LIBS) \
 		$(SDBUSPLUS_LIBS) \
diff --git a/callouts/callout_test.cpp b/callouts/callout_test.cpp
new file mode 100644
index 0000000..2af6dc0
--- /dev/null
+++ b/callouts/callout_test.cpp
@@ -0,0 +1,32 @@
+#include <iostream>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include "elog_meta.hpp"
+
+using namespace phosphor::logging;
+
+int main(int argc, char** argv)
+{
+    if(2 != argc)
+    {
+        std::cerr << "usage: callout-test <sysfs path>" << std::endl;
+        return -1;
+    }
+
+    using namespace example::xyz::openbmc_project::Example::Elog;
+    try
+    {
+        elog<TestCallout>(
+            TestCallout::DEV_ADDR(0xDEADEAD),
+            TestCallout::CALLOUT_ERRNO_TEST(0),
+            TestCallout::CALLOUT_DEVICE_PATH_TEST(argv[1]));
+    }
+    catch (elogException<TestCallout>& e)
+    {
+        commit(e.name());
+    }
+
+    return 0;
+}
+
+
diff --git a/elog_meta.hpp b/elog_meta.hpp
index f5c6f4c..09e3ede 100644
--- a/elog_meta.hpp
+++ b/elog_meta.hpp
@@ -2,8 +2,12 @@
 
 #include <vector>
 #include <string>
+#include <tuple>
+#include <algorithm>
+#include <cstring>
 #include <phosphor-logging/elog-errors.hpp>
 #include "elog_entry.hpp"
+#include "callouts-gen.hpp"
 
 namespace phosphor
 {
@@ -64,6 +68,38 @@
 {
 }
 
+template <>
+inline void build<example::xyz::openbmc_project::
+                  Example::Device::Callout::CALLOUT_DEVICE_PATH_TEST>(
+    const std::string& match,
+    const std::vector<std::string>& data,
+    AssociationList& list)
+{
+    constexpr auto ROOT = "/xyz/openbmc_project/inventory";
+    std::map<std::string, std::string> metadata;
+    parse(data, metadata);
+    auto iter = metadata.find(match);
+    if(metadata.end() != iter)
+    {
+        auto comp = [](const auto& first, const auto& second)
+        {
+            return (strcmp(std::get<0>(first), second) < 0);
+        };
+        auto callout = std::lower_bound(callouts.begin(),
+                                        callouts.end(),
+                                        (iter->second).c_str(),
+                                        comp);
+        if((callouts.end() != callout) &&
+           !strcmp((iter->second).c_str(), std::get<0>(*callout)))
+        {
+            list.push_back(std::make_tuple("callout",
+                                           "fault",
+                                           std::string(ROOT) +
+                                           std::get<1>(*callout)));
+        }
+    }
+}
+
 } // namespace associations
 } // namespace metadata
 } // namespace logging
diff --git a/tools/example/xyz/openbmc_project/Example/Device.errors.yaml b/tools/example/xyz/openbmc_project/Example/Device.errors.yaml
new file mode 100644
index 0000000..fbcf78c
--- /dev/null
+++ b/tools/example/xyz/openbmc_project/Example/Device.errors.yaml
@@ -0,0 +1,2 @@
+- name: Callout
+  description: Generic device callout
diff --git a/tools/example/xyz/openbmc_project/Example/Device.metadata.yaml b/tools/example/xyz/openbmc_project/Example/Device.metadata.yaml
new file mode 100644
index 0000000..e5d6508
--- /dev/null
+++ b/tools/example/xyz/openbmc_project/Example/Device.metadata.yaml
@@ -0,0 +1,7 @@
+- name: Callout
+  meta:
+    - str: "CALLOUT_ERRNO_TEST=%d"
+      type: int32
+    - str: "CALLOUT_DEVICE_PATH_TEST=%s"
+      type: string
+      process: true
diff --git a/tools/example/xyz/openbmc_project/Example/Elog.errors.yaml b/tools/example/xyz/openbmc_project/Example/Elog.errors.yaml
index d968823..77dacdb 100644
--- a/tools/example/xyz/openbmc_project/Example/Elog.errors.yaml
+++ b/tools/example/xyz/openbmc_project/Example/Elog.errors.yaml
@@ -6,3 +6,6 @@
 
 - name: AutoTestSimple
   description: This is a simple test error.
+
+- name: TestCallout
+  description: This is test error TestCallout
diff --git a/tools/example/xyz/openbmc_project/Example/Elog.metadata.yaml b/tools/example/xyz/openbmc_project/Example/Elog.metadata.yaml
index 64db7fc..cb1dc7a 100644
--- a/tools/example/xyz/openbmc_project/Example/Elog.metadata.yaml
+++ b/tools/example/xyz/openbmc_project/Example/Elog.metadata.yaml
@@ -26,3 +26,11 @@
   meta:
     - str: STRING=%s
       type: string
+
+- name: TestCallout
+  level: ERR
+  meta:
+        - str: DEV_ADDR=0x%.8X
+          type: uint32
+  inherits:
+    - example.xyz.openbmc_project.Example.Device.Callout