libpldmresponder: implement setStateEffecterStates

This commit implements the handler for setStateEffecterStates response.
Apart from that it actually sets the effecter for PLDM_BOOT_PROGRESS
state. This is used when host sends setStateEffecterStates to mark
any change in hypervisor state. The currently supported states are
"StandBy" and "BootComplete" as per
xyz.openbmc_project.State.OperatingSystem.Status

Change-Id: I205627b2b8a796a0dd4a200ac3d59c1d19d71f01
Signed-off-by: Sampa Misra <sampmisr@in.ibm.com>
diff --git a/test/Makefile.am b/test/Makefile.am
index fbaa01f..9891a28 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -27,14 +27,18 @@
 	$(PTHREAD_CFLAGS) \
 	$(PHOSPHOR_LOGGING_CFLAGS) \
 	$(SDBUSPLUS_CFLAGS) \
-	$(CODE_COVERAGE_CXXFLAGS)
+	$(CODE_COVERAGE_CXXFLAGS) \
+	$(PHOSPHOR_DBUS_INTERFACES_CFLAGS)
 
 test_ldflags = \
 	-lgtest_main \
 	-lgtest \
+	-lgmock \
+	-lstdc++fs \
 	$(PTHREAD_LIBS) \
 	$(SDBUSPLUS_LIBS) \
 	$(PHOSPHOR_LOGGING_LIBS) \
+	$(PHOSPHOR_DBUS_INTERFACES_LIBS) \
 	$(OESDK_TESTCASE_FLAGS)
 
 if OEM_IBM
@@ -162,13 +166,15 @@
 
 libpldmresponder_platform_test_CPPFLAGS = $(test_cppflags)
 libpldmresponder_platform_test_CXXFLAGS = $(test_cxxflags)
-libpldmresponder_platform_test_LDFLAGS = $(test_ldflags)
+libpldmresponder_platform_test_LDFLAGS = $(test_ldflags) $(SDBUSPLUS_LIBS)
 libpldmresponder_platform_test_LDADD = \
+	$(top_builddir)/pldmd-registration.o \
 	$(top_builddir)/libpldm/libpldm_la-base.o \
 	$(top_builddir)/libpldm/libpldm_la-platform.o \
 	$(top_builddir)/libpldmresponder/libpldmresponder_la-pdr.o \
 	$(top_builddir)/libpldmresponder/libpldmresponder_la-effecters.o \
 	$(top_builddir)/libpldmresponder/libpldmresponder_la-platform.o \
+	$(top_builddir)/libpldmresponder/libpldmresponder_la-utils.o
 	$(PHOSPHOR_LOGGING_LIBS) \
 	$(PHOSPHOR_DBUS_INTERFACES_LIBS) \
 	$(SDBUSPLUS_LIBS) \
diff --git a/test/libpldmresponder_pdr_state_effecter_test.cpp b/test/libpldmresponder_pdr_state_effecter_test.cpp
index f763593..c55feb0 100644
--- a/test/libpldmresponder_pdr_state_effecter_test.cpp
+++ b/test/libpldmresponder_pdr_state_effecter_test.cpp
@@ -25,7 +25,7 @@
     ASSERT_EQ(pdr->hdr.version, 1);
     ASSERT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR);
     ASSERT_EQ(pdr->hdr.record_change_num, 0);
-    ASSERT_EQ(pdr->hdr.length, 19);
+    ASSERT_EQ(pdr->hdr.length, 23);
 
     ASSERT_EQ(pdr->terminus_handle, 0);
     ASSERT_EQ(pdr->effecter_id, 1);
@@ -35,7 +35,7 @@
     ASSERT_EQ(pdr->effecter_semantic_id, 0);
     ASSERT_EQ(pdr->effecter_init, PLDM_NO_INIT);
     ASSERT_EQ(pdr->has_description_pdr, false);
-    ASSERT_EQ(pdr->composite_effecter_count, 1);
+    ASSERT_EQ(pdr->composite_effecter_count, 2);
     state_effecter_possible_states* states =
         reinterpret_cast<state_effecter_possible_states*>(pdr->possible_states);
     ASSERT_EQ(states->state_set_id, 196);
