[ICD] Convert TestICDManager to gtest (#33269)

* Convert TestICDManager to gtest

* Refactor friend tests with a single access point

* Fix openIoT

* remove namespace from friend since they are in the same

* fix typo

* Replace VerifyOrDie with Assert statement

* Remove extra namespaces
diff --git a/src/BUILD.gn b/src/BUILD.gn
index aa65778..61292e1 100644
--- a/src/BUILD.gn
+++ b/src/BUILD.gn
@@ -67,7 +67,6 @@
       "${chip_root}/src/protocols/user_directed_commissioning/tests",
       "${chip_root}/src/transport/retransmit/tests",
       "${chip_root}/src/app/icd/server/tests",
-      "${chip_root}/src/app/icd/server/tests:tests_nltest",
     ]
 
     # Skip DNSSD tests for Mbed platform due to flash memory size limitations
diff --git a/src/app/icd/server/ICDConfigurationData.h b/src/app/icd/server/ICDConfigurationData.h
index 8b87d09..9358f37 100644
--- a/src/app/icd/server/ICDConfigurationData.h
+++ b/src/app/icd/server/ICDConfigurationData.h
@@ -28,13 +28,14 @@
 namespace app {
 // Forward declaration of ICDManager to allow it to be friend with ICDConfigurationData.
 class ICDManager;
-
-// Forward declaration of TestICDManager to allow it to be friend with the ICDConfigurationData.
-// Used in unit tests
-class TestICDManager;
-
 } // namespace app
 
+namespace Test {
+// Forward declaration of ICDConfigurationDataTestAccess tests to allow it to be friend with the ICDConfigurationData.
+// Used in unit tests
+class ICDConfigurationDataTestAccess;
+} // namespace Test
+
 /**
  * @brief ICDConfigurationData manages and stores ICD related configurations for the ICDManager.
  *        Goal of the class is to expose ICD information to all consummers without creating circular dependencies
@@ -99,7 +100,8 @@
     // the ICDManager, the ICDManager is a friend that can access the private setters. If a consummer needs to be notified when a
     // value is changed, they can leverage the Observer events the ICDManager generates. See src/app/icd/server/ICDStateObserver.h
     friend class chip::app::ICDManager;
-    friend class chip::app::TestICDManager;
+
+    friend class chip::Test::ICDConfigurationDataTestAccess;
 
     void SetICDMode(ICDMode mode) { mICDMode = mode; };
     void SetSlowPollingInterval(System::Clock::Milliseconds32 slowPollInterval) { mSlowPollingInterval = slowPollInterval; };
diff --git a/src/app/icd/server/ICDManager.h b/src/app/icd/server/ICDManager.h
index ec7d06b..bf9474b 100644
--- a/src/app/icd/server/ICDManager.h
+++ b/src/app/icd/server/ICDManager.h
@@ -47,9 +47,9 @@
 namespace chip {
 namespace app {
 
-// Forward declaration of TestICDManager to allow it to be friend with ICDManager
+// Forward declaration of TestICDManager tests to allow it to be friend with ICDManager
 // Used in unit tests
-class TestICDManager;
+class TestICDManager_TestShouldCheckInMsgsBeSentAtActiveModeFunction_Test;
 
 /**
  * @brief ICD Manager is responsible of processing the events and triggering the correct action for an ICD
@@ -132,6 +132,8 @@
 
     ICDConfigurationData::ICDMode GetICDMode() { return ICDConfigurationData::GetInstance().GetICDMode(); };
 
+    OperationalState GetOperaionalState() { return mOperationalState; };
+
     /**
      * @brief Adds the referenced observer in parameters to the mStateObserverPool
      * A maximum of CHIP_CONFIG_ICD_OBSERVERS_POOL_SIZE observers can be concurrently registered
@@ -199,7 +201,9 @@
     void OnSubscriptionReport() override;
 
 private:
-    friend class TestICDManager;
+    // TODO : Once <gtest/gtest_prod.h> can be included, use FRIEND_TEST for the friend class.
+    friend class TestICDManager_TestShouldCheckInMsgsBeSentAtActiveModeFunction_Test;
+
     /**
      * @brief UpdateICDMode evaluates in which mode the ICD can be in; SIT or LIT mode.
      *        If the current operating mode does not match the evaluated operating mode, function updates the ICDMode and triggers
diff --git a/src/app/icd/server/tests/BUILD.gn b/src/app/icd/server/tests/BUILD.gn
index 727dd13..0887225 100644
--- a/src/app/icd/server/tests/BUILD.gn
+++ b/src/app/icd/server/tests/BUILD.gn
@@ -19,31 +19,22 @@
 import("${chip_root}/build/chip/chip_test_suite.gni")
 import("${chip_root}/src/app/icd/icd.gni")
 
-chip_test_suite_using_nltest("tests_nltest") {
-  output_name = "libICDServerTestsNL"
+chip_test_suite("tests") {
+  output_name = "libICDServerTests"
 
-  test_sources = [ "TestICDManager.cpp" ]
+  test_sources = [
+    "TestICDManager.cpp",
+    "TestICDMonitoringTable.cpp",
+  ]
+
+  sources = [ "ICDConfigurationDataTestAccess.h" ]
 
   public_deps = [
     "${chip_root}/src/app/icd/server:manager",
     "${chip_root}/src/app/icd/server:monitoring-table",
     "${chip_root}/src/lib/support:test_utils",
     "${chip_root}/src/lib/support:testing",
-    "${chip_root}/src/lib/support:testing_nlunit",
     "${chip_root}/src/messaging/tests:helpers",
-    "${nlunit_test_root}:nlunit-test",
-  ]
-}
-
-chip_test_suite("tests") {
-  output_name = "libICDServerTests"
-
-  test_sources = [ "TestICDMonitoringTable.cpp" ]
-
-  public_deps = [
-    "${chip_root}/src/app/icd/server:monitoring-table",
-    "${chip_root}/src/lib/support:test_utils",
-    "${chip_root}/src/lib/support:testing",
   ]
 
   cflags = [ "-Wconversion" ]
diff --git a/src/app/icd/server/tests/ICDConfigurationDataTestAccess.h b/src/app/icd/server/tests/ICDConfigurationDataTestAccess.h
new file mode 100644
index 0000000..8771ce1
--- /dev/null
+++ b/src/app/icd/server/tests/ICDConfigurationDataTestAccess.h
@@ -0,0 +1,47 @@
+/*
+ *
+ *    Copyright (c) 2024 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#pragma once
+
+#include <app/icd/server/ICDConfigurationData.h>
+
+namespace chip {
+namespace Test {
+/**
+ * @brief Class acts as an accessor to private methods of the ICDConfigurationData class without needing to give friend access to
+ *        each individual test.
+ *        This design is necessary because certain tests validate specific edge cases around specific configurations.
+ *        See ICDConfigurationData.h for more details why SetModeDurations cannot be a public API.
+ */
+class ICDConfigurationDataTestAccess
+{
+public:
+    ICDConfigurationDataTestAccess() = delete;
+    ICDConfigurationDataTestAccess(ICDConfigurationData * data) : mData(data) {}
+
+    CHIP_ERROR SetModeDurations(Optional<System::Clock::Milliseconds32> activeModeDuration,
+                                Optional<System::Clock::Milliseconds32> idleModeDuration)
+    {
+        return mData->SetModeDurations(activeModeDuration, idleModeDuration);
+    }
+
+private:
+    ICDConfigurationData * mData = nullptr;
+};
+
+} // namespace Test
+} // namespace chip
diff --git a/src/app/icd/server/tests/TestICDManager.cpp b/src/app/icd/server/tests/TestICDManager.cpp
index 79b1ee8..366bcb5 100644
--- a/src/app/icd/server/tests/TestICDManager.cpp
+++ b/src/app/icd/server/tests/TestICDManager.cpp
@@ -22,19 +22,18 @@
 #include <app/icd/server/ICDMonitoringTable.h>
 #include <app/icd/server/ICDNotifier.h>
 #include <app/icd/server/ICDStateObserver.h>
+#include <app/icd/server/tests/ICDConfigurationDataTestAccess.h>
 #include <crypto/DefaultSessionKeystore.h>
+#include <gtest/gtest.h>
 #include <lib/core/DataModelTypes.h>
 #include <lib/core/NodeId.h>
 #include <lib/support/TestPersistentStorageDelegate.h>
 #include <lib/support/TimeUtils.h>
-#include <lib/support/UnitTestContext.h>
-#include <lib/support/UnitTestExtendedAssertions.h>
-#include <lib/support/UnitTestRegistration.h>
 #include <messaging/tests/MessagingContext.h>
-#include <nlunit-test.h>
 #include <system/SystemLayerImpl.h>
 
 using namespace chip;
+using namespace chip::Test;
 using namespace chip::app;
 using namespace chip::System;
 using namespace chip::System::Clock;
@@ -44,6 +43,7 @@
 
 namespace {
 
+#if CHIP_CONFIG_ENABLE_ICD_CIP
 // Test Values
 constexpr uint16_t kMaxTestClients      = 2;
 constexpr FabricIndex kTestFabricIndex1 = 1;
@@ -65,6 +65,7 @@
 constexpr uint8_t kKeyBuffer2b[] = {
     0xf2, 0xe2, 0xd2, 0xc2, 0xb2, 0xa2, 0x92, 0x82, 0x72, 0x62, 0x52, 0x42, 0x32, 0x22, 0x12, 0x02
 };
+#endif // CHIP_CONFIG_ENABLE_ICD_CIP
 
 // Taken from the ICDManager Implementation
 enum class ICDTestEventTriggerEvent : uint64_t
@@ -78,6 +79,9 @@
 class TestICDStateObserver : public app::ICDStateObserver
 {
 public:
+    TestICDStateObserver()  = default;
+    ~TestICDStateObserver() = default;
+
     void OnEnterActiveMode() { mOnEnterActiveModeCalled = true; }
     void OnEnterIdleMode() { mOnEnterIdleModeCalled = true; }
     void OnTransitionToIdle() { mOnTransitionToIdleCalled = true; }
@@ -118,68 +122,18 @@
     bool mHasPersistedSubscription = false;
 };
 
-class TestContext : public chip::Test::LoopbackMessagingContext
-{
-public:
-    // Performs shared setup for all tests in the test suite
-    CHIP_ERROR SetUpTestSuite() override
-    {
-        ReturnErrorOnFailure(LoopbackMessagingContext::SetUpTestSuite());
-        ReturnErrorOnFailure(chip::DeviceLayer::PlatformMgr().InitChipStack());
-
-        DeviceLayer::SetSystemLayerForTesting(&GetSystemLayer());
-        mRealClock = &chip::System::SystemClock();
-        System::Clock::Internal::SetSystemClockForTesting(&mMockClock);
-
-        return CHIP_NO_ERROR;
-    }
-
-    // Performs shared teardown for all tests in the test suite
-    void TearDownTestSuite() override
-    {
-        System::Clock::Internal::SetSystemClockForTesting(mRealClock);
-        DeviceLayer::SetSystemLayerForTesting(nullptr);
-
-        chip::DeviceLayer::PlatformMgr().Shutdown();
-        LoopbackMessagingContext::TearDownTestSuite();
-    }
-
-    // Performs setup for each individual test in the test suite
-    CHIP_ERROR SetUp() override
-    {
-        ReturnErrorOnFailure(LoopbackMessagingContext::SetUp());
-
-        mICDStateObserver.ResetAll();
-        mICDManager.RegisterObserver(&mICDStateObserver);
-        mICDManager.Init(&testStorage, &GetFabricTable(), &mKeystore, &GetExchangeManager(), &mSubInfoProvider);
-
-        return CHIP_NO_ERROR;
-    }
-
-    // Performs teardown for each individual test in the test suite
-    void TearDown() override
-    {
-        mICDManager.Shutdown();
-        LoopbackMessagingContext::TearDown();
-    }
-
-    System::Clock::Internal::MockClock mMockClock;
-    TestSessionKeystoreImpl mKeystore;
-    app::ICDManager mICDManager;
-    TestSubscriptionsInfoProvider mSubInfoProvider;
-    TestPersistentStorageDelegate testStorage;
-    TestICDStateObserver mICDStateObserver;
-
-private:
-    System::Clock::ClockBase * mRealClock;
-};
+System::Clock::Internal::MockClock * pMockClock          = nullptr;
+System::Clock::ClockBase * pRealClock                    = nullptr;
+chip::Test::LoopbackMessagingContext * pMessagingContext = nullptr;
 
 } // namespace
 
 namespace chip {
 namespace app {
-class TestICDManager
+
+class TestICDManager : public ::testing::Test
 {
+
 public:
     /*
      * Advance the test Mock clock time by the amout passed in argument
@@ -188,991 +142,987 @@
      *
      * @param time_ms: Value in milliseconds.
      */
-    static void AdvanceClockAndRunEventLoop(TestContext * ctx, Milliseconds64 time)
+    static void AdvanceClockAndRunEventLoop(Milliseconds64 time)
     {
-        ctx->mMockClock.AdvanceMonotonic(time);
-        ctx->GetIOContext().DriveIO();
+        pMockClock->AdvanceMonotonic(time);
+        pMessagingContext->GetIOContext().DriveIO();
     }
 
-    static void TestICDModeDurations(nlTestSuite * aSuite, void * aContext)
+    // Performs shared setup for all tests in the test suite
+    static void SetUpTestSuite()
     {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
+        if (pMockClock == nullptr)
+        {
+            pMockClock = new Clock::Internal::MockClock();
+            ASSERT_NE(pMockClock, nullptr);
+        }
 
-        // After the init we should be in Idle mode
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetIdleModeDuration() + 1_s);
-        // Idle mode Duration expired, ICDManager transitioned to the ActiveMode.
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
-        // Active mode Duration expired, ICDManager transitioned to the IdleMode.
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetIdleModeDuration() + 1_s);
-        // Idle mode Duration expired, ICDManager transitioned to the ActiveMode.
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
+        if (pMessagingContext == nullptr)
+        {
+            pMessagingContext = new LoopbackMessagingContext();
+            ASSERT_NE(pMessagingContext, nullptr);
+        }
 
-        // Events updating the Operation to Active mode can extend the current active mode time by 1 Active mode threshold.
-        // Kick an active Threshold just before the end of the ActiveMode duration and validate that the active mode is extended.
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeDuration() - 1_ms32);
-        ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeThreshold() / 2);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeThreshold());
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
+        ASSERT_EQ(pMessagingContext->SetUpTestSuite(), CHIP_NO_ERROR);
+        ASSERT_EQ(chip::DeviceLayer::PlatformMgr().InitChipStack(), CHIP_NO_ERROR);
+
+        DeviceLayer::SetSystemLayerForTesting(&(pMessagingContext->GetSystemLayer()));
+        pRealClock = &SystemClock();
+        Clock::Internal::SetSystemClockForTesting(pMockClock);
     }
 
