Enable gtest for testing LED set operations

This patchset enables gtest to allow different combinations
of LED set operations to be verified at build time.

Change-Id: I9c2ddf82c2e23be911233b23037ee44e3ce301db
Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index 04dab40..9e49364 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,3 +15,5 @@
 
 phosphor_ledmanager_LDFLAGS = $(SYSTEMD_LIBS)
 phosphor_ledmanager_CFLAGS = $(SYSTEMD_CFLAGS)
+
+SUBDIRS = test
diff --git a/configure.ac b/configure.ac
index 612c3f4..d978030 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,9 +21,27 @@
 # Checks for libraries.
 PKG_CHECK_MODULES([SYSTEMD], [libsystemd >= 221])
 
+LT_INIT # Removes WARNING: unrecognized options: --with-libtool-sysroot
 # Check/set gtest specific functions.
 AX_PTHREAD([GTEST_CPPFLAGS="-DGTEST_HAS_PTHREAD=1"],[GTEST_CPPFLAGS="-DGTEST_HAS_PTHREAD=0"])
 AC_SUBST(GTEST_CPPFLAGS)
+AC_ARG_ENABLE([oe-sdk],
+    AS_HELP_STRING([--enable-oe-sdk], [Link testcases absolutely against OE SDK so they can be ran within it.])
+)
+AC_ARG_VAR(OECORE_TARGET_SYSROOT,
+    [Path to the OE SDK SYSROOT])
+AS_IF([test "x$enable_oe_sdk" == "xyes"],
+    AS_IF([test "x$OECORE_TARGET_SYSROOT" == "x"],
+          AC_MSG_ERROR([OECORE_TARGET_SYSROOT must be set with --enable-oe-sdk])
+    )
+    AC_MSG_NOTICE([Enabling OE-SDK at $OECORE_TARGET_SYSROOT])
+    [
+        testcase_flags="-Wl,-rpath,\${OECORE_TARGET_SYSROOT}/lib"
+        testcase_flags="${testcase_flags} -Wl,-rpath,\${OECORE_TARGET_SYSROOT}/usr/lib"
+        testcase_flags="${testcase_flags} -Wl,-dynamic-linker,`find \${OECORE_TARGET_SYSROOT}/lib/ld-*.so | sort -r -n | head -n1`"
+    ]
+    AC_SUBST([OESDK_TESTCASE_FLAGS], [$testcase_flags])
+)
 
 # Checks for header files.
 AC_CHECK_HEADER(systemd/sd-bus.h, ,[AC_MSG_ERROR([Could not find systemd/sd-bus.h...systemd developement package required])])
@@ -40,5 +58,5 @@
 AC_DEFINE_UNQUOTED([OBJPATH], ["$OBJPATH"], [The Ledmanager Dbus root])
 
 # Create configured output
-AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([Makefile test/Makefile])
 AC_OUTPUT