diff --git a/test/libpldmresponder_platform_test.cpp b/test/libpldmresponder_platform_test.cpp
index dd51e72..6b89b2e 100644
--- a/test/libpldmresponder_platform_test.cpp
+++ b/test/libpldmresponder_platform_test.cpp
@@ -1,11 +1,15 @@
+#include "libpldmresponder/effecters.hpp"
 #include "libpldmresponder/pdr.hpp"
 #include "libpldmresponder/platform.hpp"
 
 #include <iostream>
 
+#include <gmock/gmock-matchers.h>
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
 using namespace pldm::responder;
+using namespace pldm::responder::pdr;
 
 TEST(getPDR, testGoodPath)
 {
@@ -171,3 +175,84 @@
     }
     ASSERT_EQ(found, true);
 }
+
+namespace pldm
+{
+
+namespace responder
+{
+
+class MockdBusHandler
+{
+  public:
+    MOCK_CONST_METHOD4(setDbusProperty,
+                       int(const std::string&, const std::string&,
+                           const std::string&,
+                           const std::variant<std::string>&));
+};
+} // namespace responder
+} // namespace pldm
+
+using ::testing::_;
+using ::testing::Return;
+
+TEST(setStateEffecterStatesHandler, testGoodRequest)
+{
+    Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
+    pdr::Entry e = pdrRepo.at(1);
+    pldm_state_effecter_pdr* pdr =
+        reinterpret_cast<pldm_state_effecter_pdr*>(e.data());
+    EXPECT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR);
+
+    std::vector<set_effecter_state_field> stateField;
+    stateField.push_back({PLDM_REQUEST_SET, 1});
+    stateField.push_back({PLDM_REQUEST_SET, 1});
+
+    auto bootProgressInf = "xyz.openbmc_project.State.OperatingSystem.Status";
+    auto bootProgressProp = "OperatingSystemState";
+    std::string objPath = "/foo/bar";
+    std::variant<std::string> value{"xyz.openbmc_project.State.OperatingSystem."
+                                    "Status.OSStatus.Standby"};
+
+    MockdBusHandler handlerObj;
+    EXPECT_CALL(handlerObj, setDbusProperty(objPath, bootProgressProp,
+                                            bootProgressInf, value))
+        .Times(2);
+    auto rc = setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x1,
+                                                             stateField);
+    ASSERT_EQ(rc, 0);
+}
+
+TEST(setStateEffecterStatesHandler, testBadRequest)
+{
+    Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
+    pdr::Entry e = pdrRepo.at(1);
+    pldm_state_effecter_pdr* pdr =
+        reinterpret_cast<pldm_state_effecter_pdr*>(e.data());
+    EXPECT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR);
+
+    std::vector<set_effecter_state_field> stateField;
+    stateField.push_back({PLDM_REQUEST_SET, 3});
+    stateField.push_back({PLDM_REQUEST_SET, 4});
+
+    MockdBusHandler handlerObj;
+    auto rc = setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x1,
+                                                             stateField);
+    ASSERT_EQ(rc, PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE);
+
+    rc = setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x9,
+                                                        stateField);
+    ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_EFFECTER_ID);
+
+    stateField.push_back({PLDM_REQUEST_SET, 4});
+    rc = setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x1,
+                                                        stateField);
+    ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    std::vector<set_effecter_state_field> newStateField;
+    newStateField.push_back({PLDM_REQUEST_SET, 1});
+
+    rc = setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x2,
+                                                        newStateField);
+    ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_STATE_VALUE);
+}
diff --git a/test/meson.build b/test/meson.build
index 1ddb598..5bfad27 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -38,6 +38,6 @@
                      implicit_include_directories: false,
                      link_args: dynamic_linker,
                      build_rpath: get_option('oe-sdk').enabled() ? rpath : '',
-                     dependencies: [libpldm, libpldmresponder, gtest, gmock]),
+                     dependencies: [libpldm, libpldmresponder, gtest, gmock, dependency('sdbusplus')]),
        workdir: meson.current_source_dir())
 endforeach
diff --git a/test/pdr_jsons/state_effecter/good/11.json b/test/pdr_jsons/state_effecter/good/11.json
index a037ad4..6a9944b 100644
--- a/test/pdr_jsons/state_effecter/good/11.json
+++ b/test/pdr_jsons/state_effecter/good/11.json
@@ -10,6 +10,14 @@
                 "states" : [1]
             },
             "dbus" : "/foo/bar"
+        },
+        {
+            "set" : {
+                "id" : 196,
+                "size" : 1,
+                "states" : [1, 2]
+            },
+            "dbus" : "/foo/bar"
         }]
     },
     {