-    /**
-     * @brief Test verifies that the ICDManager starts its timers correctly based on if it will have any messages to send
-     *        when the IdleMode timer expires
-     */
-    static void TestICDModeDurationsWith0ActiveModeDurationWithoutActiveSub(nlTestSuite * aSuite, void * aContext)
+    // Performs shared teardown for all tests in the test suite
+    static void TearDownTestSuite()
     {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
-        typedef ICDListener::ICDManagementEvents ICDMEvent;
-        ICDConfigurationData & icdConfigData = ICDConfigurationData::GetInstance();
+        Clock::Internal::SetSystemClockForTesting(pRealClock);
+        DeviceLayer::SetSystemLayerForTesting(nullptr);
 
-        // Set FeatureMap - Configures CIP, UAT and LITS to 1
-        ctx->mICDManager.SetTestFeatureMapValue(0x07);
+        DeviceLayer::PlatformMgr().Shutdown();
+        pMessagingContext->TearDownTestSuite();
 
-        // Set that there are no matching subscriptions
-        ctx->mSubInfoProvider.SetHasActiveSubscription(false);
-        ctx->mSubInfoProvider.SetHasPersistedSubscription(false);
+        if (pMockClock != nullptr)
+        {
+            delete pMockClock;
+            pMockClock = nullptr;
+        }
 
-        // Set New durations for test case
-        Milliseconds32 oldActiveModeDuration = icdConfigData.GetActiveModeDuration();
-        icdConfigData.SetModeDurations(MakeOptional<Milliseconds32>(0), NullOptional);
+        if (pMessagingContext != nullptr)
+        {
+            delete pMessagingContext;
+            pMessagingContext = nullptr;
+        }
 
-        // Verify That ICDManager starts in Idle
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-
-        // Reset IdleModeInterval since it was started before the ActiveModeDuration change
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetIdleModeDuration() + 1_s);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
-
-        // Force the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is now 0
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetActiveModeThreshold() + 1_ms16);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-
-        // Expire Idle mode duration; ICDManager should remain in IdleMode since it has no message to send
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetIdleModeDuration() + 1_s);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-
-        // Add an entry to the ICDMonitoringTable
-        ICDMonitoringTable table(ctx->testStorage, kTestFabricIndex1, kMaxTestClients, &(ctx->mKeystore));
-
-        ICDMonitoringEntry entry(&(ctx->mKeystore));
-        entry.checkInNodeID    = kClientNodeId11;
-        entry.monitoredSubject = kClientNodeId11;
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer1a)));
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == table.Set(0, entry));
-
-        // Trigger register event after first entry was added
-        ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
-
-        // Check ICDManager is now in the LIT operating mode
-        NL_TEST_ASSERT(aSuite, icdConfigData.GetICDMode() == ICDConfigurationData::ICDMode::LIT);
-
-        // Kick an ActiveModeThreshold since a Registration can only happen from an incoming message that would transition the ICD
-        // to ActiveMode
-        ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
-
-        // Return the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is 0
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetActiveModeThreshold() + 1_ms16);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-
-        // Expire IdleMode timer - Device should be in ActiveMode since it has an ICDM registration
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetIdleModeDuration() + 1_s);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
-
-        // Remove entry from the fabric - ICDManager won't have any messages to send
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == table.Remove(0));
-        NL_TEST_ASSERT(aSuite, table.IsEmpty());
-
-        // Return the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is 0
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetActiveModeThreshold() + 1_ms16);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-
-        // Expire Idle mode duration; ICDManager should remain in IdleMode since it has no message to send
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetIdleModeDuration() + 1_s);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-
-        // Reset Old durations
-        icdConfigData.SetModeDurations(MakeOptional(oldActiveModeDuration), NullOptional);
+        pRealClock = nullptr;
     }
 
-    /**
-     * @brief Test verifies that the ICDManager remains in IdleMode since it will not have any messages to send
-     *        when the IdleMode timer expires
-     */
-    static void TestICDModeDurationsWith0ActiveModeDurationWithActiveSub(nlTestSuite * aSuite, void * aContext)
+    // Performs setup for each individual test in the test suite
+    void SetUp() override
     {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
-        typedef ICDListener::ICDManagementEvents ICDMEvent;
-        ICDConfigurationData & icdConfigData = ICDConfigurationData::GetInstance();
+        EXPECT_EQ(pMessagingContext->SetUp(), CHIP_NO_ERROR);
 
-        // Set FeatureMap - Configures CIP, UAT and LITS to 1
-        ctx->mICDManager.SetTestFeatureMapValue(0x07);
-
-        // Set that there are not matching subscriptions
-        ctx->mSubInfoProvider.SetHasActiveSubscription(true);
-        ctx->mSubInfoProvider.SetHasPersistedSubscription(true);
-
-        // Set New durations for test case
-        Milliseconds32 oldActiveModeDuration = icdConfigData.GetActiveModeDuration();
-        icdConfigData.SetModeDurations(MakeOptional<Milliseconds32>(0), NullOptional);
-
-        // Verify That ICDManager starts in Idle
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-
-        // Reset IdleModeInterval since it was started before the ActiveModeDuration change
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetIdleModeDuration() + 1_s);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
-
-        // Force the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is now 0
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetActiveModeThreshold() + 1_ms16);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-
-        // Expire Idle mode duration; ICDManager should remain in IdleMode since it has no message to send
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetIdleModeDuration() + 1_s);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-
-        // Add an entry to the ICDMonitoringTable
-        ICDMonitoringTable table(ctx->testStorage, kTestFabricIndex1, kMaxTestClients, &(ctx->mKeystore));
-
-        ICDMonitoringEntry entry(&(ctx->mKeystore));
-        entry.checkInNodeID    = kClientNodeId11;
-        entry.monitoredSubject = kClientNodeId11;
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer1a)));
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == table.Set(0, entry));
-
-        // Trigger register event after first entry was added
-        ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
-
-        // Check ICDManager is now in the LIT operating mode
-        NL_TEST_ASSERT(aSuite, icdConfigData.GetICDMode() == ICDConfigurationData::ICDMode::LIT);
-
-        // Kick an ActiveModeThreshold since a Registration can only happen from an incoming message that would transition the ICD
-        // to ActiveMode
-        ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
-
-        // Return the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is 0
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetActiveModeThreshold() + 1_ms16);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-
-        // Expire IdleMode timer - Device stay in IdleMode since it has an active subscription for the ICDM entry
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetIdleModeDuration() + 1_s);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-
-        // Remove entry from the fabric
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == table.Remove(0));
-        NL_TEST_ASSERT(aSuite, table.IsEmpty());
-
-        // Trigger unregister event after last entry was removed
-        ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
-
-        // Check ICDManager is now in the LIT operating mode
-        NL_TEST_ASSERT(aSuite, icdConfigData.GetICDMode() == ICDConfigurationData::ICDMode::SIT);
-
-        // Kick an ActiveModeThreshold since a Unregistration can only happen from an incoming message that would transition the ICD
-        // to ActiveMode
-        ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
-
-        // Return the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is 0
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetActiveModeThreshold() + 1_ms16);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-
-        // Expire Idle mode duration; ICDManager should remain in IdleMode since it has no message to send
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetIdleModeDuration() + 1_s);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-
-        // Reset Old durations
-        icdConfigData.SetModeDurations(MakeOptional<Milliseconds32>(oldActiveModeDuration), NullOptional);
+        mICDStateObserver.ResetAll();
+        mICDManager.RegisterObserver(&mICDStateObserver);
+        mICDManager.Init(&testStorage, &(pMessagingContext->GetFabricTable()), &mKeystore,
+                         &(pMessagingContext->GetExchangeManager()), &mSubInfoProvider);
     }
 
-    static void TestKeepActivemodeRequests(nlTestSuite * aSuite, void * aContext)
+    // Performs teardown for each individual test in the test suite
+    void TearDown() override
     {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
-        typedef ICDListener::KeepActiveFlag ActiveFlag;
-        ICDNotifier notifier = ICDNotifier::GetInstance();
-
-        // Setting a requirement will transition the ICD to active mode.
-        notifier.NotifyActiveRequestNotification(ActiveFlag::kCommissioningWindowOpen);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
-        // Advance time so active mode duration expires.
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
-        // Requirement flag still set. We stay in active mode
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
-
-        // Remove requirement. we should directly transition to idle mode.
-        notifier.NotifyActiveRequestWithdrawal(ActiveFlag::kCommissioningWindowOpen);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-
-        notifier.NotifyActiveRequestNotification(ActiveFlag::kFailSafeArmed);
-        // Requirement will transition us to active mode.
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
-
-        // Advance time, but by less than the active mode duration and remove the requirement.
-        // We should stay in active mode.
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeDuration() / 2);
-        notifier.NotifyActiveRequestWithdrawal(ActiveFlag::kFailSafeArmed);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
-
-        // Advance time again, The activemode duration is completed.
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-
-        // Set two requirements
-        notifier.NotifyActiveRequestNotification(ActiveFlag::kFailSafeArmed);
-        notifier.NotifyActiveRequestNotification(ActiveFlag::kExchangeContextOpen);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
-        // advance time so the active mode duration expires.
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
-        // A requirement flag is still set. We stay in active mode.
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
-
-        // remove 1 requirement. Active mode is maintained
-        notifier.NotifyActiveRequestWithdrawal(ActiveFlag::kFailSafeArmed);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
-        // remove the last requirement
-        notifier.NotifyActiveRequestWithdrawal(ActiveFlag::kExchangeContextOpen);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
+        mICDManager.Shutdown();
+        pMessagingContext->TearDown();
     }
 