diff --git a/group.cpp b/group.cpp
index 8ed2ab0..fda5982 100644
--- a/group.cpp
+++ b/group.cpp
@@ -8,8 +8,20 @@
 /** @brief Overloaded Property Setter function */
 bool Group::asserted(bool value)
 {
-    // Group management is handled by Manager
-    auto result = manager.setGroupState(path, value);
+    // Introducing these to enable gtest.
+    Manager::group ledsAssert {};
+    Manager::group ledsDeAssert {};
+    Manager::group ledsUpdate {};
+
+    // Group management is handled by Manager. The populated leds* sets are not
+    // really used by production code. They are there to enable gtest for
+    // validation.
+    auto result = manager.setGroupState(path, value, ledsAssert,
+                                        ledsDeAssert, ledsUpdate);
+
+    // If something does not go right here, then there should be an sdbusplus
+    // exception thrown.
+    manager.driveLEDs(ledsAssert, ledsDeAssert, ledsUpdate);
 
     // Set the base class's asserted to 'true' since the getter
     // operation is handled there.
diff --git a/led-main.cpp b/led-main.cpp
index 8a091eb..2dc0dce 100644
--- a/led-main.cpp
+++ b/led-main.cpp
@@ -1,12 +1,14 @@
 #include <iostream>
+#include "ledlayout.hpp"
 #include "manager.hpp"
 #include "group.hpp"
 #include "config.h"
+#include "led-gen.hpp"
 
 int main(void)
 {
     /** @brief Group manager object */
-    phosphor::led::Manager manager;
+    phosphor::led::Manager manager(systemLedMap);
 
     /** @brief Dbus constructs used by LED Group manager */
     sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
@@ -18,7 +20,7 @@
     std::vector<std::unique_ptr<phosphor::led::Group>> groups;
 
     /** Now create so many dbus objects as there are groups */
-    for (auto &grp: phosphor::led::Manager::ledMap)
+    for (auto &grp: systemLedMap)
     {
         groups.emplace_back(std::make_unique<phosphor::led::Group>(
                     bus, grp.first, manager));
diff --git a/ledlayout.hpp b/ledlayout.hpp
new file mode 100644
index 0000000..d3d0e40
--- /dev/null
+++ b/ledlayout.hpp
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <map>
+#include <set>
+namespace phosphor
+{
+namespace led
+{
+/** @namespace Layout
+ *  @brief Depicts the LED and their mappings and group actions
+ */
+namespace Layout
+{
+    /** @brief Define possible actions on a given LED.
+     *  For the BLINK operation, follow 50-50 duty cycle
+     */
+    enum Action
+    {
+        Off,
+        On,
+        Blink,
+    };
+
+    /** @brief Name of the LED and it's proposed action.
+     *  This structure is supplied as configuration at build time
+     */
+    struct LedAction
+    {
+        std::string name;
+        Action action;
+
+        // Needed for inserting elements into sets
+        bool operator<(const LedAction& right) const
+        {
+            if (name == right.name)
+            {
+                return action < right.action;
+            }
+            return name < right.name;
+        }
+    };
+} // namespace Layout
+} // namespace led
+} // namespace phosphor
diff --git a/manager.cpp b/manager.cpp
index f4b85c7..e4137d3 100644
--- a/manager.cpp
+++ b/manager.cpp
@@ -2,14 +2,15 @@
 #include <string>
 #include <algorithm>
 #include "manager.hpp"
-#include "led-gen.hpp"
 namespace phosphor
 {
 namespace led
 {
 
 // Assert -or- De-assert
-bool Manager::setGroupState(const std::string& path, bool assert)
+bool Manager::setGroupState(const std::string& path, bool assert,
+                            group& ledsAssert, group& ledsDeAssert,
+                            group& ledsUpdate)
 {
     if (assert)
     {
@@ -23,17 +24,7 @@
             assertedGroups.erase(&ledMap.at(path));
         }
     }
-    // If something does not go right here, then there should be an sdbusplus
-    // exception thrown.
-    driveLEDs();
 
-    // If we survive, then set the state accordingly.
-    return assert;
-}
-
-/** @brief Run through the map and apply action on the LEDs */
-void Manager::driveLEDs()
-{
     // This will contain the union of what's already in the asserted group
     group desiredState {};
     for(const auto& grp : assertedGroups)
@@ -46,7 +37,6 @@
     std::set_difference(currentState.begin(), currentState.end(),
                         desiredState.begin(), desiredState.end(),
                         std::inserter(transient, transient.begin()));
-
     if(transient.size())
     {
         // We really do not want the Manager to know how a particular LED
@@ -60,58 +50,67 @@
         // request to make it blink, the end state would now be blink.
         // If we either turn off blink / fault, then we need to go back to its
         // previous state.
-        group ledsUpdate {};
         std::set_intersection(desiredState.begin(), desiredState.end(),
                               transient.begin(), transient.end(),
                               std::inserter(ledsUpdate, ledsUpdate.begin()),
                               ledComp);
 
-        if (ledsUpdate.size())
-        {
-            std::cout << "Asserting LEDs again" << std::endl;
-            for (const auto& it: ledsUpdate)
-            {
-                std::cout << "\t{" << it.name << "::" << it.action << "}"
-                          << std::endl;
-            }
-        }
-
         // These LEDs are only to be De-Asserted.
-        group ledsDeAssert {};
         std::set_difference(transient.begin(), transient.end(),
                             ledsUpdate.begin(), ledsUpdate.end(),
                             std::inserter(ledsDeAssert, ledsDeAssert.begin()),
                             ledComp);
 
-        if (ledsDeAssert.size())
-        {
-            std::cout << "De-Asserting LEDs" << std::endl;
-            for (const auto& it: ledsDeAssert)
-            {
-                std::cout << "\t{" << it.name << "::" << it.action << "}"
-                          << std::endl;
-            }
-        }
     }
 
     // Turn on these
-    group ledsAssert {};
     std::set_difference(desiredState.begin(), desiredState.end(),
                         currentState.begin(), currentState.end(),
                         std::inserter(ledsAssert, ledsAssert.begin()));
 
+
+    // Done.. Save the latest and greatest.
+    currentState = std::move(desiredState);
+
+    // If we survive, then set the state accordingly.
+    return assert;
+}
+
+/** @brief Run through the map and apply action on the LEDs */
+void Manager::driveLEDs(group& ledsAssert, group& ledsDeAssert,
+                        group& ledsUpdate)
+{
+    // This order of LED operation is important.
+    if (ledsUpdate.size())
+    {
+        std::cout << "Updating LED states between (On <--> Blink)"
+                  << std::endl;
+        for (const auto& it: ledsUpdate)
+        {
+            std::cout << "\t{" << it.name << "::" << it.action << "}"
+                << std::endl;
+        }
+    }
+
+    if (ledsDeAssert.size())
+    {
+        std::cout << "De-Asserting LEDs" << std::endl;
+        for (const auto& it: ledsDeAssert)
+        {
+            std::cout << "\t{" << it.name << "::" << it.action << "}"
+                << std::endl;
+        }
+    }
+
     if(ledsAssert.size())
     {
         std::cout << "Asserting LEDs" << std::endl;
         for (const auto& it: ledsAssert)
         {
             std::cout << "\t{" << it.name << "::" << it.action << "}"
-                      << std::endl;
+                << std::endl;
         }
     }
-
-    // Done.. Save the latest and greatest.
-    currentState = std::move(desiredState);
     return;
 }
 
diff --git a/manager.hpp b/manager.hpp
index 9e32216..10af42d 100644
--- a/manager.hpp
+++ b/manager.hpp
@@ -2,6 +2,7 @@
 
 #include <map>
 #include <set>
+#include "ledlayout.hpp"
 namespace phosphor
 {
 namespace led
@@ -13,61 +14,62 @@
 class Manager
 {
     public:
-        /** @brief Define possible actions on a given LED.
-         *  For the BLINK operation, follow 50-50 duty cycle
-         */
-        enum Action
-        {
-            Off,
-            On,
-            Blink,
-        };
-
         /** @brief Only need the default Manager */
-        Manager() = default;
+        Manager() = delete;
         ~Manager() = default;
         Manager(const Manager&) = delete;
         Manager& operator=(const Manager&) = delete;
         Manager(Manager&&) = delete;
         Manager& operator=(Manager&&) = delete;
 
-        /** @brief Name of the LED and it's proposed action.
-         *  This structure is supplied as configuration at build time
-         */
-        struct LedAction
-        {
-            std::string name;
-            Action action;
-
-            // Needed for inserting elements into sets
-            bool operator<(const LedAction& right) const
-            {
-                if (name == right.name)
-                {
-                    return action < right.action;
-                }
-                return name < right.name;
-            }
-        };
-
         /** @brief For finding intersection */
-        static bool ledComp(const LedAction& left, const LedAction& right)
+        static bool ledComp(const phosphor::led::Layout::LedAction& left,
+                            const phosphor::led::Layout::LedAction& right)
         {
             return left.name < right.name;
         }
 
-        using group = std::set<LedAction>;
+        using group = std::set<phosphor::led::Layout::LedAction>;
 
         /** @brief static global map constructed at compile time */
-        static const std::map<std::string, group> ledMap;
+        const std::map<std::string, group>& ledMap;
+
+        /** @brief Refer the user supplied LED layout.
+         *
+         *  @param [in] ledLayout - LEDs group layout
+         */
+        explicit Manager(const std::map<std::string, Manager::group>& ledLayout)
+                : ledMap(ledLayout)
+        {
+            // Nothing here
+        }
 
         /** @brief Given a group name, applies the action on the group
          *
-         *  @param[in]  path    -  dbus path of group
-         *  @param[in]  assert  -  Could be true or false
-         *  @return             -  Success or exception thrown
+         *  @param[in]  path          -  dbus path of group
+         *  @param[in]  assert        -  Could be true or false
+         *  @param[in]  ledsAssert    -  LEDs that are to be asserted newly
+         *  @param[in]  ledsDeAssert  -  LEDs that are to be Deasserted
+         *  @param[in]  ledsUpdate    -  LEDs that need a transition between
+         *                               different types of asserted states.
+         *
+         *  @return                   -  Success or exception thrown
          */
-        bool setGroupState(const std::string& path, bool assert);
+        bool setGroupState(const std::string& path, bool assert,
+                           group& ledsAssert, group& ledsDeAssert,
+                           group& ledsUpdate);
+
+        /** @brief Finds the set of LEDs to operate on and executes action
+         *
+         *  @param[in]  ledsAssert    -  LEDs that are to be asserted newly
+         *  @param[in]  ledsDeAssert  -  LEDs that are to be Deasserted
+         *  @param[in]  ledsUpdate    -  LEDs that need a transition between
+         *                               different types of asserted states.
+         *
+         *  @return: None
+         */
+        void driveLEDs(group& ledsAssert, group& ledsDeAssert,
+                       group& ledsUpdate);
 
     private:
         /** @brief Pointers to groups that are in asserted state */
@@ -76,11 +78,6 @@
         /** @brief Contains the LEDs that are in asserted state */
         group currentState;
 
-        /** @brief Finds the set of LEDs to operate on and executes action
-         *
-         *  @return: None
-         */
-        void driveLEDs();
 };
 
 } // namespace led
diff --git a/parse_led.py b/parse_led.py
index ea58876..35f67aa 100755
--- a/parse_led.py
+++ b/parse_led.py
@@ -11,9 +11,9 @@
         ofile.write('/* !!! WARNING: This is a GENERATED Code..')
         ofile.write('Please do NOT Edit !!! */\n\n')
 
-        ofile.write('const std::map<std::string,')
-        ofile.write(' std::set<phosphor::led::Manager::LedAction>>')
-        ofile.write(' phosphor::led::Manager::ledMap = {\n\n')
+        ofile.write('static const std::map<std::string,')
+        ofile.write(' std::set<phosphor::led::Layout::LedAction>>')
+        ofile.write(' systemLedMap = {\n\n')
         for group in ifile.iterkeys():
             # Value of this group is a std::set<string, led structure>
             ledset = ifile[group]
@@ -23,7 +23,7 @@
                 for name, value in list_dict.iteritems():
                     if group and led_dict and name and value:
                         ofile.write('        {\"' + led_dict + '\",')
-                        ofile.write(value + '},\n')
+                        ofile.write('phosphor::led::Layout::' + value + '},\n')
             ofile.write('   }},\n')
         ofile.write('};\n')
 
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 0000000..e434c40
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,12 @@
+AM_CPPFLAGS = -I$(top_srcdir)
+
+# Run all 'check' test programs
+TESTS = $(check_PROGRAMS)
+
+# # Build/add utest to test suite
+check_PROGRAMS = utest
+utest_CPPFLAGS = -Igtest $(GTEST_CPPFLAGS) $(AM_CPPFLAGS)
+utest_CXXFLAGS = $(PTHREAD_CFLAGS)
+utest_LDFLAGS = -lgtest_main -lgtest $(PTHREAD_LIBS) $(OESDK_TESTCASE_FLAGS)
+utest_SOURCES = utest.cpp
+utest_LDADD = $(top_builddir)/manager.o
diff --git a/test/led-test-map.hpp b/test/led-test-map.hpp
new file mode 100644
index 0000000..067bb47
--- /dev/null
+++ b/test/led-test-map.hpp
@@ -0,0 +1,134 @@
+static const std::map<std::string,
+    std::set<phosphor::led::Layout::LedAction>> singleLedOn = {
+    {   "/xyz/openbmc_project/ledmanager/groups/SingleLed",{
+            {"One",phosphor::led::Layout::On},
+        }
+    },
+};
+
+static const std::map<std::string,
+    std::set<phosphor::led::Layout::LedAction>> singleLedBlink = {
+    {   "/xyz/openbmc_project/ledmanager/groups/SingleLed",{
+            {"One",phosphor::led::Layout::Blink},
+        }
+    },
+};
+
+static const std::map<std::string,
+    std::set<phosphor::led::Layout::LedAction>> multipleLedsOn = {
+    {   "/xyz/openbmc_project/ledmanager/groups/MultipleLeds",{
+            {"One",phosphor::led::Layout::On},
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::On},
+        }
+    },
+};
+
+static const std::map<std::string,
+    std::set<phosphor::led::Layout::LedAction>> multipleLedsBlink = {
+    {   "/xyz/openbmc_project/ledmanager/groups/MultipleLeds",{
+            {"One",phosphor::led::Layout::Blink},
+            {"Two",phosphor::led::Layout::Blink},
+            {"Three",phosphor::led::Layout::Blink},
+        }
+    },
+};
+
+static const std::map<std::string,
+    std::set<phosphor::led::Layout::LedAction>> multipleLedsOnAndBlink = {
+    {   "/xyz/openbmc_project/ledmanager/groups/MultipleLedsMix",{
+            {"One",phosphor::led::Layout::Blink},
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::Blink},
+            {"Four",phosphor::led::Layout::On},
+            {"Five",phosphor::led::Layout::On},
+        }
+    },
+};
+
+static const std::map<std::string,
+    std::set<phosphor::led::Layout::LedAction>> twoGroupsWithDistinctLEDsOn = {
+    {   "/xyz/openbmc_project/ledmanager/groups/MultipleLedsASet",{
+            {"One",phosphor::led::Layout::On},
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::On},
+        }
+    },
+    {   "/xyz/openbmc_project/ledmanager/groups/MultipleLedsBSet",{
+            {"Four",phosphor::led::Layout::On},
+            {"Five",phosphor::led::Layout::On},
+            {"Six",phosphor::led::Layout::On},
+        }
+    },
+};
+
+static const std::map<std::string,
+    std::set<phosphor::led::Layout::LedAction>> twoGroupsWithOneComonLEDOn = {
+    {   "/xyz/openbmc_project/ledmanager/groups/MultipleLedsASet",{
+            {"One",phosphor::led::Layout::On},
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::On},
+        }
+    },
+    {   "/xyz/openbmc_project/ledmanager/groups/MultipleLedsBSet",{
+            {"Four",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::On},
+            {"Six",phosphor::led::Layout::On},
+        }
+    },
+};
+
+static const std::map<std::string,
+    std::set<phosphor::led::Layout::LedAction>>
+        twoGroupsWithOneComonLEDInDifferentState = {
+    {   "/xyz/openbmc_project/ledmanager/groups/MultipleLedsASet",{
+            {"One",phosphor::led::Layout::On},
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::On},
+        }
+    },
+    {   "/xyz/openbmc_project/ledmanager/groups/MultipleLedsBSet",{
+            {"Two",phosphor::led::Layout::Blink},
+            {"Four",phosphor::led::Layout::On},
+            {"Five",phosphor::led::Layout::On},
+            {"Six",phosphor::led::Layout::On},
+        }
+    },
+};
+
+static const std::map<std::string,
+    std::set<phosphor::led::Layout::LedAction>>
+        twoGroupsWithMultiplComonLEDOn = {
+    {   "/xyz/openbmc_project/ledmanager/groups/MultipleLedsASet",{
+            {"One",phosphor::led::Layout::On},
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::On},
+        }
+    },
+    {   "/xyz/openbmc_project/ledmanager/groups/MultipleLedsBSet",{
+            {"Two",phosphor::led::Layout::On},
+            {"Six",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::On},
+            {"Seven",phosphor::led::Layout::On},
+        }
+    },
+};
+
+static const std::map<std::string,
+    std::set<phosphor::led::Layout::LedAction>>
+        twoGroupsWithMultipleComonLEDInDifferentState = {
+    {   "/xyz/openbmc_project/ledmanager/groups/MultipleLedsASet",{
+            {"One",phosphor::led::Layout::On},
+            {"Two",phosphor::led::Layout::Blink},
+            {"Three",phosphor::led::Layout::On},
+            {"Four",phosphor::led::Layout::On},
+        }
+    },
+    {   "/xyz/openbmc_project/ledmanager/groups/MultipleLedsBSet",{
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::Blink},
+            {"Five",phosphor::led::Layout::On},
+            {"Six",phosphor::led::Layout::On},
+        }
+    },
+};
diff --git a/test/utest.cpp b/test/utest.cpp
new file mode 100644
index 0000000..38f8196
--- /dev/null
+++ b/test/utest.cpp
@@ -0,0 +1,877 @@
+#include <set>
+#include <algorithm>
+#include <gtest/gtest.h>
+#include "manager.hpp"
+#include "led-test-map.hpp"
+
+using namespace phosphor::led;
+class LedTest : public ::testing::Test
+{
+    public:
+        virtual void SetUp()
+        {
+            // Not having a need at the moment but for future.
+        }
+        virtual void TearDown()
+        {
+            // Leaving upto auto cleanup.
+        }
+};
+
+/** @brief Assert Single LED to On */
+TEST_F(LedTest, assertSingleLedOn)
+{
+    Manager manager(singleLedOn);
+    {
+        // Assert the LEDs.
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group = "/xyz/openbmc_project/ledmanager/groups/SingleLed";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"One",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+}
+
+/** @brief Assert Single LED to Blink */
+TEST_F(LedTest, assertSingleLedBlink)
+{
+    Manager manager(singleLedBlink);
+    {
+        // Assert the LEDs.
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group = "/xyz/openbmc_project/ledmanager/groups/SingleLed";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"One",phosphor::led::Layout::Blink},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+}
+
+/** @brief Assert Single LED to On and Try Assert Again */
+TEST_F(LedTest, assertSingleLedOnAndreAssert)
+{
+    Manager manager(singleLedOn);
+    {
+        // Assert the LEDs.
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group = "/xyz/openbmc_project/ledmanager/groups/SingleLed";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"One",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+    {
+        // Assert the LEDs.
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group = "/xyz/openbmc_project/ledmanager/groups/SingleLed";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        EXPECT_EQ(0, ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+    }
+}
+
+/** @brief Assert Multiple LEDs to On */
+TEST_F(LedTest, assertMultipleLedOn)
+{
+    Manager manager(multipleLedsOn);
+    {
+        // Assert the LEDs.
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group = "/xyz/openbmc_project/ledmanager/groups/MultipleLeds";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"One",phosphor::led::Layout::On},
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+}
+
+/** @brief Assert Multiple LEDs to Blink */
+TEST_F(LedTest, assertMultipleLedBlink)
+{
+    Manager manager(multipleLedsBlink);
+    {
+        // Assert the LEDs.
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group = "/xyz/openbmc_project/ledmanager/groups/MultipleLeds";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"One",phosphor::led::Layout::Blink},
+            {"Two",phosphor::led::Layout::Blink},
+            {"Three",phosphor::led::Layout::Blink},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+}
+
+/** @brief Assert Multiple LEDs to Blink, DeAssert */
+TEST_F(LedTest, assertMultipleLedBlinkAndDeAssert)
+{
+    Manager manager(multipleLedsBlink);
+    {
+        // Assert the LEDs.
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group = "/xyz/openbmc_project/ledmanager/groups/MultipleLeds";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"One",phosphor::led::Layout::Blink},
+            {"Two",phosphor::led::Layout::Blink},
+            {"Three",phosphor::led::Layout::Blink},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+    {
+        // Assert the LEDs.
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group = "/xyz/openbmc_project/ledmanager/groups/MultipleLeds";
+        auto result = manager.setGroupState(group, false, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(false, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refDeAssert = {
+            {"One",phosphor::led::Layout::Blink},
+            {"Two",phosphor::led::Layout::Blink},
+            {"Three",phosphor::led::Layout::Blink},
+        };
+        EXPECT_EQ(refDeAssert.size(), ledsDeAssert.size());
+        EXPECT_EQ(0, ledsAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refDeAssert and ledsDeAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsDeAssert.begin(), ledsDeAssert.end(),
+                            refDeAssert.begin(), refDeAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+}
+
+/** @brief Assert Multiple LEDs to Blink, DeAssert Twice */
+TEST_F(LedTest, assertMultipleLedBlinkAndDeAssertTwice)
+{
+    Manager manager(multipleLedsBlink);
+    {
+        // Assert the LEDs.
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group = "/xyz/openbmc_project/ledmanager/groups/MultipleLeds";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"One",phosphor::led::Layout::Blink},
+            {"Two",phosphor::led::Layout::Blink},
+            {"Three",phosphor::led::Layout::Blink},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+    {
+        // DeAssert the LEDs.
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group = "/xyz/openbmc_project/ledmanager/groups/MultipleLeds";
+        auto result = manager.setGroupState(group, false, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(false, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refDeAssert = {
+            {"One",phosphor::led::Layout::Blink},
+            {"Two",phosphor::led::Layout::Blink},
+            {"Three",phosphor::led::Layout::Blink},
+        };
+        EXPECT_EQ(refDeAssert.size(), ledsDeAssert.size());
+        EXPECT_EQ(0, ledsAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refDeAssert and ledsDeAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsDeAssert.begin(), ledsDeAssert.end(),
+                            refDeAssert.begin(), refDeAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+    {
+        // DeAssert the LEDs.
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group = "/xyz/openbmc_project/ledmanager/groups/MultipleLeds";
+        auto result = manager.setGroupState(group, false, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(false, result);
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+    }
+}
+
+/** @brief Assert Multiple LEDs to mix of On and Blink */
+TEST_F(LedTest, assertMultipleLedOnAndBlink)
+{
+    Manager manager(multipleLedsOnAndBlink);
+    {
+        // Assert the LEDs.
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group = "/xyz/openbmc_project/ledmanager/groups/MultipleLedsMix";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"One",phosphor::led::Layout::Blink},
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::Blink},
+            {"Four",phosphor::led::Layout::On},
+            {"Five",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+}
+
+/** @brief Assert 2 groups having distinct LEDs */
+TEST_F(LedTest, assertTwoGroupsOnWithDistinctLEDOn)
+{
+    Manager manager(twoGroupsWithDistinctLEDsOn);
+    {
+        // Assert Set-A
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsASet";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"One",phosphor::led::Layout::On},
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+    {
+        // Assert Set-B
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsBSet";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"Four",phosphor::led::Layout::On},
+            {"Five",phosphor::led::Layout::On},
+            {"Six",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+}
+
+/** @brief Assert 2 groups having one of the LEDs common */
+TEST_F(LedTest, asserttwoGroupsWithOneComonLEDOn)
+{
+    Manager manager(twoGroupsWithOneComonLEDOn);
+    {
+        // Assert Set-A
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsASet";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"One",phosphor::led::Layout::On},
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+    {
+        // Assert Set-B
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsBSet";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"Four",phosphor::led::Layout::On},
+            {"Six",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+}
+
+/** @brief Assert 2 groups having one of the LEDs common in different state */
+TEST_F(LedTest, assertTwoGroupsWithOneComonLEDInDifferentState)
+{
+    Manager manager(twoGroupsWithOneComonLEDInDifferentState);
+    {
+        // Assert Set-A
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsASet";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"One",phosphor::led::Layout::On},
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+    {
+        // Assert Set-B
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsBSet";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"Two",phosphor::led::Layout::Blink},
+            {"Four",phosphor::led::Layout::On},
+            {"Five",phosphor::led::Layout::On},
+            {"Six",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+}
+
+/** @brief Assert 2 groups having multiple common LEDs in Same State */
+TEST_F(LedTest, assertTwoGroupsWithMultiplComonLEDOn)
+{
+    Manager manager(twoGroupsWithMultiplComonLEDOn);
+    {
+        // Assert Set-B
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsBSet";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"Two",phosphor::led::Layout::On},
+            {"Six",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::On},
+            {"Seven",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+    {
+        // Assert Set-A
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsASet";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"One",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+}
+
+/** @brief Assert 2 groups having multiple LEDs common in different state */
+TEST_F(LedTest, assertTwoGroupsWithMultipleComonLEDInDifferentStates)
+{
+    Manager manager(twoGroupsWithMultipleComonLEDInDifferentState);
+    {
+        // Assert Set-A
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsASet";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"One",phosphor::led::Layout::On},
+            {"Two",phosphor::led::Layout::Blink},
+            {"Three",phosphor::led::Layout::On},
+            {"Four",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+    {
+        // Assert Set-B
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsBSet";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::Blink},
+            {"Five",phosphor::led::Layout::On},
+            {"Six",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+}
+
+/** @brief Assert 2 groups having multiple LEDs common in Same State
+ *         and then De-Assert One
+ */
+TEST_F(LedTest, assertTwoGroupsWithMultipleComonLEDAndDeAssertOne)
+{
+    Manager manager(twoGroupsWithMultiplComonLEDOn);
+    {
+        // Assert Set-A
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsASet";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"One",phosphor::led::Layout::On},
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+    {
+        // Assert Set-B
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsBSet";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"Six",phosphor::led::Layout::On},
+            {"Seven",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+    {
+        // DeAssert Set-A
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsASet";
+        auto result = manager.setGroupState(group, false, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(false, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refDeAssert = {
+            {"One",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refDeAssert.size(), ledsDeAssert.size());
+        EXPECT_EQ(0, ledsAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsDeAssert.begin(), ledsDeAssert.end(),
+                            refDeAssert.begin(), refDeAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+}
+
+/** @brief Assert 2 groups having multiple LEDs common but in
+ *         different state and De-Assert one*/
+TEST_F(LedTest, assertTwoGroupsWithMultipleComonLEDInDifferentStateDeAssertOne)
+{
+    Manager manager(twoGroupsWithMultipleComonLEDInDifferentState);
+    {
+        // Assert Set-B
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsBSet";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::Blink},
+            {"Five",phosphor::led::Layout::On},
+            {"Six",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+    {
+        // Assert Set-A
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsASet";
+        auto result = manager.setGroupState(group, true, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(true, result);
+
+        // Need just the ledsAssserted populated with these.
+        std::set<Layout::LedAction> refAssert = {
+            {"One",phosphor::led::Layout::On},
+            {"Two",phosphor::led::Layout::Blink},
+            {"Three",phosphor::led::Layout::On},
+            {"Four",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refAssert.size(), ledsAssert.size());
+        EXPECT_EQ(0, ledsDeAssert.size());
+        EXPECT_EQ(0, ledsUpdate.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsAssert.begin(), ledsAssert.end(),
+                            refAssert.begin(), refAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+    {
+        // DeAssert Set-A
+        Manager::group ledsAssert {};
+        Manager::group ledsDeAssert {};
+        Manager::group ledsUpdate {};
+
+        auto group ="/xyz/openbmc_project/ledmanager/groups/MultipleLedsASet";
+        auto result = manager.setGroupState(group, false, ledsAssert,
+                                            ledsDeAssert, ledsUpdate);
+        EXPECT_EQ(false, result);
+
+        // Need just the ledsUpdated populated with these.
+        std::set<Layout::LedAction> refUpdate = {
+            {"Two",phosphor::led::Layout::On},
+            {"Three",phosphor::led::Layout::Blink},
+        };
+        EXPECT_EQ(refUpdate.size(), ledsUpdate.size());
+        EXPECT_EQ(0, ledsAssert.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        Manager::group temp {};
+        std::set_difference(ledsUpdate.begin(), ledsUpdate.end(),
+                            refUpdate.begin(), refUpdate.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+
+        // Need just the ledsDeAsserted populated with these.
+        std::set<Layout::LedAction> refDeAssert = {
+            {"One",phosphor::led::Layout::On},
+            {"Four",phosphor::led::Layout::On},
+        };
+        EXPECT_EQ(refDeAssert.size(), ledsDeAssert.size());
+
+        // difference of refAssert and ledsAssert must be null.
+        temp.clear();
+        std::set_difference(ledsDeAssert.begin(), ledsDeAssert.end(),
+                            refDeAssert.begin(), refDeAssert.end(),
+                            std::inserter(temp, temp.begin()));
+        EXPECT_EQ(0, temp.size());
+    }
+}