Implemented close session cmd in host interface

This command can close any session via host interface.

Tested:

Close the existing valid session by session id
ipmitool raw 0x6 0x3c <valid sesssion id >
Response : 00  // success

Close the existing valid session by session handle
ipmitool raw 0x6 0x3c <zero session id> <valid session handle>
Response : 00  // success

Close the session by zero session id
ipmitool raw 0x6 0x3c <zero session id>
Response : 0x87  // inavlid session id

Close the session by zero session handle
ipmitool raw 0x6 0x3c <zero session id> <zero session handle>
Response : 0x88  // inavlid session handle

Close an inactive session.
ipmitool raw 0x6 0x3c <valid session id>
Response : 0xcc  // invalid data field in request

Close an inactive session.
ipmitool raw 0x6 0x3c <zero session id> <valid session hnadle>
Response : 0xcc  // invalid data field in request

Signed-off-by: Rajashekar Gade Reddy <raja.sekhar.reddy.gade@linux.intel.com>
Change-Id: I8af290001d8effbbcdbbe2dd93aabf1b015e7a88
diff --git a/test/Makefile.am b/test/Makefile.am
index e4ff261..0faeda7 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -72,3 +72,21 @@
     %reldir%/message/unpack.cpp \
     %reldir%/message/pack.cpp
 check_PROGRAMS += %reldir%/message_unittest
+
+# Build/add closesession_unittest to test suite
+session_unittest_CPPFLAGS = \
+    -Igtest \
+    $(GTEST_CPPFLAGS) \
+    $(AM_CPPFLAGS)
+session_unittest_CXXFLAGS = \
+    $(PTHREAD_CFLAGS) \
+    $(CODE_COVERAGE_CXXFLAGS) \
+    $(CODE_COVERAGE_CFLAGS)
+session_unittest_LDFLAGS = \
+    -lgtest_main \
+    -lgtest \
+    -pthread \
+    $(OESDK_TESTCASE_FLAGS) \
+    $(CODE_COVERAGE_LDFLAGS)
+session_unittest_SOURCES = %reldir%/session/closesession_unittest.cpp
+check_PROGRAMS += %reldir%/session_unittest
diff --git a/test/session/closesession_unittest.cpp b/test/session/closesession_unittest.cpp
new file mode 100644
index 0000000..2b184ca
--- /dev/null
+++ b/test/session/closesession_unittest.cpp
@@ -0,0 +1,114 @@
+#include <ipmid/sessionhelper.hpp>
+
+#include <gtest/gtest.h>
+
+TEST(parseSessionInputPayloadTest, ValidObjectPath)
+{
+    uint32_t sessionId = 0;
+    uint8_t sessionHandle = 0;
+    std::string objectPath =
+        "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a";
+
+    EXPECT_TRUE(
+        parseCloseSessionInputPayload(objectPath, sessionId, sessionHandle));
+    EXPECT_EQ(0x12a4567d, sessionId);
+    EXPECT_EQ(0x8a, sessionHandle);
+}
+
+TEST(parseSessionInputPayloadTest, InvalidObjectPath)
+{
+    uint32_t sessionId = 0;
+    uint8_t sessionHandle = 0;
+    // A valid object path will be like
+    // "/xyz/openbmc_project/ipmi/session/channel/sessionId_sessionHandle"
+    // Ex: "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a"
+    // SessionId    : 0X12a4567d
+    // SessionHandle: 0X8a
+    std::string objectPath = "/xyz/openbmc_project/ipmi/session/eth0/12a4567d";
+
+    EXPECT_FALSE(
+        parseCloseSessionInputPayload(objectPath, sessionId, sessionHandle));
+}
+
+TEST(parseSessionInputPayloadTest, NoObjectPath)
+{
+    uint32_t sessionId = 0;
+    uint8_t sessionHandle = 0;
+    std::string objectPath;
+
+    EXPECT_FALSE(
+        parseCloseSessionInputPayload(objectPath, sessionId, sessionHandle));
+}
+
+TEST(isSessionObjectMatchedTest, ValidSessionId)
+{
+    std::string objectPath =
+        "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a";
+    uint32_t sessionId = 0x12a4567d;
+    uint8_t sessionHandle = 0;
+
+    EXPECT_TRUE(isSessionObjectMatched(objectPath, sessionId, sessionHandle));
+}
+
+TEST(isSessionObjectMatchedTest, ValidSessionHandle)
+{
+    std::string objectPath =
+        "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a";
+    uint32_t sessionId = 0;
+    uint8_t sessionHandle = 0x8a;
+
+    EXPECT_TRUE(isSessionObjectMatched(objectPath, sessionId, sessionHandle));
+}
+
+TEST(isSessionObjectMatchedTest, InvalidSessionId)
+{
+    std::string objectPath =
+        "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a";
+    uint32_t sessionId = 0x1234b67d;
+    uint8_t sessionHandle = 0;
+
+    EXPECT_FALSE(isSessionObjectMatched(objectPath, sessionId, sessionHandle));
+}
+
+TEST(isSessionObjectMatchedTest, InvalidSessionHandle)
+{
+    std::string objectPath =
+        "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a";
+    uint32_t sessionId = 0;
+    uint8_t sessionHandle = 0x9b;
+
+    EXPECT_FALSE(isSessionObjectMatched(objectPath, sessionId, sessionHandle));
+}
+
+TEST(isSessionObjectMatchedTest, ZeroSessionId_ZeroSessionHandle)
+{
+    std::string objectPath =
+        "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a";
+    uint32_t sessionId = 0;
+    uint8_t sessionHandle = 0;
+
+    EXPECT_FALSE(isSessionObjectMatched(objectPath, sessionId, sessionHandle));
+}
+
+TEST(isSessionObjectMatchedTest, InvalidObjectPath)
+{
+    // A valid object path will be like
+    // "/xyz/openbmc_project/ipmi/session/channel/sessionId_sessionHandle"
+    // Ex: "/xyz/openbmc_project/ipmi/session/eth0/12a4567d_8a"
+    // SessionId    : 0X12a4567d
+    // SessionHandle: 0X8a
+    std::string objectPath = "/xyz/openbmc_project/ipmi/session/eth0/12a4567d";
+    uint32_t sessionId = 0x12a4567d;
+    uint8_t sessionHandle = 0;
+
+    EXPECT_FALSE(isSessionObjectMatched(objectPath, sessionId, sessionHandle));
+}
+
+TEST(isSessionObjectMatchedTest, NoObjectPath)
+{
+    std::string objectPath;
+    uint32_t sessionId = 0x12a4567d;
+    uint8_t sessionHandle = 0x8a;
+
+    EXPECT_FALSE(isSessionObjectMatched(objectPath, sessionId, sessionHandle));
+}