-    /**
-     * @brief Test that verifies that the ICDManager is in the correct operating mode based on entries
-     *        in the ICDMonitoringTable
-     */
-    static void TestICDMRegisterUnregisterEvents(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
-        typedef ICDListener::ICDManagementEvents ICDMEvent;
-        ICDNotifier notifier = ICDNotifier::GetInstance();
+    TestSessionKeystoreImpl mKeystore;
+    ICDManager mICDManager;
+    TestSubscriptionsInfoProvider mSubInfoProvider;
+    TestPersistentStorageDelegate testStorage;
+    TestICDStateObserver mICDStateObserver;
+};
 
-        // Set FeatureMap
-        // Configures CIP, UAT and LITS to 1
-        ctx->mICDManager.SetTestFeatureMapValue(0x07);
+TEST_F(TestICDManager, TestICDModeDurations)
+{
+    // After the init we should be in Idle mode
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() + 1_s);
+    // Idle mode Duration expired, ICDManager transitioned to the ActiveMode.
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
+    // Active mode Duration expired, ICDManager transitioned to the IdleMode.
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() + 1_s);
+    // Idle mode Duration expired, ICDManager transitioned to the ActiveMode.
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
 
-        // Check ICDManager starts in SIT mode if no entries are present
-        NL_TEST_ASSERT(aSuite, ICDConfigurationData::GetInstance().GetICDMode() == ICDConfigurationData::ICDMode::SIT);
+    // Events updating the Operation to Active mode can extend the current active mode time by 1 Active mode threshold.
+    // Kick an active Threshold just before the end of the ActiveMode duration and validate that the active mode is extended.
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() - 1_ms32);
+    ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeThreshold() / 2);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeThreshold());
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
+}
 
-        // Trigger a "fake" register, ICDManager shoudl remain in SIT mode
-        notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+#if CHIP_CONFIG_ENABLE_ICD_CIP
+/**
+ * @brief Test verifies that the ICDManager starts its timers correctly based on if it will have any messages to send
+ *        when the IdleMode timer expires
+ */
+TEST_F(TestICDManager, TestICDModeDurationsWith0ActiveModeDurationWithoutActiveSub)
+{
+    typedef ICDListener::ICDManagementEvents ICDMEvent;
+    ICDConfigurationData & icdConfigData = ICDConfigurationData::GetInstance();
+    ICDConfigurationDataTestAccess privateIcdConfigData(&icdConfigData);
 
-        // Check ICDManager stayed in SIT mode
-        NL_TEST_ASSERT(aSuite, ICDConfigurationData::GetInstance().GetICDMode() == ICDConfigurationData::ICDMode::SIT);
+    // Set FeatureMap - Configures CIP, UAT and LITS to 1
+    mICDManager.SetTestFeatureMapValue(0x07);
 
-        // Create tables with different fabrics
-        ICDMonitoringTable table1(ctx->testStorage, kTestFabricIndex1, kMaxTestClients, &(ctx->mKeystore));
-        ICDMonitoringTable table2(ctx->testStorage, kTestFabricIndex2, kMaxTestClients, &(ctx->mKeystore));
+    // Set that there are no matching subscriptions
+    mSubInfoProvider.SetHasActiveSubscription(false);
+    mSubInfoProvider.SetHasPersistedSubscription(false);
 
-        // Add first entry to the first fabric
-        ICDMonitoringEntry entry1(&(ctx->mKeystore));
-        entry1.checkInNodeID    = kClientNodeId11;
-        entry1.monitoredSubject = kClientNodeId12;
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry1.SetKey(ByteSpan(kKeyBuffer1a)));
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == table1.Set(0, entry1));
+    // Set New durations for test case
+    Milliseconds32 oldActiveModeDuration = icdConfigData.GetActiveModeDuration();
+    privateIcdConfigData.SetModeDurations(MakeOptional<Milliseconds32>(0), NullOptional);
 
-        // Trigger register event after first entry was added
-        notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+    // Verify That ICDManager starts in Idle
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
 
-        // Check ICDManager is now in the LIT operating mode
-        NL_TEST_ASSERT(aSuite, ICDConfigurationData::GetInstance().GetICDMode() == ICDConfigurationData::ICDMode::LIT);
+    // Reset IdleModeInterval since it was started before the ActiveModeDuration change
+    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
 
-        // Add second entry to the first fabric
-        ICDMonitoringEntry entry2(&(ctx->mKeystore));
-        entry2.checkInNodeID    = kClientNodeId12;
-        entry2.monitoredSubject = kClientNodeId11;
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry2.SetKey(ByteSpan(kKeyBuffer1b)));
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == table1.Set(1, entry2));
+    // Force the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is now 0
+    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeThreshold() + 1_ms16);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
 
-        // Trigger register event after first entry was added
-        notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+    // Expire Idle mode duration; ICDManager should remain in IdleMode since it has no message to send
+    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
 
-        // Check ICDManager is now in the LIT operating mode
-        NL_TEST_ASSERT(aSuite, ICDConfigurationData::GetInstance().GetICDMode() == ICDConfigurationData::ICDMode::LIT);
+    // Add an entry to the ICDMonitoringTable
+    ICDMonitoringTable table(testStorage, kTestFabricIndex1, kMaxTestClients, &(mKeystore));
 
-        // Add first entry to the first fabric
-        ICDMonitoringEntry entry3(&(ctx->mKeystore));
-        entry3.checkInNodeID    = kClientNodeId21;
-        entry3.monitoredSubject = kClientNodeId22;
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry3.SetKey(ByteSpan(kKeyBuffer2a)));
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == table2.Set(0, entry3));
+    ICDMonitoringEntry entry(&(mKeystore));
+    entry.checkInNodeID    = kClientNodeId11;
+    entry.monitoredSubject = kClientNodeId11;
+    EXPECT_EQ(CHIP_NO_ERROR, entry.SetKey(ByteSpan(kKeyBuffer1a)));
+    EXPECT_EQ(CHIP_NO_ERROR, table.Set(0, entry));
 
-        // Trigger register event after first entry was added
-        notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+    // Trigger register event after first entry was added
+    ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
 
-        // Check ICDManager is now in the LIT operating mode
-        NL_TEST_ASSERT(aSuite, ICDConfigurationData::GetInstance().GetICDMode() == ICDConfigurationData::ICDMode::LIT);
+    // Check ICDManager is now in the LIT operating mode
+    EXPECT_EQ(icdConfigData.GetICDMode(), ICDConfigurationData::ICDMode::LIT);
 
-        // Add second entry to the first fabric
-        ICDMonitoringEntry entry4(&(ctx->mKeystore));
-        entry4.checkInNodeID    = kClientNodeId22;
-        entry4.monitoredSubject = kClientNodeId21;
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry4.SetKey(ByteSpan(kKeyBuffer2b)));
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == table2.Set(1, entry4));
+    // Kick an ActiveModeThreshold since a Registration can only happen from an incoming message that would transition the ICD
+    // to ActiveMode
+    ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
 
-        // Clear a fabric
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == table2.RemoveAll());
+    // Return the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is 0
+    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeThreshold() + 1_ms16);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
 
-        // Trigger register event after fabric was cleared
-        notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+    // Expire IdleMode timer - Device should be in ActiveMode since it has an ICDM registration
+    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
 
-        // Check ICDManager is still in the LIT operating mode
-        NL_TEST_ASSERT(aSuite, ICDConfigurationData::GetInstance().GetICDMode() == ICDConfigurationData::ICDMode::LIT);
+    // Remove entry from the fabric - ICDManager won't have any messages to send
+    EXPECT_EQ(CHIP_NO_ERROR, table.Remove(0));
+    EXPECT_TRUE(table.IsEmpty());
 
-        // Remove single entry from remaining fabric
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == table1.Remove(1));
+    // Return the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is 0
+    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeThreshold() + 1_ms16);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
 
-        // Trigger register event after fabric was cleared
-        notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+    // Expire Idle mode duration; ICDManager should remain in IdleMode since it has no message to send
+    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
 
-        // Check ICDManager is still in the LIT operating mode
-        NL_TEST_ASSERT(aSuite, ICDConfigurationData::GetInstance().GetICDMode() == ICDConfigurationData::ICDMode::LIT);
+    // Reset Old durations
+    privateIcdConfigData.SetModeDurations(MakeOptional(oldActiveModeDuration), NullOptional);
+}
 
-        // Remove last entry from remaining fabric
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == table1.Remove(0));
-        NL_TEST_ASSERT(aSuite, table1.IsEmpty());
-        NL_TEST_ASSERT(aSuite, table2.IsEmpty());
+/**
+ * @brief Test verifies that the ICDManager remains in IdleMode since it will not have any messages to send
+ *        when the IdleMode timer expires
+ */
+TEST_F(TestICDManager, TestICDModeDurationsWith0ActiveModeDurationWithActiveSub)
+{
+    typedef ICDListener::ICDManagementEvents ICDMEvent;
+    ICDConfigurationData & icdConfigData = ICDConfigurationData::GetInstance();
+    ICDConfigurationDataTestAccess privateIcdConfigData(&icdConfigData);
 
-        // Trigger register event after fabric was cleared
-        notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+    // Set FeatureMap - Configures CIP, UAT and LITS to 1
+    mICDManager.SetTestFeatureMapValue(0x07);
 
-        // Check ICDManager is still in the LIT operating mode
-        NL_TEST_ASSERT(aSuite, ICDConfigurationData::GetInstance().GetICDMode() == ICDConfigurationData::ICDMode::SIT);
-    }
+    // Set that there are not matching subscriptions
+    mSubInfoProvider.SetHasActiveSubscription(true);
+    mSubInfoProvider.SetHasPersistedSubscription(true);
 
-    static void TestICDCounter(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
-        uint32_t counter  = ICDConfigurationData::GetInstance().GetICDCounter().GetValue();
+    // Set New durations for test case
+    Milliseconds32 oldActiveModeDuration = icdConfigData.GetActiveModeDuration();
+    privateIcdConfigData.SetModeDurations(MakeOptional<Milliseconds32>(0), NullOptional);
 
-        // Shut down and reinit ICDManager to increment counter
-        ctx->mICDManager.Shutdown();
-        ctx->mICDManager.Init(&(ctx->testStorage), &(ctx->GetFabricTable()), &(ctx->mKeystore), &(ctx->GetExchangeManager()),
-                              &(ctx->mSubInfoProvider));
-        ctx->mICDManager.RegisterObserver(&(ctx->mICDStateObserver));
+    // Verify That ICDManager starts in Idle
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
 
-        NL_TEST_ASSERT_EQUALS(aSuite, counter + ICDConfigurationData::kICDCounterPersistenceIncrement,
-                              ICDConfigurationData::GetInstance().GetICDCounter().GetValue());
-    }
+    // Reset IdleModeInterval since it was started before the ActiveModeDuration change
+    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
 
-    static void TestOnSubscriptionReport(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx    = static_cast<TestContext *>(aContext);
-        ICDNotifier notifier = ICDNotifier::GetInstance();
+    // Force the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is now 0
+    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeThreshold() + 1_ms16);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
 
-        // After the init we should be in Idle mode
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
+    // Expire Idle mode duration; ICDManager should remain in IdleMode since it has no message to send
+    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
 
-        // Trigger a subscription report
-        notifier.NotifySubscriptionReport();
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
+    // Add an entry to the ICDMonitoringTable
+    ICDMonitoringTable table(testStorage, kTestFabricIndex1, kMaxTestClients, &(mKeystore));
 
-        // Trigger another subscription report - active time should not be increased
-        notifier.NotifySubscriptionReport();
+    ICDMonitoringEntry entry(&(mKeystore));
+    entry.checkInNodeID    = kClientNodeId11;
+    entry.monitoredSubject = kClientNodeId11;
+    EXPECT_EQ(CHIP_NO_ERROR, entry.SetKey(ByteSpan(kKeyBuffer1a)));
+    EXPECT_EQ(CHIP_NO_ERROR, table.Set(0, entry));
 
-        // Advance time so active mode interval expires.
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
+    // Trigger register event after first entry was added
+    ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
 
-        // After the init we should be in Idle mode
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-    }
+    // Check ICDManager is now in the LIT operating mode
+    EXPECT_EQ(icdConfigData.GetICDMode(), ICDConfigurationData::ICDMode::LIT);
 
-    /**
-     * @brief Test verifies the logic of the ICDManager when it receives a StayActiveRequest
-     */
-    static void TestICDMStayActive(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx                    = static_cast<TestContext *>(aContext);
-        ICDNotifier notifier                 = ICDNotifier::GetInstance();
-        ICDConfigurationData & icdConfigData = ICDConfigurationData::GetInstance();
+    // Kick an ActiveModeThreshold since a Registration can only happen from an incoming message that would transition the ICD
+    // to ActiveMode
+    ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
 
-        // Verify That ICDManager starts in Idle
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
+    // Return the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is 0
+    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeThreshold() + 1_ms16);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
 
-        // Trigger a subscription report. Put the ICD manager into active mode.
-        notifier.NotifySubscriptionReport();
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
+    // Expire IdleMode timer - Device stay in IdleMode since it has an active subscription for the ICDM entry
+    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
 
-        // Advance time just before ActiveMode timer expires
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetActiveModeDuration() - 1_ms32);
-        // Confirm ICD manager is in active mode
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
+    // Remove entry from the fabric
+    EXPECT_EQ(CHIP_NO_ERROR, table.Remove(0));
+    EXPECT_TRUE(table.IsEmpty());
 
-        uint32_t stayActiveRequestedMs = 20000;
-        // Send a stay active request for 20 seconds
-        uint32_t stayActivePromisedMs = ctx->mICDManager.StayActiveRequest(stayActiveRequestedMs);
-        // confirm the promised time is the same as the requested time
-        NL_TEST_ASSERT(aSuite, stayActivePromisedMs == stayActiveRequestedMs);
+    // Trigger unregister event after last entry was removed
+    ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
 
-        // Advance time by the duration of the stay stayActiveRequestedMs - 1 ms
-        AdvanceClockAndRunEventLoop(ctx, Milliseconds32(stayActiveRequestedMs) - 1_ms32);
-        // Confirm ICD manager is in active mode
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
+    // Check ICDManager is now in the LIT operating mode
+    EXPECT_EQ(icdConfigData.GetICDMode(), ICDConfigurationData::ICDMode::SIT);
 
-        // Advance time by 1ms and Confirm ICD manager is in idle mode
-        AdvanceClockAndRunEventLoop(ctx, 1_ms32);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
+    // Kick an ActiveModeThreshold since a Unregistration can only happen from an incoming message that would transition the ICD
+    // to ActiveMode
+    ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
 
-        // Trigger a subscription report Put the ICD manager into active mode
-        notifier.NotifySubscriptionReport();
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
+    // Return the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is 0
+    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeThreshold() + 1_ms16);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
 
-        // Advance time by the duration of the stay active request - 1 ms
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetActiveModeDuration() - 1_ms32);
-        stayActiveRequestedMs = 35000;
-        // Send a stay active request for 35 seconds, which is higher than the maximum stay active duration (30 seconds)
-        stayActivePromisedMs = ctx->mICDManager.StayActiveRequest(stayActiveRequestedMs);
-        // confirm the promised time is the maximum stay active duration (30 seconds)
-        NL_TEST_ASSERT(aSuite, stayActivePromisedMs == 30000);
+    // Expire Idle mode duration; ICDManager should remain in IdleMode since it has no message to send
+    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
 
-        // Advance time by the duration of the max stay active duration - 1 ms
-        AdvanceClockAndRunEventLoop(ctx, Milliseconds32(30000) - 1_ms32);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
+    // Reset Old durations
+    privateIcdConfigData.SetModeDurations(MakeOptional<Milliseconds32>(oldActiveModeDuration), NullOptional);
+}
+#endif // CHIP_CONFIG_ENABLE_ICD_CIP
 
-        // Advance time by 1ms and Confirm ICD manager is in idle mode
-        AdvanceClockAndRunEventLoop(ctx, 1_ms32);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
+TEST_F(TestICDManager, TestKeepActivemodeRequests)
+{
+    typedef ICDListener::KeepActiveFlag ActiveFlag;
+    ICDNotifier notifier = ICDNotifier::GetInstance();
 
-        // Trigger a subscription report Put the ICD manager into active mode
-        notifier.NotifySubscriptionReport();
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
+    // Setting a requirement will transition the ICD to active mode.
+    notifier.NotifyActiveRequestNotification(ActiveFlag::kCommissioningWindowOpen);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
+    // Advance time so active mode duration expires.
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
+    // Requirement flag still set. We stay in active mode
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
 
-        // Advance time by the duration of the stay active request - 1 ms
-        AdvanceClockAndRunEventLoop(ctx, icdConfigData.GetActiveModeDuration() - 1_ms32);
-        stayActiveRequestedMs = 30000;
-        // Send a stay active request for 30 seconds
-        stayActivePromisedMs = ctx->mICDManager.StayActiveRequest(stayActiveRequestedMs);
-        // confirm the promised time is the same as the requested time
-        NL_TEST_ASSERT(aSuite, stayActivePromisedMs == 30000);
+    // Remove requirement. we should directly transition to idle mode.
+    notifier.NotifyActiveRequestWithdrawal(ActiveFlag::kCommissioningWindowOpen);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
 
-        // Advance time by the duration of the stay active request - 20000 ms
-        AdvanceClockAndRunEventLoop(ctx, Milliseconds32(stayActiveRequestedMs) - 20000_ms32);
-        // Confirm ICD manager is in active mode, we should have 20000 seconds left at that point
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
+    notifier.NotifyActiveRequestNotification(ActiveFlag::kFailSafeArmed);
+    // Requirement will transition us to active mode.
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
 
-        stayActiveRequestedMs = 10000;
-        stayActivePromisedMs  = ctx->mICDManager.StayActiveRequest(stayActiveRequestedMs);
-        // confirm the promised time is 20000 since the device is already planing to stay active longer than the requested time
-        NL_TEST_ASSERT(aSuite, stayActivePromisedMs == 20000);
-    }
+    // Advance time, but by less than the active mode duration and remove the requirement.
+    // We should stay in active mode.
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() / 2);
+    notifier.NotifyActiveRequestWithdrawal(ActiveFlag::kFailSafeArmed);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
+
+    // Advance time again, The activemode duration is completed.
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
+
+    // Set two requirements
+    notifier.NotifyActiveRequestNotification(ActiveFlag::kFailSafeArmed);
+    notifier.NotifyActiveRequestNotification(ActiveFlag::kExchangeContextOpen);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
+    // advance time so the active mode duration expires.
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
+    // A requirement flag is still set. We stay in active mode.
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
+
+    // remove 1 requirement. Active mode is maintained
+    notifier.NotifyActiveRequestWithdrawal(ActiveFlag::kFailSafeArmed);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
+    // remove the last requirement
+    notifier.NotifyActiveRequestWithdrawal(ActiveFlag::kExchangeContextOpen);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
+}
+
+#if CHIP_CONFIG_ENABLE_ICD_CIP
+/**
+ * @brief Test that verifies that the ICDManager is in the correct operating mode based on entries
+ *        in the ICDMonitoringTable
+ */
+TEST_F(TestICDManager, TestICDMRegisterUnregisterEvents)
+{
+    typedef ICDListener::ICDManagementEvents ICDMEvent;
+    ICDNotifier notifier = ICDNotifier::GetInstance();
+
+    // Set FeatureMap
+    // Configures CIP, UAT and LITS to 1
+    mICDManager.SetTestFeatureMapValue(0x07);
+
+    // Check ICDManager starts in SIT mode if no entries are present
+    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::SIT);
+
+    // Trigger a "fake" register, ICDManager shoudl remain in SIT mode
+    notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+
+    // Check ICDManager stayed in SIT mode
+    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::SIT);
+
+    // Create tables with different fabrics
+    ICDMonitoringTable table1(testStorage, kTestFabricIndex1, kMaxTestClients, &(mKeystore));
+    ICDMonitoringTable table2(testStorage, kTestFabricIndex2, kMaxTestClients, &(mKeystore));
+
+    // Add first entry to the first fabric
+    ICDMonitoringEntry entry1(&(mKeystore));
+    entry1.checkInNodeID    = kClientNodeId11;
+    entry1.monitoredSubject = kClientNodeId12;
+    EXPECT_EQ(CHIP_NO_ERROR, entry1.SetKey(ByteSpan(kKeyBuffer1a)));
+    EXPECT_EQ(CHIP_NO_ERROR, table1.Set(0, entry1));
+
+    // Trigger register event after first entry was added
+    notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+
+    // Check ICDManager is now in the LIT operating mode
+    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::LIT);
+
+    // Add second entry to the first fabric
+    ICDMonitoringEntry entry2(&(mKeystore));
+    entry2.checkInNodeID    = kClientNodeId12;
+    entry2.monitoredSubject = kClientNodeId11;
+    EXPECT_EQ(CHIP_NO_ERROR, entry2.SetKey(ByteSpan(kKeyBuffer1b)));
+    EXPECT_EQ(CHIP_NO_ERROR, table1.Set(1, entry2));
+
+    // Trigger register event after first entry was added
+    notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+
+    // Check ICDManager is now in the LIT operating mode
+    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::LIT);
+
+    // Add first entry to the first fabric
+    ICDMonitoringEntry entry3(&(mKeystore));
+    entry3.checkInNodeID    = kClientNodeId21;
+    entry3.monitoredSubject = kClientNodeId22;
+    EXPECT_EQ(CHIP_NO_ERROR, entry3.SetKey(ByteSpan(kKeyBuffer2a)));
+    EXPECT_EQ(CHIP_NO_ERROR, table2.Set(0, entry3));
+
+    // Trigger register event after first entry was added
+    notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+
+    // Check ICDManager is now in the LIT operating mode
+    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::LIT);
+
+    // Add second entry to the first fabric
+    ICDMonitoringEntry entry4(&(mKeystore));
+    entry4.checkInNodeID    = kClientNodeId22;
+    entry4.monitoredSubject = kClientNodeId21;
+    EXPECT_EQ(CHIP_NO_ERROR, entry4.SetKey(ByteSpan(kKeyBuffer2b)));
+    EXPECT_EQ(CHIP_NO_ERROR, table2.Set(1, entry4));
+
+    // Clear a fabric
+    EXPECT_EQ(CHIP_NO_ERROR, table2.RemoveAll());
+
+    // Trigger register event after fabric was cleared
+    notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+
+    // Check ICDManager is still in the LIT operating mode
+    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::LIT);
+
+    // Remove single entry from remaining fabric
+    EXPECT_EQ(CHIP_NO_ERROR, table1.Remove(1));
+
+    // Trigger register event after fabric was cleared
+    notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+
+    // Check ICDManager is still in the LIT operating mode
+    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::LIT);
+
+    // Remove last entry from remaining fabric
+    EXPECT_EQ(CHIP_NO_ERROR, table1.Remove(0));
+    EXPECT_TRUE(table1.IsEmpty());
+    EXPECT_TRUE(table2.IsEmpty());
+
+    // Trigger register event after fabric was cleared
+    notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+
+    // Check ICDManager is still in the LIT operating mode
+    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::SIT);
+}
+
+TEST_F(TestICDManager, TestICDCounter)
+{
+    uint32_t counter = ICDConfigurationData::GetInstance().GetICDCounter().GetValue();
+
+    // Shut down and reinit ICDManager to increment counter
+    mICDManager.Shutdown();
+    mICDManager.Init(&(testStorage), &(pMessagingContext->GetFabricTable()), &(mKeystore),
+                     &(pMessagingContext->GetExchangeManager()), &(mSubInfoProvider));
+    mICDManager.RegisterObserver(&(mICDStateObserver));
+
+    EXPECT_EQ(counter + ICDConfigurationData::kICDCounterPersistenceIncrement,
+              ICDConfigurationData::GetInstance().GetICDCounter().GetValue());
+}
+
+TEST_F(TestICDManager, TestOnSubscriptionReport)
+{
+    ICDNotifier notifier = ICDNotifier::GetInstance();
+
+    // After the init we should be in Idle mode
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
+
+    // Trigger a subscription report
+    notifier.NotifySubscriptionReport();
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
+
+    // Trigger another subscription report - active time should not be increased
+    notifier.NotifySubscriptionReport();
+
+    // Advance time so active mode interval expires.
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
+
+    // After the init we should be in Idle mode
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
+}
+#endif // CHIP_CONFIG_ENABLE_ICD_CIP
+
+/**
+ * @brief Test verifies the logic of the ICDManager when it receives a StayActiveRequest
+ */
+TEST_F(TestICDManager, TestICDMStayActive)
+{
+    ICDNotifier notifier                 = ICDNotifier::GetInstance();
+    ICDConfigurationData & icdConfigData = ICDConfigurationData::GetInstance();
+
+    // Verify That ICDManager starts in Idle
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
+
+    // Trigger a subscription report. Put the ICD manager into active mode.
+    notifier.NotifySubscriptionReport();
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
+
+    // Advance time just before ActiveMode timer expires
+    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeDuration() - 1_ms32);
+    // Confirm ICD manager is in active mode
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
+
+    uint32_t stayActiveRequestedMs = 20000;
+    // Send a stay active request for 20 seconds
+    uint32_t stayActivePromisedMs = mICDManager.StayActiveRequest(stayActiveRequestedMs);
+    // confirm the promised time is the same as the requested time
+    EXPECT_EQ(stayActivePromisedMs, stayActiveRequestedMs);
+
+    // Advance time by the duration of the stay stayActiveRequestedMs - 1 ms
+    AdvanceClockAndRunEventLoop(Milliseconds32(stayActiveRequestedMs) - 1_ms32);
+    // Confirm ICD manager is in active mode
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
+
+    // Advance time by 1ms and Confirm ICD manager is in idle mode
+    AdvanceClockAndRunEventLoop(1_ms32);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
+
+    // Trigger a subscription report Put the ICD manager into active mode
+    notifier.NotifySubscriptionReport();
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
+
+    // Advance time by the duration of the stay active request - 1 ms
+    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeDuration() - 1_ms32);
+    stayActiveRequestedMs = 35000;
+    // Send a stay active request for 35 seconds, which is higher than the maximum stay active duration (30 seconds)
+    stayActivePromisedMs = mICDManager.StayActiveRequest(stayActiveRequestedMs);
+    // confirm the promised time is the maximum stay active duration (30 seconds)
+    EXPECT_EQ(stayActivePromisedMs, 30000UL);
+
+    // Advance time by the duration of the max stay active duration - 1 ms
+    AdvanceClockAndRunEventLoop(Milliseconds32(30000) - 1_ms32);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
+
+    // Advance time by 1ms and Confirm ICD manager is in idle mode
+    AdvanceClockAndRunEventLoop(1_ms32);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
+
+    // Trigger a subscription report Put the ICD manager into active mode
+    notifier.NotifySubscriptionReport();
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
+
+    // Advance time by the duration of the stay active request - 1 ms
+    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeDuration() - 1_ms32);
+    stayActiveRequestedMs = 30000;
+    // Send a stay active request for 30 seconds
+    stayActivePromisedMs = mICDManager.StayActiveRequest(stayActiveRequestedMs);
+    // confirm the promised time is the same as the requested time
+    EXPECT_EQ(stayActivePromisedMs, 30000UL);
+
+    // Advance time by the duration of the stay active request - 20000 ms
+    AdvanceClockAndRunEventLoop(Milliseconds32(stayActiveRequestedMs) - 20000_ms32);
+    // Confirm ICD manager is in active mode, we should have 20000 seconds left at that point
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
+
+    stayActiveRequestedMs = 10000;
+    stayActivePromisedMs  = mICDManager.StayActiveRequest(stayActiveRequestedMs);
+    // confirm the promised time is 20000 since the device is already planing to stay active longer than the requested time
+    EXPECT_EQ(stayActivePromisedMs, 20000UL);
+}
 
 #if CHIP_CONFIG_ENABLE_ICD_CIP
 #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
 #if CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
-    static void TestShouldCheckInMsgsBeSentAtActiveModeFunction(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
+TEST_F(TestICDManager, TestShouldCheckInMsgsBeSentAtActiveModeFunction)
+{
+    // Test 1 - Has no ActiveSubscription & no persisted subscription
+    mSubInfoProvider.SetHasActiveSubscription(false);
+    mSubInfoProvider.SetHasPersistedSubscription(false);
+    EXPECT_TRUE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
 
-        // Test 1 - Has no ActiveSubscription & no persisted subscription
-        ctx->mSubInfoProvider.SetHasActiveSubscription(false);
-        ctx->mSubInfoProvider.SetHasPersistedSubscription(false);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
+    // Test 2 - Has no active subscription & a persisted subscription
+    mSubInfoProvider.SetHasActiveSubscription(false);
+    mSubInfoProvider.SetHasPersistedSubscription(true);
+    EXPECT_FALSE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
 
-        // Test 2 - Has no active subscription & a persisted subscription
-        ctx->mSubInfoProvider.SetHasActiveSubscription(false);
-        ctx->mSubInfoProvider.SetHasPersistedSubscription(true);
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11)));
-
-        // Test 3 - Has an active subscription & a persisted subscription
-        ctx->mSubInfoProvider.SetHasActiveSubscription(true);
-        ctx->mSubInfoProvider.SetHasPersistedSubscription(true);
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11)));
-    }
+    // Test 3 - Has an active subscription & a persisted subscription
+    mSubInfoProvider.SetHasActiveSubscription(true);
+    mSubInfoProvider.SetHasPersistedSubscription(true);
+    EXPECT_FALSE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
+}
 #else
-    static void TestShouldCheckInMsgsBeSentAtActiveModeFunction(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
+TEST_F(TestICDManager, TestShouldCheckInMsgsBeSentAtActiveModeFunction)
+{
+    // Test 1 - Has no active subscription and no persisted subscription at boot up
+    mSubInfoProvider.SetHasActiveSubscription(false);
+    mSubInfoProvider.SetHasPersistedSubscription(false);
+    EXPECT_TRUE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
 
-        // Test 1 - Has no active subscription and no persisted subscription at boot up
-        ctx->mSubInfoProvider.SetHasActiveSubscription(false);
-        ctx->mSubInfoProvider.SetHasPersistedSubscription(false);
-        ctx->mICDManager.mIsBootUpResumeSubscriptionExecuted = false;
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
+    // Test 2 - Has no active subscription and a persisted subscription at boot up
+    mSubInfoProvider.SetHasActiveSubscription(false);
+    mSubInfoProvider.SetHasPersistedSubscription(true);
+    EXPECT_FALSE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
 
-        // Test 2 - Has no active subscription and a persisted subscription at boot up
-        ctx->mSubInfoProvider.SetHasActiveSubscription(false);
-        ctx->mSubInfoProvider.SetHasPersistedSubscription(true);
-        ctx->mICDManager.mIsBootUpResumeSubscriptionExecuted = false;
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11)));
+    mICDManager.SetBootUpResumeSubscriptionExecuted();
 
-        // Test 3 - Has an active subscription and a persisted subscription during normal operations
-        ctx->mSubInfoProvider.SetHasActiveSubscription(true);
-        ctx->mSubInfoProvider.SetHasPersistedSubscription(true);
-        ctx->mICDManager.mIsBootUpResumeSubscriptionExecuted = true;
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11)));
+    // Test 3 - Has an active subscription and a persisted subscription during normal operations
+    mSubInfoProvider.SetHasActiveSubscription(true);
+    mSubInfoProvider.SetHasPersistedSubscription(true);
+    EXPECT_FALSE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
 
-        // Test 4 - Has no active subscription and a persisted subscription during normal operations
-        ctx->mSubInfoProvider.SetHasActiveSubscription(false);
-        ctx->mSubInfoProvider.SetHasPersistedSubscription(true);
-        ctx->mICDManager.mIsBootUpResumeSubscriptionExecuted = true;
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
-    }
+    // Test 4 - Has no active subscription and a persisted subscription during normal operations
+    mSubInfoProvider.SetHasActiveSubscription(false);
+    mSubInfoProvider.SetHasPersistedSubscription(true);
+    EXPECT_TRUE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
+}
 #endif // CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
 #else
-    static void TestShouldCheckInMsgsBeSentAtActiveModeFunction(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
+TEST_F(TestICDManager, TestShouldCheckInMsgsBeSentAtActiveModeFunction)
+{
+    // Test 1 - Has an active subscription
+    mSubInfoProvider.SetHasActiveSubscription(true);
+    EXPECT_FALSE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
 
-        // Test 1 - Has an active subscription
-        ctx->mSubInfoProvider.SetHasActiveSubscription(true);
-        NL_TEST_ASSERT(aSuite,
-                       ctx->mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11) == false);
+    // Test 2 - Has no active subscription
+    mSubInfoProvider.SetHasActiveSubscription(false);
+    EXPECT_TRUE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
 
-        // Test 2 - Has no active subscription
-        ctx->mSubInfoProvider.SetHasActiveSubscription(false);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
-
-        // Test 3 - Make sure that the persisted subscription has no impact
-        ctx->mSubInfoProvider.SetHasPersistedSubscription(true);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
-    }
+    // Test 3 - Make sure that the persisted subscription has no impact
+    mSubInfoProvider.SetHasPersistedSubscription(true);
+    EXPECT_TRUE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
+}
 #endif // CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
 #endif // CHIP_CONFIG_ENABLE_ICD_CIP
 
-    static void TestHandleTestEventTriggerActiveModeReq(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
+TEST_F(TestICDManager, TestHandleTestEventTriggerActiveModeReq)
+{
+    // Verify That ICDManager starts in Idle
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
 
-        // Verify That ICDManager starts in Idle
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
+    // Add ActiveMode req for the Test event trigger event
+    mICDManager.HandleEventTrigger(static_cast<uint64_t>(ICDTestEventTriggerEvent::kAddActiveModeReq));
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
 
-        // Add ActiveMode req for the Test event trigger event
-        ctx->mICDManager.HandleEventTrigger(static_cast<uint64_t>(ICDTestEventTriggerEvent::kAddActiveModeReq));
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
+    // Advance clock by the ActiveModeDuration and check that the device is still in ActiveMode
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
 
-        // Advance clock by the ActiveModeDuration and check that the device is still in ActiveMode
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::ActiveMode);
+    // Remove req and device should go to IdleMode
+    mICDManager.HandleEventTrigger(static_cast<uint64_t>(ICDTestEventTriggerEvent::kRemoveActiveModeReq));
+    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
+}
 
-        // Remove req and device should go to IdleMode
-        ctx->mICDManager.HandleEventTrigger(static_cast<uint64_t>(ICDTestEventTriggerEvent::kRemoveActiveModeReq));
-        NL_TEST_ASSERT(aSuite, ctx->mICDManager.mOperationalState == ICDManager::OperationalState::IdleMode);
-    }
+#if CHIP_CONFIG_ENABLE_ICD_CIP
+TEST_F(TestICDManager, TestHandleTestEventTriggerInvalidateHalfCounterValues)
+{
+    constexpr uint32_t startValue    = 1;
+    constexpr uint32_t expectedValue = 2147483648;
 
-    static void TestHandleTestEventTriggerInvalidateHalfCounterValues(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
+    // Set starting value
+    uint32_t currentValue = ICDConfigurationData::GetInstance().GetICDCounter().GetValue();
+    uint32_t delta        = startValue - currentValue;
 
-        constexpr uint32_t startValue    = 1;
-        constexpr uint32_t expectedValue = 2147483648;
+    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDCounter().AdvanceBy(delta), CHIP_NO_ERROR);
+    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDCounter().GetValue(), startValue);
 
-        // Set starting value
-        uint32_t currentValue = ICDConfigurationData::GetInstance().GetICDCounter().GetValue();
-        uint32_t delta        = startValue - currentValue;
+    // Trigger ICD kInvalidateHalfCounterValues event
+    mICDManager.HandleEventTrigger(static_cast<uint64_t>(ICDTestEventTriggerEvent::kInvalidateHalfCounterValues));
 
-        NL_TEST_ASSERT(aSuite, ICDConfigurationData::GetInstance().GetICDCounter().AdvanceBy(delta) == CHIP_NO_ERROR);
-        NL_TEST_ASSERT(aSuite, ICDConfigurationData::GetInstance().GetICDCounter().GetValue() == startValue);
+    // Validate counter has the expected value
+    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDCounter().GetValue(), expectedValue);
+}
 
-        // Trigger ICD kInvalidateHalfCounterValues event
-        ctx->mICDManager.HandleEventTrigger(static_cast<uint64_t>(ICDTestEventTriggerEvent::kInvalidateHalfCounterValues));
+TEST_F(TestICDManager, TestHandleTestEventTriggerInvalidateAllCounterValues)
+{
+    constexpr uint32_t startValue    = 105;
+    constexpr uint32_t expectedValue = 104;
 
-        // Validate counter has the expected value
-        NL_TEST_ASSERT(aSuite, ICDConfigurationData::GetInstance().GetICDCounter().GetValue() == expectedValue);
-    }
+    // Set starting value
+    uint32_t currentValue = ICDConfigurationData::GetInstance().GetICDCounter().GetValue();
+    uint32_t delta        = startValue - currentValue;
 
-    static void TestHandleTestEventTriggerInvalidateAllCounterValues(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
+    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDCounter().AdvanceBy(delta), CHIP_NO_ERROR);
+    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDCounter().GetValue(), startValue);
 
-        constexpr uint32_t startValue    = 105;
-        constexpr uint32_t expectedValue = 104;
+    // Trigger ICD kInvalidateAllCounterValues event
+    mICDManager.HandleEventTrigger(static_cast<uint64_t>(ICDTestEventTriggerEvent::kInvalidateAllCounterValues));
 
-        // Set starting value
-        uint32_t currentValue = ICDConfigurationData::GetInstance().GetICDCounter().GetValue();
-        uint32_t delta        = startValue - currentValue;
+    // Validate counter has the expected value
+    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDCounter().GetValue(), expectedValue);
+}
+#endif // CHIP_CONFIG_ENABLE_ICD_CIP
 
-        NL_TEST_ASSERT(aSuite, ICDConfigurationData::GetInstance().GetICDCounter().AdvanceBy(delta) == CHIP_NO_ERROR);
-        NL_TEST_ASSERT(aSuite, ICDConfigurationData::GetInstance().GetICDCounter().GetValue() == startValue);
+/**
+ * @brief Test verifies when OnEnterIdleMode is called during normal operations.
+ *        Without the ActiveMode timer being extended
+ */
+TEST_F(TestICDManager, TestICDStateObserverOnEnterIdleModeActiveModeDuration)
+{
+    // Verify that ICDManager starts in IdleMode and calls OnEnterIdleMode
+    EXPECT_TRUE(mICDStateObserver.mOnEnterIdleModeCalled);
+    mICDStateObserver.ResetOnEnterIdleMode();
 
-        // Trigger ICD kInvalidateAllCounterValues event
-        ctx->mICDManager.HandleEventTrigger(static_cast<uint64_t>(ICDTestEventTriggerEvent::kInvalidateAllCounterValues));
+    // Advance clock just before IdleMode timer expires
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
+    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);
 
-        // Validate counter has the expected value
-        NL_TEST_ASSERT(aSuite, ICDConfigurationData::GetInstance().GetICDCounter().GetValue() == expectedValue);
-    }
+    // Expire IdleModeInterval
+    AdvanceClockAndRunEventLoop(1_s);
+    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);
 
-    /**
-     * @brief Test verifies when OnEnterIdleMode is called during normal operations.
-     *        Without the ActiveMode timer being extended
-     */
-    static void TestICDStateObserverOnEnterIdleModeActiveModeDuration(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
+    // Advance clock Just before ActiveMode timer expires
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() - 1_ms32);
+    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);
 
-        // Verify that ICDManager starts in IdleMode and calls OnEnterIdleMode
-        NL_TEST_ASSERT(aSuite, ctx->mICDStateObserver.mOnEnterIdleModeCalled);
-        ctx->mICDStateObserver.ResetOnEnterIdleMode();
+    // Expire ActiveMode timer
+    AdvanceClockAndRunEventLoop(1_ms32);
+    EXPECT_TRUE(mICDStateObserver.mOnEnterIdleModeCalled);
+}
 
-        // Advance clock just before IdleMode timer expires
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
-        NL_TEST_ASSERT(aSuite, !ctx->mICDStateObserver.mOnEnterIdleModeCalled);
+/**
+ * @brief Test verifies when OnEnterIdleMode is called with the ActiveMode timer gets extended
+ */
+TEST_F(TestICDManager, TestICDStateObserverOnEnterIdleModeActiveModeThreshold)
+{
+    // Verify that ICDManager starts in IdleMode and calls OnEnterIdleMode
+    EXPECT_TRUE(mICDStateObserver.mOnEnterIdleModeCalled);
+    mICDStateObserver.ResetOnEnterIdleMode();
 
-        // Expire IdleModeInterval
-        AdvanceClockAndRunEventLoop(ctx, 1_s);
-        NL_TEST_ASSERT(aSuite, !ctx->mICDStateObserver.mOnEnterIdleModeCalled);
+    // Advance clock just before the IdleMode timer expires
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
+    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);
 
-        // Advance clock Just before ActiveMode timer expires
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeDuration() - 1_ms32);
-        NL_TEST_ASSERT(aSuite, !ctx->mICDStateObserver.mOnEnterIdleModeCalled);
+    // Expire IdleMode timer
+    AdvanceClockAndRunEventLoop(1_s);
+    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);
 
-        // Expire ActiveMode timer
-        AdvanceClockAndRunEventLoop(ctx, 1_ms32);
-        NL_TEST_ASSERT(aSuite, ctx->mICDStateObserver.mOnEnterIdleModeCalled);
-    }
+    // Advance clock Just before ActiveMode timer expires
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() - 1_ms32);
+    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);
 
-    /**
-     * @brief Test verifies when OnEnterIdleMode is called with the ActiveMode timer gets extended
-     */
-    static void TestICDStateObserverOnEnterIdleModeActiveModeThreshold(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
+    // Increase ActiveMode timer by one ActiveModeThreshold
+    ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
+    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);
 
-        // Verify that ICDManager starts in IdleMode and calls OnEnterIdleMode
-        NL_TEST_ASSERT(aSuite, ctx->mICDStateObserver.mOnEnterIdleModeCalled);
-        ctx->mICDStateObserver.ResetOnEnterIdleMode();
+    // Advance clock Just before ActiveMode timer expires
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeThreshold() - 1_ms32);
+    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);
 
-        // Advance clock just before the IdleMode timer expires
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
-        NL_TEST_ASSERT(aSuite, !ctx->mICDStateObserver.mOnEnterIdleModeCalled);
+    // Expire ActiveMode timer
+    AdvanceClockAndRunEventLoop(1_ms32);
+    EXPECT_TRUE(mICDStateObserver.mOnEnterIdleModeCalled);
+}
 
-        // Expire IdleMode timer
-        AdvanceClockAndRunEventLoop(ctx, 1_s);
-        NL_TEST_ASSERT(aSuite, !ctx->mICDStateObserver.mOnEnterIdleModeCalled);
+TEST_F(TestICDManager, TestICDStateObserverOnEnterActiveMode)
+{
+    // Verify OnEnterActiveMode wasn't called at Init
+    EXPECT_FALSE(mICDStateObserver.mOnEnterActiveModeCalled);
 
-        // Advance clock Just before ActiveMode timer expires
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeDuration() - 1_ms32);
-        NL_TEST_ASSERT(aSuite, !ctx->mICDStateObserver.mOnEnterIdleModeCalled);
+    // Advance clock just before IdleMode timer expires
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
+    EXPECT_FALSE(mICDStateObserver.mOnEnterActiveModeCalled);
 
-        // Increase ActiveMode timer by one ActiveModeThreshold
-        ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
-        NL_TEST_ASSERT(aSuite, !ctx->mICDStateObserver.mOnEnterIdleModeCalled);
+    // Expire IdleMode timer and check wether OnEnterActiveMode was called
+    AdvanceClockAndRunEventLoop(1_s);
+    EXPECT_TRUE(mICDStateObserver.mOnEnterActiveModeCalled);
+    mICDStateObserver.ResetOnEnterActiveMode();
 
-        // Advance clock Just before ActiveMode timer expires
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeThreshold() - 1_ms32);
-        NL_TEST_ASSERT(aSuite, !ctx->mICDStateObserver.mOnEnterIdleModeCalled);
+    // Advance clock just before the ActiveMode timer expires
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() - 1_ms32);
 
-        // Expire ActiveMode timer
-        AdvanceClockAndRunEventLoop(ctx, 1_ms32);
-        NL_TEST_ASSERT(aSuite, ctx->mICDStateObserver.mOnEnterIdleModeCalled);
-    }
+    // Verify OnEnterActiveMde wasn't called
+    EXPECT_FALSE(mICDStateObserver.mOnEnterActiveModeCalled);
 
-    static void TestICDStateObserverOnEnterActiveMode(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
+    // Increase ActiveMode timer by one ActiveModeThreshold
+    ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
 
-        // Verify OnEnterActiveMode wasn't called at Init
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnEnterActiveModeCalled));
+    // Verify OnEnterActiveMde wasn't called
+    EXPECT_FALSE(mICDStateObserver.mOnEnterActiveModeCalled);
 
-        // Advance clock just before IdleMode timer expires
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnEnterActiveModeCalled));
+    // Advance clock just before ActiveMode timer expires
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeThreshold() - 1_ms32);
 
-        // Expire IdleMode timer and check wether OnEnterActiveMode was called
-        AdvanceClockAndRunEventLoop(ctx, 1_s);
-        NL_TEST_ASSERT(aSuite, ctx->mICDStateObserver.mOnEnterActiveModeCalled);
-        ctx->mICDStateObserver.ResetOnEnterActiveMode();
+    // Verify OnEnterActiveMde wasn't called
+    EXPECT_FALSE(mICDStateObserver.mOnEnterActiveModeCalled);
 
-        // Advance clock just before the ActiveMode timer expires
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeDuration() - 1_ms32);
+    // Expire ActiveMode timer
+    AdvanceClockAndRunEventLoop(1_ms32);
 
-        // Verify OnEnterActiveMde wasn't called
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnEnterActiveModeCalled));
+    // Verify OnEnterActiveMde wasn't called
+    EXPECT_FALSE(mICDStateObserver.mOnEnterActiveModeCalled);
 
-        // Increase ActiveMode timer by one ActiveModeThreshold
-        ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
+    // Advance clock just before IdleMode timer expires
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
+    EXPECT_FALSE(mICDStateObserver.mOnEnterActiveModeCalled);
 
-        // Verify OnEnterActiveMde wasn't called
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnEnterActiveModeCalled));
+    // Expire IdleMode timer and check OnEnterActiveMode was called
+    AdvanceClockAndRunEventLoop(1_s);
+    EXPECT_TRUE(mICDStateObserver.mOnEnterActiveModeCalled);
+}
 
-        // Advance clock just before ActiveMode timer expires
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeThreshold() - 1_ms32);
+#if CHIP_CONFIG_ENABLE_ICD_CIP
+TEST_F(TestICDManager, TestICDStateObserverOnICDModeChange)
+{
+    typedef ICDListener::ICDManagementEvents ICDMEvent;
 
-        // Verify OnEnterActiveMde wasn't called
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnEnterActiveModeCalled));
+    // Set FeatureMap - Configures CIP, UAT and LITS to 1
+    mICDManager.SetTestFeatureMapValue(0x07);
 
-        // Expire ActiveMode timer
-        AdvanceClockAndRunEventLoop(ctx, 1_ms32);
+    // Since we don't have a registration, we stay in SIT mode. No changes
+    EXPECT_FALSE(mICDStateObserver.mOnICDModeChangeCalled);
 
-        // Verify OnEnterActiveMde wasn't called
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnEnterActiveModeCalled));
+    // Trigger register event to force ICDManager to re-evaluate OperatingMode
+    ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
 
-        // Advance clock just before IdleMode timer expires
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnEnterActiveModeCalled));
+    // Since we don't have a registration, we stay in SIT mode. No changes
+    EXPECT_FALSE(mICDStateObserver.mOnICDModeChangeCalled);
 
-        // Expire IdleMode timer and check OnEnterActiveMode was called
-        AdvanceClockAndRunEventLoop(ctx, 1_s);
-        NL_TEST_ASSERT(aSuite, ctx->mICDStateObserver.mOnEnterActiveModeCalled);
-    }
+    // Add an entry to the ICDMonitoringTable
+    ICDMonitoringTable table(testStorage, kTestFabricIndex1, kMaxTestClients, &(mKeystore));
 
-    static void TestICDStateObserverOnICDModeChange(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
-        typedef ICDListener::ICDManagementEvents ICDMEvent;
+    ICDMonitoringEntry entry(&(mKeystore));
+    entry.checkInNodeID    = kClientNodeId11;
+    entry.monitoredSubject = kClientNodeId11;
+    EXPECT_EQ(CHIP_NO_ERROR, entry.SetKey(ByteSpan(kKeyBuffer1a)));
+    EXPECT_EQ(CHIP_NO_ERROR, table.Set(0, entry));
 
-        // Since we don't have a registration, we stay in SIT mode. No changes
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnICDModeChangeCalled));
+    // Trigger register event after first entry was added
+    ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
 
-        // Trigger register event to force ICDManager to re-evaluate OperatingMode
-        ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+    // We have a registration. Transition to LIT mode
+    EXPECT_TRUE(mICDStateObserver.mOnICDModeChangeCalled);
+    mICDStateObserver.ResetOnICDModeChange();
 
-        // Since we don't have a registration, we stay in SIT mode. No changes
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnICDModeChangeCalled));
+    // Trigger register event to force ICDManager to re-evaluate OperatingMode
+    ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
 
-        // Add an entry to the ICDMonitoringTable
-        ICDMonitoringTable table(ctx->testStorage, kTestFabricIndex1, kMaxTestClients, &(ctx->mKeystore));
-
-        ICDMonitoringEntry entry(&(ctx->mKeystore));
-        entry.checkInNodeID    = kClientNodeId11;
-        entry.monitoredSubject = kClientNodeId11;
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer1a)));
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == table.Set(0, entry));
-
-        // Trigger register event after first entry was added
-        ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
-
-        // We have a registration. Transition to LIT mode
-        NL_TEST_ASSERT(aSuite, ctx->mICDStateObserver.mOnICDModeChangeCalled);
-        ctx->mICDStateObserver.ResetOnICDModeChange();
-
-        // Trigger register event to force ICDManager to re-evaluate OperatingMode
-        ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
-
-        // We have a registration. We stay in LIT mode. No changes.
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnICDModeChangeCalled));
-
-        // Remove entry from the ICDMonitoringTable
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == table.Remove(0));
-        ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
+    // We have a registration. We stay in LIT mode. No changes.
+    EXPECT_FALSE(mICDStateObserver.mOnICDModeChangeCalled);
 
-        // Since we don't have a registration anymore. Transition to SIT mode.
-        NL_TEST_ASSERT(aSuite, ctx->mICDStateObserver.mOnICDModeChangeCalled);
-        ctx->mICDStateObserver.ResetOnICDModeChange();
-    }
+    // Remove entry from the ICDMonitoringTable
+    EXPECT_EQ(CHIP_NO_ERROR, table.Remove(0));
+    ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);
 
-    static void TestICDStateObserverOnICDModeChangeOnInit(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
+    // Since we don't have a registration anymore. Transition to SIT mode.
+    EXPECT_TRUE(mICDStateObserver.mOnICDModeChangeCalled);
+    mICDStateObserver.ResetOnICDModeChange();
+}
 
-        ICDMonitoringTable table(ctx->testStorage, kTestFabricIndex1, kMaxTestClients, &(ctx->mKeystore));
+TEST_F(TestICDManager, TestICDStateObserverOnICDModeChangeOnInit)
+{
+    // Set FeatureMap - Configures CIP, UAT and LITS to 1
+    mICDManager.SetTestFeatureMapValue(0x07);
 
-        // Since we don't have a registration, we stay in SIT mode. No changes
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnICDModeChangeCalled));
+    ICDMonitoringTable table(testStorage, kTestFabricIndex1, kMaxTestClients, &(mKeystore));
 
-        // Add an entry to the ICDMonitoringTable
-        ICDMonitoringEntry entry(&(ctx->mKeystore));
-        entry.checkInNodeID    = kClientNodeId11;
-        entry.monitoredSubject = kClientNodeId11;
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer1a)));
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == table.Set(0, entry));
+    // Since we don't have a registration, we stay in SIT mode. No changes
+    EXPECT_FALSE(mICDStateObserver.mOnICDModeChangeCalled);
 
-        // Shut down and reinit ICDManager - We should go to LIT mode since we have a registration
-        ctx->mICDManager.Shutdown();
-        ctx->mICDManager.RegisterObserver(&(ctx->mICDStateObserver));
-        ctx->mICDManager.Init(&(ctx->testStorage), &(ctx->GetFabricTable()), &(ctx->mKeystore), &(ctx->GetExchangeManager()),
-                              &(ctx->mSubInfoProvider));
+    // Add an entry to the ICDMonitoringTable
+    ICDMonitoringEntry entry(&(mKeystore));
+    entry.checkInNodeID    = kClientNodeId11;
+    entry.monitoredSubject = kClientNodeId11;
+    EXPECT_EQ(CHIP_NO_ERROR, entry.SetKey(ByteSpan(kKeyBuffer1a)));
+    EXPECT_EQ(CHIP_NO_ERROR, table.Set(0, entry));
 
-        // We have a registration, transition to LIT mode
-        NL_TEST_ASSERT(aSuite, ctx->mICDStateObserver.mOnICDModeChangeCalled);
-        ctx->mICDStateObserver.ResetOnICDModeChange();
+    // Shut down and reinit ICDManager - We should go to LIT mode since we have a registration
+    mICDManager.Shutdown();
+    mICDManager.RegisterObserver(&(mICDStateObserver));
+    mICDManager.Init(&testStorage, &(pMessagingContext->GetFabricTable()), &mKeystore, &(pMessagingContext->GetExchangeManager()),
+                     &mSubInfoProvider);
 
-        // Remove entry from the ICDMonitoringTable
-        NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == table.Remove(0));
-    }
+    // We have a registration, transition to LIT mode
+    EXPECT_TRUE(mICDStateObserver.mOnICDModeChangeCalled);
+    mICDStateObserver.ResetOnICDModeChange();
 
-    /**
-     * @brief Test verifies the OnTransitionToIdleMode event when the ActiveModeDuration is greater than the
-     *        ICD_ACTIVE_TIME_JITTER_MS
-     */
-    static void TestICDStateObserverOnTransitionToIdleModeGreaterActiveModeDuration(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
+    // Remove entry from the ICDMonitoringTable
+    EXPECT_EQ(CHIP_NO_ERROR, table.Remove(0));
+}
+#endif
 
-        // Set New durations for test case - ActiveModeDuration must be longuer than ICD_ACTIVE_TIME_JITTER_MS
-        Milliseconds32 oldActiveModeDuration = ICDConfigurationData::GetInstance().GetActiveModeDuration();
-        ICDConfigurationData::GetInstance().SetModeDurations(
-            MakeOptional<Milliseconds32>(Milliseconds32(200) + Milliseconds32(ICD_ACTIVE_TIME_JITTER_MS)), NullOptional);
+/**
+ * @brief Test verifies the OnTransitionToIdleMode event when the ActiveModeDuration is greater than the
+ *        ICD_ACTIVE_TIME_JITTER_MS
+ */
+TEST_F(TestICDManager, TestICDStateObserverOnTransitionToIdleModeGreaterActiveModeDuration)
+{
+    ICDConfigurationDataTestAccess privateIcdConfigData(&ICDConfigurationData::GetInstance());
 
-        // Advance clock just before IdleMode timer expires
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnTransitionToIdleCalled));
+    // Set New durations for test case - ActiveModeDuration must be longuer than ICD_ACTIVE_TIME_JITTER_MS
+    Milliseconds32 oldActiveModeDuration = ICDConfigurationData::GetInstance().GetActiveModeDuration();
+    privateIcdConfigData.SetModeDurations(
+        MakeOptional<Milliseconds32>(Milliseconds32(200) + Milliseconds32(ICD_ACTIVE_TIME_JITTER_MS)), NullOptional);
 
-        // Expire IdleMode timer
-        AdvanceClockAndRunEventLoop(ctx, 1_s);
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnTransitionToIdleCalled));
+    // Advance clock just before IdleMode timer expires
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
+    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);
 
-        // Advance time just before OnTransitionToIdleMode is called
-        AdvanceClockAndRunEventLoop(
-            ctx, ICDConfigurationData::GetInstance().GetActiveModeDuration() - Milliseconds32(ICD_ACTIVE_TIME_JITTER_MS) - 1_ms32);
+    // Expire IdleMode timer
+    AdvanceClockAndRunEventLoop(1_s);
+    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);
 
-        // Check mOnTransitionToIdleCalled has not been called
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnTransitionToIdleCalled));
+    // Advance time just before OnTransitionToIdleMode is called
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() -
+                                Milliseconds32(ICD_ACTIVE_TIME_JITTER_MS) - 1_ms32);
 
-        // Increase ActiveMode timer by one ActiveModeThreshold
-        ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnTransitionToIdleCalled));
+    // Check mOnTransitionToIdleCalled has not been called
+    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);
 
-        // Advance time just before OnTransitionToIdleMode is called
-        AdvanceClockAndRunEventLoop(
-            ctx, ICDConfigurationData::GetInstance().GetActiveModeThreshold() - Milliseconds32(ICD_ACTIVE_TIME_JITTER_MS) - 1_ms32);
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnTransitionToIdleCalled));
+    // Increase ActiveMode timer by one ActiveModeThreshold
+    ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
+    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);
 
-        // Expire OnTransitionToIdleMode
-        AdvanceClockAndRunEventLoop(ctx, 1_ms32);
-        // Check mOnTransitionToIdleCalled has been called
-        NL_TEST_ASSERT(aSuite, ctx->mICDStateObserver.mOnTransitionToIdleCalled);
-        ctx->mICDStateObserver.ResetOnTransitionToIdle();
+    // Advance time just before OnTransitionToIdleMode is called
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeThreshold() -
+                                Milliseconds32(ICD_ACTIVE_TIME_JITTER_MS) - 1_ms32);
+    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);
 
-        // Expire ActiveMode timer
-        AdvanceClockAndRunEventLoop(ctx, Milliseconds32(ICD_ACTIVE_TIME_JITTER_MS));
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnTransitionToIdleCalled));
+    // Expire OnTransitionToIdleMode
+    AdvanceClockAndRunEventLoop(1_ms32);
+    // Check mOnTransitionToIdleCalled has been called
+    EXPECT_TRUE(mICDStateObserver.mOnTransitionToIdleCalled);
+    mICDStateObserver.ResetOnTransitionToIdle();
 
-        // Reset Old durations
-        ICDConfigurationData::GetInstance().SetModeDurations(MakeOptional(oldActiveModeDuration), NullOptional);
-    }
+    // Expire ActiveMode timer
+    AdvanceClockAndRunEventLoop(Milliseconds32(ICD_ACTIVE_TIME_JITTER_MS));
+    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);
 
-    /**
-     * @brief Test verifies the OnTransitionToIdleMode event when the ActiveModeDuration is equal to the
-     *        ICD_ACTIVE_TIME_JITTER_MS.
-     */
-    static void TestICDStateObserverOnTransitionToIdleModeEqualActiveModeDuration(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
+    // Reset Old durations
+    privateIcdConfigData.SetModeDurations(MakeOptional(oldActiveModeDuration), NullOptional);
+}
 
-        // Set New durations for test case - ActiveModeDuration must be equal to ICD_ACTIVE_TIME_JITTER_MS
-        Milliseconds32 oldActiveModeDuration = ICDConfigurationData::GetInstance().GetActiveModeDuration();
-        ICDConfigurationData::GetInstance().SetModeDurations(
-            MakeOptional<Milliseconds32>(Milliseconds32(ICD_ACTIVE_TIME_JITTER_MS)), NullOptional);
+/**
+ * @brief Test verifies the OnTransitionToIdleMode event when the ActiveModeDuration is equal to the
+ *        ICD_ACTIVE_TIME_JITTER_MS.
+ */
+TEST_F(TestICDManager, TestICDStateObserverOnTransitionToIdleModeEqualActiveModeDuration)
+{
+    ICDConfigurationDataTestAccess privateIcdConfigData(&ICDConfigurationData::GetInstance());
 
-        // Advance clock just before IdleMode timer expires
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnTransitionToIdleCalled));
+    // Set New durations for test case - ActiveModeDuration must be equal to ICD_ACTIVE_TIME_JITTER_MS
+    Milliseconds32 oldActiveModeDuration = ICDConfigurationData::GetInstance().GetActiveModeDuration();
+    privateIcdConfigData.SetModeDurations(MakeOptional<Milliseconds32>(Milliseconds32(ICD_ACTIVE_TIME_JITTER_MS)), NullOptional);
 
-        // Expire IdleMode timer
-        AdvanceClockAndRunEventLoop(ctx, 1_s);
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnTransitionToIdleCalled));
+    // Advance clock just before IdleMode timer expires
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
+    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);
 
-        // Expire OnTransitionToIdleMode
-        AdvanceClockAndRunEventLoop(ctx, 1_ms32);
-        NL_TEST_ASSERT(aSuite, ctx->mICDStateObserver.mOnTransitionToIdleCalled);
+    // Expire IdleMode timer
+    AdvanceClockAndRunEventLoop(1_s);
+    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);
 
-        // Reset Old durations
-        ICDConfigurationData::GetInstance().SetModeDurations(MakeOptional(oldActiveModeDuration), NullOptional);
-    }
+    // Expire OnTransitionToIdleMode
+    AdvanceClockAndRunEventLoop(1_ms32);
+    EXPECT_TRUE(mICDStateObserver.mOnTransitionToIdleCalled);
 
-    /**
-     * @brief Test verifies the OnTransitionToIdleMode event when the ActiveModeDuration is 0 and without an ActiveMode req
-     */
-    static void TestICDStateObserverOnTransitionToIdleMode0ActiveModeDurationWithoutReq(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
+    // Reset Old durations
+    privateIcdConfigData.SetModeDurations(MakeOptional(oldActiveModeDuration), NullOptional);
+}
 
-        // Set New durations for test case - ActiveModeDuration equal 0
-        Milliseconds32 oldActiveModeDuration = ICDConfigurationData::GetInstance().GetActiveModeDuration();
-        ICDConfigurationData::GetInstance().SetModeDurations(MakeOptional<Milliseconds32>(0), NullOptional);
+/**
+ * @brief Test verifies the OnTransitionToIdleMode event when the ActiveModeDuration is 0 and without an ActiveMode req
+ */
+TEST_F(TestICDManager, TestICDStateObserverOnTransitionToIdleMode0ActiveModeDurationWithoutReq)
+{
+    ICDConfigurationDataTestAccess privateIcdConfigData(&ICDConfigurationData::GetInstance());
 
-        // Advance clock just before IdleMode timer expires
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnTransitionToIdleCalled));
+    // Set New durations for test case - ActiveModeDuration equal 0
+    Milliseconds32 oldActiveModeDuration = ICDConfigurationData::GetInstance().GetActiveModeDuration();
+    privateIcdConfigData.SetModeDurations(MakeOptional<Milliseconds32>(0), NullOptional);
 
-        // Expire IdleMode timer
-        AdvanceClockAndRunEventLoop(ctx, 1_s);
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnTransitionToIdleCalled));
+    // Advance clock just before IdleMode timer expires
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
+    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);
 
-        // Increase time by 1 - Should not trigger OnTransitionToIdle.
-        // Timer length is one ActiveModeThreshold
-        AdvanceClockAndRunEventLoop(ctx, 1_ms32);
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnTransitionToIdleCalled));
+    // Expire IdleMode timer
+    AdvanceClockAndRunEventLoop(1_s);
+    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);
 
-        // Expire ActiveModeThreshold
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetActiveModeThreshold());
-        NL_TEST_ASSERT(aSuite, ctx->mICDStateObserver.mOnTransitionToIdleCalled);
+    // Increase time by 1 - Should not trigger OnTransitionToIdle.
+    // Timer length is one ActiveModeThreshold
+    AdvanceClockAndRunEventLoop(1_ms32);
+    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);
 
-        // Reset Old durations
-        ICDConfigurationData::GetInstance().SetModeDurations(MakeOptional(oldActiveModeDuration), NullOptional);
-    }
+    // Expire ActiveModeThreshold
+    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeThreshold());
+    EXPECT_TRUE(mICDStateObserver.mOnTransitionToIdleCalled);
 
-    /**
-     * @brief Test verifies the OnTransitionToIdleMode event when the ActiveModeDuration is 0 with an ActiveMode req
-     */
-    static void TestICDStateObserverOnTransitionToIdleMode0ActiveModeDurationWittReq(nlTestSuite * aSuite, void * aContext)
-    {
-        TestContext * ctx = static_cast<TestContext *>(aContext);
+    // Reset Old durations
+    privateIcdConfigData.SetModeDurations(MakeOptional(oldActiveModeDuration), NullOptional);
+}
 
-        // Set New durations for test case - ActiveModeDuration equal 0
-        Milliseconds32 oldActiveModeDuration = ICDConfigurationData::GetInstance().GetActiveModeDuration();
-        ICDConfigurationData::GetInstance().SetModeDurations(MakeOptional<Milliseconds32>(0), NullOptional);
+/**
+ * @brief Test verifies the OnTransitionToIdleMode event when the ActiveModeDuration is 0 with an ActiveMode req
+ *        TODO(#33074): When the OnTransitionToIdle edge is fixed, we can enable this test
+ */
+// TEST_F(TestICDManager, TestICDStateObserverOnTransitionToIdleMode0ActiveModeDurationWithReq)
+// {
+//     // Set New durations for test case - ActiveModeDuration equal 0
+//     Milliseconds32 oldActiveModeDuration = ICDConfigurationData::GetInstance().GetActiveModeDuration();
+//     ICDConfigurationData::GetInstance().SetModeDurations(MakeOptional<Milliseconds32>(0), NullOptional);
 
-        // Add ActiveMode req for the Test event trigger event
-        ctx->mICDManager.HandleEventTrigger(static_cast<uint64_t>(ICDTestEventTriggerEvent::kAddActiveModeReq));
+//     // Add ActiveMode req for the Test event trigger event
+//     mICDManager.HandleEventTrigger(static_cast<uint64_t>(ICDTestEventTriggerEvent::kAddActiveModeReq));
 
-        // Expire IdleMode timer
-        AdvanceClockAndRunEventLoop(ctx, ICDConfigurationData::GetInstance().GetIdleModeDuration());
-        NL_TEST_ASSERT(aSuite, !(ctx->mICDStateObserver.mOnTransitionToIdleCalled));
+//     // Expire IdleMode timer
+//     AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration());
+//     EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);
 
-        // Reset Old durations
-        ICDConfigurationData::GetInstance().SetModeDurations(MakeOptional(oldActiveModeDuration), NullOptional);
-    }
-};
+//     // Reset Old durations
+//     ICDConfigurationData::GetInstance().SetModeDurations(MakeOptional(oldActiveModeDuration), NullOptional);
+// }
 
 } // namespace app
 } // namespace chip
-
-namespace {
-static const nlTest sTests[] = {
-    NL_TEST_DEF("TestICDModeDurations", TestICDManager::TestICDModeDurations),
-    NL_TEST_DEF("TestOnSubscriptionReport", TestICDManager::TestOnSubscriptionReport),
-    NL_TEST_DEF("TestKeepActivemodeRequests", TestICDManager::TestKeepActivemodeRequests),
-    NL_TEST_DEF("TestICDStayActive", TestICDManager::TestICDMStayActive),
-#if CHIP_CONFIG_ENABLE_ICD_CIP
-    NL_TEST_DEF("TestICDCounter", TestICDManager::TestICDCounter),
-    NL_TEST_DEF("TestICDMRegisterUnregisterEvents", TestICDManager::TestICDMRegisterUnregisterEvents),
-    NL_TEST_DEF("TestICDModeDurationsWith0ActiveModeDurationWithActiveSub",
-                TestICDManager::TestICDModeDurationsWith0ActiveModeDurationWithActiveSub),
-    NL_TEST_DEF("TestICDModeDurationsWith0ActiveModeDurationWithoutActiveSub",
-                TestICDManager::TestICDModeDurationsWith0ActiveModeDurationWithoutActiveSub),
-    NL_TEST_DEF("TestShouldCheckInMsgsBeSentAtActiveModeFunction", TestICDManager::TestShouldCheckInMsgsBeSentAtActiveModeFunction),
-    NL_TEST_DEF("TestHandleTestEventTriggerInvalidateHalfCounterValues",
-                TestICDManager::TestHandleTestEventTriggerInvalidateHalfCounterValues),
-    NL_TEST_DEF("TestHandleTestEventTriggerInvalidateAllCounterValues",
-                TestICDManager::TestHandleTestEventTriggerInvalidateAllCounterValues),
-    NL_TEST_DEF("TestICDStateObserverOnICDModeChange", TestICDManager::TestICDStateObserverOnICDModeChange),
-    NL_TEST_DEF("TestICDStateObserverOnICDModeChangeOnInit", TestICDManager::TestICDStateObserverOnICDModeChangeOnInit),
-#endif // CHIP_CONFIG_ENABLE_ICD_CIP
-    NL_TEST_DEF("TestHandleTestEventTriggerActiveModeReq", TestICDManager::TestHandleTestEventTriggerActiveModeReq),
-    NL_TEST_DEF("TestICDStateObserverOnEnterIdleModeActiveModeDuration",
-                TestICDManager::TestICDStateObserverOnEnterIdleModeActiveModeDuration),
-    NL_TEST_DEF("TestICDStateObserverOnEnterIdleModeActiveModeThreshold",
-                TestICDManager::TestICDStateObserverOnEnterIdleModeActiveModeThreshold),
-    NL_TEST_DEF("TestICDStateObserverOnEnterActiveMode", TestICDManager::TestICDStateObserverOnEnterActiveMode),
-    NL_TEST_DEF("TestICDStateObserverOnTransitionToIdleModeGreaterActiveModeDuration",
-                TestICDManager::TestICDStateObserverOnTransitionToIdleModeGreaterActiveModeDuration),
-    NL_TEST_DEF("TestICDStateObserverOnTransitionToIdleModeEqualActiveModeDuration",
-                TestICDManager::TestICDStateObserverOnTransitionToIdleModeEqualActiveModeDuration),
-    NL_TEST_DEF("TestICDStateObserverOnTransitionToIdleMode0ActiveModeDurationWithoutReq",
-                TestICDManager::TestICDStateObserverOnTransitionToIdleMode0ActiveModeDurationWithoutReq),
-    // TODO(#33074): When the OnTransitionToIdle edge is fixed, we can enable this test
-    // NL_TEST_DEF("TestICDStateObserverOnTransitionToIdleMode0ActiveModeDurationWittReq",
-    //             TestICDManager::TestICDStateObserverOnTransitionToIdleMode0ActiveModeDurationWittReq),
-    NL_TEST_SENTINEL(),
-};
-
-nlTestSuite cmSuite = {
-    "TestICDManager",
-    &sTests[0],
-    TestContext::nlTestSetUpTestSuite,
-    TestContext::nlTestTearDownTestSuite,
-    TestContext::nlTestSetUp,
-    TestContext::nlTestTearDown,
-};
-} // namespace
-
-int TestSuiteICDManager()
-{
-    return ExecuteTestsWithContext<TestContext>(&cmSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestSuiteICDManager)
diff --git a/src/messaging/tests/BUILD.gn b/src/messaging/tests/BUILD.gn
index 699066f..c597c36 100644
--- a/src/messaging/tests/BUILD.gn
+++ b/src/messaging/tests/BUILD.gn
@@ -38,6 +38,12 @@
     "${chip_root}/src/transport",
     "${chip_root}/src/transport/tests:helpers",
   ]
+
+  # MessagingContext exposes nl-test compatible setup/teardown functions, specifically
+  # they return nltest specific SUCCESS/FAILURE constants hence this dependency.
+  #
+  # Once all tests are moved to pw_unittest/gtest, this dependency should be removed
+  public_deps = [ "${nlunit_test_root}:nlunit-test" ]
 }
 
 chip_test_suite_using_nltest("tests") {
diff --git a/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt b/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt
index 37f0bf2..9408e84 100644
--- a/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt
+++ b/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt
@@ -1,6 +1,5 @@
 AppTests
 DataModelTests
-ICDServerTestsNL
 InetLayerTests
 MessagingLayerTests
 SecureChannelTestsNL