/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *    All rights reserved.
 *
 *    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.
 */

#include <gtest/gtest.h>

#include "system/SystemClock.h"
#include "transport/SecureSession.h"
#include <app-common/zap-generated/cluster-objects.h>
#include <app/ClusterStateCache.h>
#include <app/ConcreteAttributePath.h>
#include <app/ConcreteEventPath.h>
#include <app/InteractionModelEngine.h>
#include <app/tests/AppTestContext.h>
#include <app/util/mock/Constants.h>
#include <app/util/mock/Functions.h>
#include <controller/ReadInteraction.h>
#include <lib/core/ErrorStr.h>
#include <lib/support/logging/CHIPLogging.h>
#include <messaging/tests/MessagingContext.h>
#include <protocols/interaction_model/Constants.h>

using TestContext = chip::Test::AppContext;

using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::Protocols;

namespace {

constexpr EndpointId kTestEndpointId        = 1;
constexpr DataVersion kDataVersion          = 5;
constexpr AttributeId kPerpetualAttributeid = chip::Test::MockAttributeId(1);
constexpr ClusterId kPerpetualClusterId     = chip::Test::MockClusterId(2);
bool expectedAttribute1                     = true;
int16_t expectedAttribute2                  = 42;
uint64_t expectedAttribute3                 = 0xdeadbeef0000cafe;
uint8_t expectedAttribute4[256]             = {
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
};

enum ResponseDirective
{
    kSendDataResponse,
    kSendManyDataResponses,          // Many data blocks, for a single concrete path
                                     // read, simulating a malicious server.
    kSendManyDataResponsesWrongPath, // Many data blocks, all using the wrong
                                     // path, for a single concrete path
                                     // read, simulating a malicious server.
    kSendDataError,
    kSendTwoDataErrors, // Multiple errors, for a single concrete path,
                        // simulating a malicious server.
};

ResponseDirective responseDirective;

// Number of reads of Clusters::UnitTesting::Attributes::Int16u that we have observed.
// Every read will increment this count by 1 and return the new value.
uint16_t totalReadCount = 0;

bool isLitIcd = false;

} // namespace

namespace chip {
namespace app {
CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescriptor, bool aIsFabricFiltered,
                                 const ConcreteReadAttributePath & aPath, AttributeReportIBs::Builder & aAttributeReports,
                                 AttributeEncodeState * apEncoderState)
{
    if (aPath.mEndpointId >= chip::Test::kMockEndpointMin)
    {
        return chip::Test::ReadSingleMockClusterData(aSubjectDescriptor.fabricIndex, aPath, aAttributeReports, apEncoderState);
    }

    if (responseDirective == kSendManyDataResponses || responseDirective == kSendManyDataResponsesWrongPath)
    {
        if (aPath.mClusterId != Clusters::UnitTesting::Id || aPath.mAttributeId != Clusters::UnitTesting::Attributes::Boolean::Id)
        {
            return CHIP_ERROR_INCORRECT_STATE;
        }

        for (size_t i = 0; i < 4; ++i)
        {
            ConcreteAttributePath path(aPath);
            // Use an incorrect attribute id for some of the responses.
            path.mAttributeId =
                static_cast<AttributeId>(path.mAttributeId + (i / 2) + (responseDirective == kSendManyDataResponsesWrongPath));
            AttributeEncodeState state(apEncoderState);
            AttributeValueEncoder valueEncoder(aAttributeReports, aSubjectDescriptor, path, kDataVersion, aIsFabricFiltered, state);
            ReturnErrorOnFailure(valueEncoder.Encode(true));
        }

        return CHIP_NO_ERROR;
    }

    if (responseDirective == kSendDataResponse)
    {
        if (aPath.mClusterId == app::Clusters::UnitTesting::Id &&
            aPath.mAttributeId == app::Clusters::UnitTesting::Attributes::ListFabricScoped::Id)
        {
            AttributeEncodeState state(apEncoderState);
            AttributeValueEncoder valueEncoder(aAttributeReports, aSubjectDescriptor, aPath, kDataVersion, aIsFabricFiltered,
                                               state);

            return valueEncoder.EncodeList([aSubjectDescriptor](const auto & encoder) -> CHIP_ERROR {
                app::Clusters::UnitTesting::Structs::TestFabricScoped::Type val;
                val.fabricIndex = aSubjectDescriptor.fabricIndex;
                ReturnErrorOnFailure(encoder.Encode(val));
                val.fabricIndex = (val.fabricIndex == 1) ? 2 : 1;
                ReturnErrorOnFailure(encoder.Encode(val));
                return CHIP_NO_ERROR;
            });
        }
        if (aPath.mClusterId == app::Clusters::UnitTesting::Id &&
            aPath.mAttributeId == app::Clusters::UnitTesting::Attributes::Int16u::Id)
        {
            AttributeEncodeState state(apEncoderState);
            AttributeValueEncoder valueEncoder(aAttributeReports, aSubjectDescriptor, aPath, kDataVersion, aIsFabricFiltered,
                                               state);

            return valueEncoder.Encode(++totalReadCount);
        }
        if (aPath.mClusterId == kPerpetualClusterId ||
            (aPath.mClusterId == app::Clusters::UnitTesting::Id && aPath.mAttributeId == kPerpetualAttributeid))
        {
            AttributeEncodeState state;
            AttributeValueEncoder valueEncoder(aAttributeReports, aSubjectDescriptor, aPath, kDataVersion, aIsFabricFiltered,
                                               state);

            CHIP_ERROR err = valueEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR {
                encoder.Encode(static_cast<uint8_t>(1));
                return CHIP_ERROR_NO_MEMORY;
            });

            if (err != CHIP_NO_ERROR)
            {
                // If the err is not CHIP_NO_ERROR, means the encoding was aborted, then the valueEncoder may save its state.
                // The state is used by list chunking feature for now.
                if (apEncoderState != nullptr)
                {
                    *apEncoderState = valueEncoder.GetState();
                }
                return err;
            }
        }
        if (aPath.mClusterId == app::Clusters::IcdManagement::Id &&
            aPath.mAttributeId == app::Clusters::IcdManagement::Attributes::OperatingMode::Id)
        {
            AttributeEncodeState state(apEncoderState);
            AttributeValueEncoder valueEncoder(aAttributeReports, aSubjectDescriptor, aPath, kDataVersion, aIsFabricFiltered,
                                               state);

            return valueEncoder.Encode(isLitIcd ? Clusters::IcdManagement::OperatingModeEnum::kLit
                                                : Clusters::IcdManagement::OperatingModeEnum::kSit);
        }

        AttributeReportIB::Builder & attributeReport = aAttributeReports.CreateAttributeReport();
        ReturnErrorOnFailure(aAttributeReports.GetError());
        AttributeDataIB::Builder & attributeData = attributeReport.CreateAttributeData();
        ReturnErrorOnFailure(attributeReport.GetError());
        Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo::Type value;
        Clusters::UnitTesting::Structs::TestListStructOctet::Type valueBuf[4];

        value = valueBuf;

        uint8_t i = 0;
        for (auto & item : valueBuf)
        {
            item.member1 = i;
            i++;
        }

        attributeData.DataVersion(kDataVersion);
        ReturnErrorOnFailure(attributeData.GetError());
        AttributePathIB::Builder & attributePath = attributeData.CreatePath();
        attributePath.Endpoint(aPath.mEndpointId).Cluster(aPath.mClusterId).Attribute(aPath.mAttributeId).EndOfAttributePathIB();
        ReturnErrorOnFailure(attributePath.GetError());

        ReturnErrorOnFailure(DataModel::Encode(*(attributeData.GetWriter()), TLV::ContextTag(AttributeDataIB::Tag::kData), value));
        ReturnErrorOnFailure(attributeData.EndOfAttributeDataIB());
        return attributeReport.EndOfAttributeReportIB();
    }

    for (size_t i = 0; i < (responseDirective == kSendTwoDataErrors ? 2 : 1); ++i)
    {
        AttributeReportIB::Builder & attributeReport = aAttributeReports.CreateAttributeReport();
        ReturnErrorOnFailure(aAttributeReports.GetError());
        AttributeStatusIB::Builder & attributeStatus = attributeReport.CreateAttributeStatus();
        AttributePathIB::Builder & attributePath     = attributeStatus.CreatePath();
        attributePath.Endpoint(aPath.mEndpointId).Cluster(aPath.mClusterId).Attribute(aPath.mAttributeId).EndOfAttributePathIB();
        ReturnErrorOnFailure(attributePath.GetError());

        StatusIB::Builder & errorStatus = attributeStatus.CreateErrorStatus();
        ReturnErrorOnFailure(attributeStatus.GetError());
        errorStatus.EncodeStatusIB(StatusIB(Protocols::InteractionModel::Status::Busy));
        attributeStatus.EndOfAttributeStatusIB();
        ReturnErrorOnFailure(attributeStatus.GetError());
        ReturnErrorOnFailure(attributeReport.EndOfAttributeReportIB());
    }

    return CHIP_NO_ERROR;
}

bool IsClusterDataVersionEqual(const app::ConcreteClusterPath & aConcreteClusterPath, DataVersion aRequiredVersion)
{
    if (aRequiredVersion == kDataVersion)
    {
        return true;
    }
    if (Test::GetVersion() == aRequiredVersion)
    {
        return true;
    }

    return false;
}

bool IsDeviceTypeOnEndpoint(DeviceTypeId deviceType, EndpointId endpoint)
{
    return false;
}

bool ConcreteAttributePathExists(const ConcreteAttributePath & aPath)
{
    return true;
}

Protocols::InteractionModel::Status CheckEventSupportStatus(const ConcreteEventPath & aPath)
{
    return Protocols::InteractionModel::Status::Success;
}

} // namespace app
} // namespace chip

namespace {

class TestRead : public ::testing::Test, public app::ReadHandler::ApplicationCallback
{
public:
    // Performs shared setup for all tests in the test suite
    static void SetUpTestSuite()
    {
        if (mpContext == nullptr)
        {
            mpContext = new TestContext();
            ASSERT_NE(mpContext, nullptr);
        }
        mpContext->SetUpTestSuite();
    }

    // Performs shared teardown for all tests in the test suite
    static void TearDownTestSuite()
    {
        mpContext->TearDownTestSuite();
        if (mpContext != nullptr)
        {
            delete mpContext;
            mpContext = nullptr;
        }
    }

protected:
    // Performs setup for each individual test in the test suite
    void SetUp() { mpContext->SetUp(); }

    // Performs teardown for each individual test in the test suite
    void TearDown() { mpContext->TearDown(); }

    static TestContext * mpContext;

    static uint16_t mMaxInterval;

    CHIP_ERROR OnSubscriptionRequested(app::ReadHandler & aReadHandler, Transport::SecureSession & aSecureSession)
    {
        VerifyOrReturnError(!mEmitSubscriptionError, CHIP_ERROR_INVALID_ARGUMENT);

        if (mAlterSubscriptionIntervals)
        {
            ReturnErrorOnFailure(aReadHandler.SetMaxReportingInterval(mMaxInterval));
        }
        return CHIP_NO_ERROR;
    }

    void OnSubscriptionEstablished(app::ReadHandler & aReadHandler) { mNumActiveSubscriptions++; }

    void OnSubscriptionTerminated(app::ReadHandler & aReadHandler) { mNumActiveSubscriptions--; }

    // Issue the given number of reads in parallel and wait for them all to
    // succeed.
    static void MultipleReadHelper(TestContext * apCtx, size_t aReadCount);

    // Helper for MultipleReadHelper that does not spin the event loop, so we
    // don't end up with nested event loops.
    static void MultipleReadHelperInternal(TestContext * apCtx, size_t aReadCount, uint32_t & aNumSuccessCalls,
                                           uint32_t & aNumFailureCalls);

    // Establish the given number of subscriptions, then issue the given number
    // of reads in parallel and wait for them all to succeed.
    static void SubscribeThenReadHelper(TestContext * apCtx, size_t aSubscribeCount, size_t aReadCount);

    // Compute the amount of time it would take a subscription with a given
    // max-interval to time out.
    static System::Clock::Timeout ComputeSubscriptionTimeout(System::Clock::Seconds16 aMaxInterval);

    bool mEmitSubscriptionError      = false;
    int32_t mNumActiveSubscriptions  = 0;
    bool mAlterSubscriptionIntervals = false;
};

TestContext * TestRead::mpContext = nullptr;
uint16_t TestRead::mMaxInterval   = 66;

class MockInteractionModelApp : public chip::app::ClusterStateCache::Callback
{
public:
    void OnEventData(const chip::app::EventHeader & aEventHeader, chip::TLV::TLVReader * apData,
                     const chip::app::StatusIB * apStatus) override
    {}

    void OnAttributeData(const chip::app::ConcreteDataAttributePath & aPath, chip::TLV::TLVReader * apData,
                         const chip::app::StatusIB & status) override
    {
        if (status.mStatus == chip::Protocols::InteractionModel::Status::Success)
        {
            ChipLogProgress(DataManagement, "\t\t -- attribute  status sucess");
            mNumAttributeResponse++;
        }
        ChipLogProgress(DataManagement, "\t\t -- OnAttributeData is called");
    }

    void OnError(CHIP_ERROR aError) override
    {
        mError     = aError;
        mReadError = true;
    }

    void OnDone(app::ReadClient *) override {}

    void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) override
    {
        if (aReadPrepareParams.mpAttributePathParamsList != nullptr)
        {
            delete[] aReadPrepareParams.mpAttributePathParamsList;
        }

        if (aReadPrepareParams.mpEventPathParamsList != nullptr)
        {
            delete[] aReadPrepareParams.mpEventPathParamsList;
        }

        if (aReadPrepareParams.mpDataVersionFilterList != nullptr)
        {
            delete[] aReadPrepareParams.mpDataVersionFilterList;
        }
    }

    int mNumAttributeResponse = 0;
    bool mReadError           = false;
    CHIP_ERROR mError         = CHIP_NO_ERROR;
};

TEST_F(TestRead, TestReadAttributeResponse)
{
    auto sessionHandle      = mpContext->GetSessionBobToAlice();
    bool onSuccessCbInvoked = false, onFailureCbInvoked = false;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&onSuccessCbInvoked](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        uint8_t i = 0;
        EXPECT_TRUE(attributePath.mDataVersion.HasValue() && attributePath.mDataVersion.Value() == kDataVersion);
        auto iter = dataResponse.begin();
        while (iter.Next())
        {
            auto & item = iter.GetValue();
            EXPECT_EQ(item.member1, i);
            i++;
        }
        EXPECT_EQ(i, 4u);
        EXPECT_EQ(iter.GetStatus(), CHIP_NO_ERROR);
        onSuccessCbInvoked = true;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&onFailureCbInvoked](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        onFailureCbInvoked = true;
    };

    Controller::ReadAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
        &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb);

    mpContext->DrainAndServiceIO();

    EXPECT_TRUE(onSuccessCbInvoked && !onFailureCbInvoked);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u);
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

// NOTE: This test must execute before TestReadSubscribeAttributeResponseWithCache or else it will fail on
// `EXPECT_TRUE(version1.HasValue() && (version1.Value() == 0))`.
TEST_F(TestRead, TestReadSubscribeAttributeResponseWithVersionOnlyCache)
{
    CHIP_ERROR err    = CHIP_NO_ERROR;
    responseDirective = kSendDataResponse;

    MockInteractionModelApp delegate;
    chip::app::ClusterStateCache cache(delegate, Optional<EventNumber>::Missing(), false /*cachedData*/);

    chip::app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice());
    //
    // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination
    // callbacks.
    //
    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    // read of E2C2A* and E3C2A2. Expect cache E2C2 version
    {
        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(),
                                   cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read);
        chip::app::AttributePathParams attributePathParams2[2];
        attributePathParams2[0].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams2[0].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams2[0].mAttributeId = kInvalidAttributeId;

        attributePathParams2[1].mEndpointId            = chip::Test::kMockEndpoint3;
        attributePathParams2[1].mClusterId             = chip::Test::MockClusterId(2);
        attributePathParams2[1].mAttributeId           = chip::Test::MockAttributeId(2);
        readPrepareParams.mpAttributePathParamsList    = attributePathParams2;
        readPrepareParams.mAttributePathParamsListSize = 2;
        err                                            = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();
        // There are supported 2 global and 3 non-global attributes in E2C2A* and  1 E3C2A2
        EXPECT_EQ(delegate.mNumAttributeResponse, 6);
        EXPECT_FALSE(delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        EXPECT_EQ(cache.GetVersion(clusterPath1, version1), CHIP_NO_ERROR);
        EXPECT_TRUE(version1.HasValue() && (version1.Value() == 0));
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));
        EXPECT_EQ(cache.GetVersion(clusterPath2, version2), CHIP_NO_ERROR);
        EXPECT_FALSE(version2.HasValue());

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_NE(cache.Get(attributePath, reader), CHIP_NO_ERROR);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(3));
            TLV::TLVReader reader;
            EXPECT_NE(cache.Get(attributePath, reader), CHIP_NO_ERROR);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_NE(cache.Get(attributePath, reader), CHIP_NO_ERROR);
        }
        delegate.mNumAttributeResponse = 0;
    }

    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u);
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache)
{
    CHIP_ERROR err    = CHIP_NO_ERROR;
    responseDirective = kSendDataResponse;

    MockInteractionModelApp delegate;
    chip::app::ClusterStateCache cache(delegate);

    chip::app::EventPathParams eventPathParams[100];
    for (auto & eventPathParam : eventPathParams)
    {
        eventPathParam.mEndpointId = chip::Test::kMockEndpoint3;
        eventPathParam.mClusterId  = chip::Test::MockClusterId(2);
        eventPathParam.mEventId    = 0;
    }

    chip::app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice());
    readPrepareParams.mMinIntervalFloorSeconds   = 0;
    readPrepareParams.mMaxIntervalCeilingSeconds = 4;
    //
    // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination
    // callbacks.
    //
    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    [[maybe_unused]] int testId = 0;

    // Read of E2C3A1(dedup), E*C3A1(E1C3A1 not exit, E2C3A1 exist), E2C3A* (5 supported attributes)
    // Expect no versions would be cached.
    {
        testId++;
        ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId);
        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(),
                                   cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read);
        chip::app::AttributePathParams attributePathParams1[3];
        attributePathParams1[0].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams1[0].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams1[0].mAttributeId = chip::Test::MockAttributeId(1);

        attributePathParams1[1].mEndpointId  = kInvalidEndpointId;
        attributePathParams1[1].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams1[1].mAttributeId = chip::Test::MockAttributeId(1);

        attributePathParams1[2].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams1[2].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams1[2].mAttributeId = kInvalidAttributeId;

        readPrepareParams.mpAttributePathParamsList    = attributePathParams1;
        readPrepareParams.mAttributePathParamsListSize = 3;
        err                                            = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();
        EXPECT_EQ(delegate.mNumAttributeResponse, 6);
        EXPECT_FALSE(delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        EXPECT_EQ(cache.GetVersion(clusterPath1, version1), CHIP_NO_ERROR);
        EXPECT_FALSE(version1.HasValue());
        delegate.mNumAttributeResponse = 0;
    }

    // Read of E2C3A1, E2C3A2 and E3C2A2.
    // Expect no versions would be cached.
    {
        testId++;
        ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId);
        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(),
                                   cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read);
        chip::app::AttributePathParams attributePathParams1[3];
        attributePathParams1[0].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams1[0].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams1[0].mAttributeId = chip::Test::MockAttributeId(1);

        attributePathParams1[1].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams1[1].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams1[1].mAttributeId = chip::Test::MockAttributeId(2);

        attributePathParams1[2].mEndpointId  = chip::Test::kMockEndpoint3;
        attributePathParams1[2].mClusterId   = chip::Test::MockClusterId(2);
        attributePathParams1[2].mAttributeId = chip::Test::MockAttributeId(2);

        readPrepareParams.mpAttributePathParamsList    = attributePathParams1;
        readPrepareParams.mAttributePathParamsListSize = 3;
        err                                            = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();
        EXPECT_EQ(delegate.mNumAttributeResponse, 3);
        EXPECT_FALSE(delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        EXPECT_EQ(cache.GetVersion(clusterPath1, version1), CHIP_NO_ERROR);
        EXPECT_FALSE(version1.HasValue());
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));
        EXPECT_EQ(cache.GetVersion(clusterPath2, version2), CHIP_NO_ERROR);
        EXPECT_FALSE(version2.HasValue());

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            EXPECT_EQ(receivedAttribute1, expectedAttribute1);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }

        delegate.mNumAttributeResponse = 0;
    }

    // Read of E*C2A2, E2C2A2 and E3C2A2 where 2nd, 3rd concrete paths are part of first wildcard path, would be deduplicate,
    // E*C2A2 don't have wildcard attribute so no version would be cached.
    // Expect no versions would be cached.
    {
        testId++;
        ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId);
        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(),
                                   cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read);
        chip::app::AttributePathParams attributePathParams1[3];
        attributePathParams1[0].mEndpointId  = kInvalidEndpointId;
        attributePathParams1[0].mClusterId   = chip::Test::MockClusterId(2);
        attributePathParams1[0].mAttributeId = chip::Test::MockAttributeId(2);

        attributePathParams1[1].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams1[1].mClusterId   = chip::Test::MockClusterId(2);
        attributePathParams1[1].mAttributeId = chip::Test::MockAttributeId(2);

        attributePathParams1[2].mEndpointId  = chip::Test::kMockEndpoint3;
        attributePathParams1[2].mClusterId   = chip::Test::MockClusterId(2);
        attributePathParams1[2].mAttributeId = chip::Test::MockAttributeId(2);

        readPrepareParams.mpAttributePathParamsList    = attributePathParams1;
        readPrepareParams.mAttributePathParamsListSize = 3;
        err                                            = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();
        EXPECT_EQ(delegate.mNumAttributeResponse, 2);
        EXPECT_FALSE(delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        EXPECT_EQ(cache.GetVersion(clusterPath1, version1), CHIP_NO_ERROR);
        EXPECT_FALSE(version1.HasValue());
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));
        EXPECT_EQ(cache.GetVersion(clusterPath2, version2), CHIP_NO_ERROR);
        EXPECT_FALSE(version2.HasValue());

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint1, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_NE(cache.Get(attributePath, reader), CHIP_NO_ERROR);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }
        delegate.mNumAttributeResponse = 0;
    }

    // read of E2C2A* and E3C2A2. We cannot use the stored data versions in the cache since there is no cached version from
    // previous test. Expect cache E2C2 version
    {
        testId++;
        ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId);
        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(),
                                   cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read);
        chip::app::AttributePathParams attributePathParams2[2];
        attributePathParams2[0].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams2[0].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams2[0].mAttributeId = kInvalidAttributeId;

        attributePathParams2[1].mEndpointId            = chip::Test::kMockEndpoint3;
        attributePathParams2[1].mClusterId             = chip::Test::MockClusterId(2);
        attributePathParams2[1].mAttributeId           = chip::Test::MockAttributeId(2);
        readPrepareParams.mpAttributePathParamsList    = attributePathParams2;
        readPrepareParams.mAttributePathParamsListSize = 2;
        err                                            = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();
        // There are supported 2 global and 3 non-global attributes in E2C2A* and  1 E3C2A2
        EXPECT_EQ(delegate.mNumAttributeResponse, 6);
        EXPECT_FALSE(delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        EXPECT_EQ(cache.GetVersion(clusterPath1, version1), CHIP_NO_ERROR);
        EXPECT_TRUE(version1.HasValue() && (version1.Value() == 0));
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));
        EXPECT_EQ(cache.GetVersion(clusterPath2, version2), CHIP_NO_ERROR);
        EXPECT_FALSE(version2.HasValue());

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            EXPECT_EQ(receivedAttribute1, expectedAttribute1);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(3));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            uint64_t receivedAttribute3;
            reader.Get(receivedAttribute3);
            EXPECT_EQ(receivedAttribute3, expectedAttribute3);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }
        delegate.mNumAttributeResponse = 0;
    }

    // Read of E2C3A1, E2C3A2, and E3C2A2. It would use the stored data versions in the cache since our subsequent read's C1A1
    // path intersects with previous cached data version Expect no E2C3 attributes in report, only E3C2A1 attribute in report
    {
        testId++;
        ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId);
        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(),
                                   cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read);
        chip::app::AttributePathParams attributePathParams1[3];
        attributePathParams1[0].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams1[0].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams1[0].mAttributeId = chip::Test::MockAttributeId(1);

        attributePathParams1[1].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams1[1].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams1[1].mAttributeId = chip::Test::MockAttributeId(2);

        attributePathParams1[2].mEndpointId  = chip::Test::kMockEndpoint3;
        attributePathParams1[2].mClusterId   = chip::Test::MockClusterId(2);
        attributePathParams1[2].mAttributeId = chip::Test::MockAttributeId(2);

        readPrepareParams.mpAttributePathParamsList    = attributePathParams1;
        readPrepareParams.mAttributePathParamsListSize = 3;
        err                                            = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();
        EXPECT_EQ(delegate.mNumAttributeResponse, 1);
        EXPECT_FALSE(delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        EXPECT_EQ(cache.GetVersion(clusterPath1, version1), CHIP_NO_ERROR);
        EXPECT_TRUE(version1.HasValue() && (version1.Value() == 0));
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));
        EXPECT_EQ(cache.GetVersion(clusterPath2, version2), CHIP_NO_ERROR);
        EXPECT_FALSE(version2.HasValue());

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            EXPECT_EQ(receivedAttribute1, expectedAttribute1);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }
        delegate.mNumAttributeResponse = 0;
    }

    // Read of E2C3A* and E3C2A2. It would use the stored data versions in the cache since our subsequent read's C1A* path
    // intersects with previous cached data version Expect no C1 attributes in report, only E3C2A2 attribute in report
    {
        testId++;
        ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId);
        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(),
                                   cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read);
        chip::app::AttributePathParams attributePathParams2[2];
        attributePathParams2[0].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams2[0].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams2[0].mAttributeId = kInvalidAttributeId;

        attributePathParams2[1].mEndpointId            = chip::Test::kMockEndpoint3;
        attributePathParams2[1].mClusterId             = chip::Test::MockClusterId(2);
        attributePathParams2[1].mAttributeId           = chip::Test::MockAttributeId(2);
        readPrepareParams.mpAttributePathParamsList    = attributePathParams2;
        readPrepareParams.mAttributePathParamsListSize = 2;
        err                                            = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();
        EXPECT_EQ(delegate.mNumAttributeResponse, 1);
        EXPECT_FALSE(delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        EXPECT_EQ(cache.GetVersion(clusterPath1, version1), CHIP_NO_ERROR);
        EXPECT_TRUE(version1.HasValue() && (version1.Value() == 0));
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));
        EXPECT_EQ(cache.GetVersion(clusterPath2, version2), CHIP_NO_ERROR);
        EXPECT_FALSE(version2.HasValue());

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            EXPECT_EQ(receivedAttribute1, expectedAttribute1);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(3));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            uint64_t receivedAttribute3;
            reader.Get(receivedAttribute3);
            EXPECT_EQ(receivedAttribute3, expectedAttribute3);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }
        delegate.mNumAttributeResponse = 0;
    }

    chip::Test::BumpVersion();

    // Read of E2C3A1, E2C3A2 and E3C2A2. It would use the stored data versions in the cache since our subsequent read's C1A*
    // path intersects with previous cached data version, server's version is changed. Expect E2C3A1, E2C3A2 and E3C2A2 attribute in
    // report, and invalidate the cached pending and committed data version since no wildcard attributes exists in mRequestPathSet.
    {
        testId++;
        ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId);
        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(),
                                   cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read);
        chip::app::AttributePathParams attributePathParams1[3];
        attributePathParams1[0].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams1[0].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams1[0].mAttributeId = chip::Test::MockAttributeId(1);

        attributePathParams1[1].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams1[1].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams1[1].mAttributeId = chip::Test::MockAttributeId(2);

        attributePathParams1[2].mEndpointId  = chip::Test::kMockEndpoint3;
        attributePathParams1[2].mClusterId   = chip::Test::MockClusterId(2);
        attributePathParams1[2].mAttributeId = chip::Test::MockAttributeId(2);

        readPrepareParams.mpAttributePathParamsList    = attributePathParams1;
        readPrepareParams.mAttributePathParamsListSize = 3;
        err                                            = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();
        EXPECT_EQ(delegate.mNumAttributeResponse, 3);
        EXPECT_FALSE(delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        EXPECT_EQ(cache.GetVersion(clusterPath1, version1), CHIP_NO_ERROR);
        EXPECT_FALSE(version1.HasValue());
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));
        EXPECT_EQ(cache.GetVersion(clusterPath2, version2), CHIP_NO_ERROR);
        EXPECT_FALSE(version2.HasValue());

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            EXPECT_EQ(receivedAttribute1, expectedAttribute1);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }
        delegate.mNumAttributeResponse = 0;
    }

    // Read of E2C3A1, E2C3A2 and E3C2A2. It would use none stored data versions in the cache since previous read does not
    // cache any committed data version. Expect E2C3A1, E2C3A2 and E3C2A2 attribute in report
    {
        testId++;
        ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId);
        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(),
                                   cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read);
        chip::app::AttributePathParams attributePathParams1[3];
        attributePathParams1[0].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams1[0].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams1[0].mAttributeId = chip::Test::MockAttributeId(1);

        attributePathParams1[1].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams1[1].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams1[1].mAttributeId = chip::Test::MockAttributeId(2);

        attributePathParams1[2].mEndpointId  = chip::Test::kMockEndpoint3;
        attributePathParams1[2].mClusterId   = chip::Test::MockClusterId(2);
        attributePathParams1[2].mAttributeId = chip::Test::MockAttributeId(2);

        readPrepareParams.mpAttributePathParamsList    = attributePathParams1;
        readPrepareParams.mAttributePathParamsListSize = 3;
        err                                            = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();
        EXPECT_EQ(delegate.mNumAttributeResponse, 3);
        EXPECT_FALSE(delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        EXPECT_EQ(cache.GetVersion(clusterPath1, version1), CHIP_NO_ERROR);
        EXPECT_FALSE(version1.HasValue());
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));
        EXPECT_EQ(cache.GetVersion(clusterPath2, version2), CHIP_NO_ERROR);
        EXPECT_FALSE(version2.HasValue());

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            EXPECT_EQ(receivedAttribute1, expectedAttribute1);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }
        delegate.mNumAttributeResponse = 0;
    }

    // Read of E2C3A* and E3C2A2, here there is no cached data version filter
    // Expect E2C3A* attributes in report, and E3C2A2 attribute in report and cache latest data version
    {
        testId++;
        ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId);
        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(),
                                   cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read);
        chip::app::AttributePathParams attributePathParams2[2];
        attributePathParams2[0].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams2[0].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams2[0].mAttributeId = kInvalidAttributeId;

        attributePathParams2[1].mEndpointId            = chip::Test::kMockEndpoint3;
        attributePathParams2[1].mClusterId             = chip::Test::MockClusterId(2);
        attributePathParams2[1].mAttributeId           = chip::Test::MockAttributeId(2);
        readPrepareParams.mpAttributePathParamsList    = attributePathParams2;
        readPrepareParams.mAttributePathParamsListSize = 2;
        err                                            = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();
        EXPECT_EQ(delegate.mNumAttributeResponse, 6);
        EXPECT_FALSE(delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        EXPECT_EQ(cache.GetVersion(clusterPath1, version1), CHIP_NO_ERROR);
        EXPECT_TRUE(version1.HasValue() && (version1.Value() == 1));
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));
        EXPECT_EQ(cache.GetVersion(clusterPath2, version2), CHIP_NO_ERROR);
        EXPECT_FALSE(version2.HasValue());

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            EXPECT_EQ(receivedAttribute1, expectedAttribute1);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(3));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            uint64_t receivedAttribute3;
            reader.Get(receivedAttribute3);
            EXPECT_EQ(receivedAttribute3, expectedAttribute3);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }
        delegate.mNumAttributeResponse = 0;
    }

    // Read of E2C3A* and E3C2A2, and inject a large amount of event path list, then it would try to apply previous cache
    // latest data version and construct data version list but run out of memory, finally fully rollback data version filter. Expect
    // E2C3A* attributes in report, and E3C2A2 attribute in report
    {
        testId++;
        ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId);
        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(),
                                   cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read);
        chip::app::AttributePathParams attributePathParams2[2];
        attributePathParams2[0].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams2[0].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams2[0].mAttributeId = kInvalidAttributeId;

        attributePathParams2[1].mEndpointId            = chip::Test::kMockEndpoint3;
        attributePathParams2[1].mClusterId             = chip::Test::MockClusterId(2);
        attributePathParams2[1].mAttributeId           = chip::Test::MockAttributeId(2);
        readPrepareParams.mpAttributePathParamsList    = attributePathParams2;
        readPrepareParams.mAttributePathParamsListSize = 2;

        readPrepareParams.mpEventPathParamsList = eventPathParams;
        // This size needs to be big enough that we can't fit our
        // DataVersionFilterIBs in the same packet.  Max size is
        // ArraySize(eventPathParams);
        static_assert(75 <= ArraySize(eventPathParams));
        readPrepareParams.mEventPathParamsListSize = 75;

        err = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();
        EXPECT_EQ(delegate.mNumAttributeResponse, 6);
        EXPECT_FALSE(delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        EXPECT_EQ(cache.GetVersion(clusterPath1, version1), CHIP_NO_ERROR);
        EXPECT_TRUE(version1.HasValue() && (version1.Value() == 1));
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));
        EXPECT_EQ(cache.GetVersion(clusterPath2, version2), CHIP_NO_ERROR);
        EXPECT_FALSE(version2.HasValue());

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            EXPECT_EQ(receivedAttribute1, expectedAttribute1);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(3));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            uint64_t receivedAttribute3;
            reader.Get(receivedAttribute3);
            EXPECT_EQ(receivedAttribute3, expectedAttribute3);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }
        delegate.mNumAttributeResponse             = 0;
        readPrepareParams.mpEventPathParamsList    = nullptr;
        readPrepareParams.mEventPathParamsListSize = 0;
    }

    chip::Test::BumpVersion();

    // Read of E1C2A* and E2C3A* and E2C2A*, it would use C1 cached version to construct DataVersionFilter, but version has
    // changed in server. Expect E1C2A* and C2C3A* and E2C2A* attributes in report, and cache their versions
    {
        testId++;
        ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId);
        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(),
                                   cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read);

        chip::app::AttributePathParams attributePathParams3[3];
        attributePathParams3[0].mEndpointId  = chip::Test::kMockEndpoint1;
        attributePathParams3[0].mClusterId   = chip::Test::MockClusterId(2);
        attributePathParams3[0].mAttributeId = kInvalidAttributeId;

        attributePathParams3[1].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams3[1].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams3[1].mAttributeId = kInvalidAttributeId;

        attributePathParams3[2].mEndpointId            = chip::Test::kMockEndpoint2;
        attributePathParams3[2].mClusterId             = chip::Test::MockClusterId(2);
        attributePathParams3[2].mAttributeId           = kInvalidAttributeId;
        readPrepareParams.mpAttributePathParamsList    = attributePathParams3;
        readPrepareParams.mAttributePathParamsListSize = 3;

        err = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();
        // E1C2A* has 3 attributes and E2C3A* has 5 attributes and E2C2A* has 4 attributes
        EXPECT_EQ(delegate.mNumAttributeResponse, 12);
        EXPECT_FALSE(delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        EXPECT_EQ(cache.GetVersion(clusterPath1, version1), CHIP_NO_ERROR);
        EXPECT_TRUE(version1.HasValue() && (version1.Value() == 2));
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(2));
        EXPECT_EQ(cache.GetVersion(clusterPath2, version2), CHIP_NO_ERROR);
        EXPECT_TRUE(version2.HasValue() && (version2.Value() == 2));
        Optional<DataVersion> version3;
        app::ConcreteClusterPath clusterPath3(chip::Test::kMockEndpoint1, chip::Test::MockClusterId(2));
        EXPECT_EQ(cache.GetVersion(clusterPath3, version3), CHIP_NO_ERROR);
        EXPECT_TRUE(version3.HasValue() && (version3.Value() == 2));

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint1, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            EXPECT_EQ(receivedAttribute1, expectedAttribute1);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            EXPECT_EQ(receivedAttribute1, expectedAttribute1);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(3));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            uint64_t receivedAttribute3;
            reader.Get(receivedAttribute3);
            EXPECT_EQ(receivedAttribute3, expectedAttribute3);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            EXPECT_EQ(receivedAttribute1, expectedAttribute1);
        }
        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }

        delegate.mNumAttributeResponse = 0;
    }

    // Read of E1C2A*(3 attributes) and E2C3A*(5 attributes) and E2C2A*(4 attributes), and inject a large amount of event path
    // list, then it would try to apply previous cache latest data version and construct data version list with the ordering from
    // largest cluster size to smallest cluster size(C3, C2, C1) but run out of memory, finally partially rollback data version
    // filter with only C3. Expect E1C2A*, E2C2A* attributes(7 attributes) in report,
    {
        testId++;
        ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId);
        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(),
                                   cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read);

        chip::app::AttributePathParams attributePathParams3[3];
        attributePathParams3[0].mEndpointId  = chip::Test::kMockEndpoint1;
        attributePathParams3[0].mClusterId   = chip::Test::MockClusterId(2);
        attributePathParams3[0].mAttributeId = kInvalidAttributeId;

        attributePathParams3[1].mEndpointId  = chip::Test::kMockEndpoint2;
        attributePathParams3[1].mClusterId   = chip::Test::MockClusterId(3);
        attributePathParams3[1].mAttributeId = kInvalidAttributeId;

        attributePathParams3[2].mEndpointId            = chip::Test::kMockEndpoint2;
        attributePathParams3[2].mClusterId             = chip::Test::MockClusterId(2);
        attributePathParams3[2].mAttributeId           = kInvalidAttributeId;
        readPrepareParams.mpAttributePathParamsList    = attributePathParams3;
        readPrepareParams.mAttributePathParamsListSize = 3;
        readPrepareParams.mpEventPathParamsList        = eventPathParams;

        // This size needs to be big enough that we can only fit our first
        // DataVersionFilterIB. Max size is ArraySize(eventPathParams);
        static_assert(73 <= ArraySize(eventPathParams));
        readPrepareParams.mEventPathParamsListSize = 73;
        err                                        = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();
        EXPECT_EQ(delegate.mNumAttributeResponse, 7);
        EXPECT_FALSE(delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        EXPECT_EQ(cache.GetVersion(clusterPath1, version1), CHIP_NO_ERROR);
        EXPECT_TRUE(version1.HasValue() && (version1.Value() == 2));
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(2));
        EXPECT_EQ(cache.GetVersion(clusterPath2, version2), CHIP_NO_ERROR);
        EXPECT_TRUE(version2.HasValue() && (version2.Value() == 2));
        Optional<DataVersion> version3;
        app::ConcreteClusterPath clusterPath3(chip::Test::kMockEndpoint1, chip::Test::MockClusterId(2));
        EXPECT_EQ(cache.GetVersion(clusterPath3, version3), CHIP_NO_ERROR);
        EXPECT_TRUE(version3.HasValue() && (version3.Value() == 2));

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint1, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            EXPECT_EQ(receivedAttribute1, expectedAttribute1);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            EXPECT_EQ(receivedAttribute1, expectedAttribute1);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3),
                                                     chip::Test::MockAttributeId(3));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            uint64_t receivedAttribute3;
            reader.Get(receivedAttribute3);
            EXPECT_EQ(receivedAttribute3, expectedAttribute3);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            EXPECT_EQ(receivedAttribute1, expectedAttribute1);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }
        delegate.mNumAttributeResponse             = 0;
        readPrepareParams.mpEventPathParamsList    = nullptr;
        readPrepareParams.mEventPathParamsListSize = 0;
    }

    // Read of E3C2 which has a oversized list attribute, MockAttributeId (4). It would use none stored data versions in the cache
    // since previous read does not cache any committed data version for E3C2, and expect to cache E3C2's version
    {
        testId++;
        ChipLogProgress(DataManagement, "\t -- Running Read with ClusterStateCache Test ID %d", testId);
        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(),
                                   cache.GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read);
        chip::app::AttributePathParams attributePathParams1[1];
        attributePathParams1[0].mEndpointId = chip::Test::kMockEndpoint3;
        attributePathParams1[0].mClusterId  = chip::Test::MockClusterId(2);

        readPrepareParams.mpAttributePathParamsList    = attributePathParams1;
        readPrepareParams.mAttributePathParamsListSize = 1;
        err                                            = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();
        EXPECT_EQ(delegate.mNumAttributeResponse, 6);
        EXPECT_FALSE(delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));

        EXPECT_EQ(cache.GetVersion(clusterPath, version1), CHIP_NO_ERROR);
        EXPECT_TRUE(version1.HasValue());

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            EXPECT_EQ(receivedAttribute1, expectedAttribute1);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            EXPECT_EQ(receivedAttribute2, expectedAttribute2);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(3));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            uint64_t receivedAttribute3;
            reader.Get(receivedAttribute3);
            EXPECT_EQ(receivedAttribute3, expectedAttribute3);
        }

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(4));
            TLV::TLVReader reader;
            EXPECT_EQ(cache.Get(attributePath, reader), CHIP_NO_ERROR);
            uint8_t receivedAttribute4[256];
            reader.GetBytes(receivedAttribute4, 256);
            EXPECT_TRUE(memcmp(receivedAttribute4, expectedAttribute4, 256));
        }
        delegate.mNumAttributeResponse = 0;
    }

    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u);
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestRead, TestReadEventResponse)
{
    auto sessionHandle      = mpContext->GetSessionBobToAlice();
    bool onSuccessCbInvoked = false, onFailureCbInvoked = false, onDoneCbInvoked = false;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&onSuccessCbInvoked](const app::EventHeader & eventHeader, const auto & EventResponse) {
        // TODO: Need to add check when IM event server integration completes
        onSuccessCbInvoked = true;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&onFailureCbInvoked](const app::EventHeader * eventHeader, CHIP_ERROR aError) {
        onFailureCbInvoked = true;
    };

    auto onDoneCb = [&onDoneCbInvoked](app::ReadClient * apReadClient) { onDoneCbInvoked = true; };

    Controller::ReadEvent<Clusters::UnitTesting::Events::TestEvent::DecodableType>(
        &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, onDoneCb);

    mpContext->DrainAndServiceIO();

    EXPECT_FALSE(onFailureCbInvoked);
    EXPECT_TRUE(onDoneCbInvoked);

    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u);
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestRead, TestReadAttributeError)
{
    auto sessionHandle      = mpContext->GetSessionBobToAlice();
    bool onSuccessCbInvoked = false, onFailureCbInvoked = false;

    responseDirective = kSendDataError;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&onSuccessCbInvoked](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        onSuccessCbInvoked = true;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&onFailureCbInvoked](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        EXPECT_TRUE(aError.IsIMStatus() && app::StatusIB(aError).mStatus == Protocols::InteractionModel::Status::Busy);
        onFailureCbInvoked = true;
    };

    Controller::ReadAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
        &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb);

    mpContext->DrainAndServiceIO();

    EXPECT_TRUE(!onSuccessCbInvoked && onFailureCbInvoked);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u);
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestRead, TestReadAttributeTimeout)
{
    auto sessionHandle      = mpContext->GetSessionBobToAlice();
    bool onSuccessCbInvoked = false, onFailureCbInvoked = false;

    responseDirective = kSendDataError;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&onSuccessCbInvoked](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        onSuccessCbInvoked = true;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&onFailureCbInvoked](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        EXPECT_EQ(aError, CHIP_ERROR_TIMEOUT);
        onFailureCbInvoked = true;
    };

    Controller::ReadAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
        &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb);

    mpContext->ExpireSessionAliceToBob();

    mpContext->DrainAndServiceIO();

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 1u);

    mpContext->ExpireSessionBobToAlice();

    mpContext->DrainAndServiceIO();

    EXPECT_TRUE(!onSuccessCbInvoked && onFailureCbInvoked);

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u);

    //
    // Let's put back the sessions so that the next tests (which assume a valid initialized set of sessions)
    // can function correctly.
    //
    mpContext->CreateSessionAliceToBob();
    mpContext->CreateSessionBobToAlice();

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

class TestResubscriptionCallback : public app::ReadClient::Callback
{
public:
    TestResubscriptionCallback() {}

    void SetReadClient(app::ReadClient * apReadClient) { mpReadClient = apReadClient; }

    void OnDone(app::ReadClient *) override { mOnDone++; }

    void OnError(CHIP_ERROR aError) override
    {
        mOnError++;
        mLastError = aError;
    }

    void OnSubscriptionEstablished(SubscriptionId aSubscriptionId) override { mOnSubscriptionEstablishedCount++; }

    CHIP_ERROR OnResubscriptionNeeded(app::ReadClient * apReadClient, CHIP_ERROR aTerminationCause) override
    {
        mOnResubscriptionsAttempted++;
        mLastError = aTerminationCause;
        if (aTerminationCause == CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT && !mScheduleLITResubscribeImmediately)
        {
            return CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT;
        }
        return apReadClient->ScheduleResubscription(apReadClient->ComputeTimeTillNextSubscription(), NullOptional, false);
    }

    void ClearCounters()
    {
        mOnSubscriptionEstablishedCount = 0;
        mOnDone                         = 0;
        mOnError                        = 0;
        mOnResubscriptionsAttempted     = 0;
        mLastError                      = CHIP_NO_ERROR;
    }

    int32_t mAttributeCount                 = 0;
    int32_t mOnReportEnd                    = 0;
    int32_t mOnSubscriptionEstablishedCount = 0;
    int32_t mOnResubscriptionsAttempted     = 0;
    int32_t mOnDone                         = 0;
    int32_t mOnError                        = 0;
    CHIP_ERROR mLastError                   = CHIP_NO_ERROR;
    bool mScheduleLITResubscribeImmediately = false;
    app::ReadClient * mpReadClient          = nullptr;
};

//
// This validates the re-subscription logic within ReadClient. This achieves it by overriding the timeout for the liveness
// timer within ReadClient to be a smaller value than the nominal max interval of the subscription. This causes the
// subscription to fail on the client side, triggering re-subscription.
//
// TODO: This does not validate the CASE establishment pathways since we're limited by the PASE-centric TestContext.
//
//
TEST_F(TestRead, TestResubscribeAttributeTimeout)
{
    auto sessionHandle = mpContext->GetSessionBobToAlice();

    mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive);

    {
        TestResubscriptionCallback callback;
        app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), callback,
                                   app::ReadClient::InteractionType::Subscribe);

        callback.SetReadClient(&readClient);

        app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice());

        // Read full wildcard paths, repeat twice to ensure chunking.
        app::AttributePathParams attributePathParams[1];
        readPrepareParams.mpAttributePathParamsList    = attributePathParams;
        readPrepareParams.mAttributePathParamsListSize = ArraySize(attributePathParams);
        attributePathParams[0].mEndpointId             = kTestEndpointId;
        attributePathParams[0].mClusterId              = app::Clusters::UnitTesting::Id;
        attributePathParams[0].mAttributeId            = app::Clusters::UnitTesting::Attributes::Boolean::Id;

        constexpr uint16_t maxIntervalCeilingSeconds = 1;

        readPrepareParams.mMaxIntervalCeilingSeconds = maxIntervalCeilingSeconds;

        auto err = readClient.SendAutoResubscribeRequest(std::move(readPrepareParams));
        EXPECT_EQ(err, CHIP_NO_ERROR);

        //
        // Drive servicing IO till we have established a subscription.
        //
        mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000),
                                               [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; });
        EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1);
        EXPECT_EQ(callback.mOnError, 0);
        EXPECT_EQ(callback.mOnResubscriptionsAttempted, 0);

        chip::app::ReadHandler * readHandler = app::InteractionModelEngine::GetInstance()->ActiveHandlerAt(0);

        uint16_t minInterval;
        uint16_t maxInterval;
        readHandler->GetReportingIntervals(minInterval, maxInterval);

        //
        // Disable packet transmission, and drive IO till we have reported a re-subscription attempt.
        //
        //
        mpContext->GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount;
        mpContext->GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)),
                                               [&]() { return callback.mOnResubscriptionsAttempted > 0; });

        EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1);
        EXPECT_EQ(callback.mLastError, CHIP_ERROR_TIMEOUT);

        mpContext->GetLoopback().mNumMessagesToDrop = 0;
        callback.ClearCounters();

        //
        // Drive servicing IO till we have established a subscription.
        //
        mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000),
                                               [&]() { return callback.mOnSubscriptionEstablishedCount == 1; });
        EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1);

        //
        // With re-sub enabled, we shouldn't have encountered any errors
        //
        EXPECT_EQ(callback.mOnError, 0);
        EXPECT_EQ(callback.mOnDone, 0);
    }

    mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

//
// This validates a vanilla subscription with re-susbcription disabled timing out correctly on the client
// side and triggering the OnError callback with the right error code.
//
TEST_F(TestRead, TestSubscribeAttributeTimeout)
{
    auto sessionHandle = mpContext->GetSessionBobToAlice();

    mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive);

    {
        TestResubscriptionCallback callback;
        app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), callback,
                                   app::ReadClient::InteractionType::Subscribe);

        callback.SetReadClient(&readClient);

        app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice());

        app::AttributePathParams attributePathParams[1];
        readPrepareParams.mpAttributePathParamsList    = attributePathParams;
        readPrepareParams.mAttributePathParamsListSize = ArraySize(attributePathParams);
        attributePathParams[0].mEndpointId             = kTestEndpointId;
        attributePathParams[0].mClusterId              = app::Clusters::UnitTesting::Id;
        attributePathParams[0].mAttributeId            = app::Clusters::UnitTesting::Attributes::Boolean::Id;

        //
        // Request a max interval that's very small to reduce time to discovering a liveness failure.
        //
        constexpr uint16_t maxIntervalCeilingSeconds = 1;
        readPrepareParams.mMaxIntervalCeilingSeconds = maxIntervalCeilingSeconds;

        auto err = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        //
        // Drive servicing IO till we have established a subscription.
        //
        mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000),
                                               [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; });
        EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1);

        //
        // Request we drop all further messages.
        //
        mpContext->GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount;

        chip::app::ReadHandler * readHandler = app::InteractionModelEngine::GetInstance()->ActiveHandlerAt(0);

        uint16_t minInterval;
        uint16_t maxInterval;
        readHandler->GetReportingIntervals(minInterval, maxInterval);

        //
        // Drive IO until we get an error on the subscription, which should be caused
        // by the liveness timer firing once we hit our max-interval plus
        // retransmit timeouts.
        //
        mpContext->GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)),
                                               [&]() { return callback.mOnError >= 1; });

        EXPECT_EQ(callback.mOnError, 1);
        EXPECT_EQ(callback.mLastError, CHIP_ERROR_TIMEOUT);
        EXPECT_EQ(callback.mOnDone, 1);
        EXPECT_EQ(callback.mOnResubscriptionsAttempted, 0);
    }

    mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
    mpContext->GetLoopback().mNumMessagesToDrop = 0;
}

TEST_F(TestRead, TestReadHandler_MultipleSubscriptions)
{
    auto sessionHandle                       = mpContext->GetSessionBobToAlice();
    uint32_t numSuccessCalls                 = 0;
    uint32_t numSubscriptionEstablishedCalls = 0;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&numSuccessCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        numSuccessCalls++;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        //
        // We shouldn't be encountering any failures in this test.
        //
        EXPECT_TRUE(false);
    };

    auto onSubscriptionEstablishedCb = [&numSubscriptionEstablishedCalls](const app::ReadClient & readClient,
                                                                          chip::SubscriptionId aSubscriptionId) {
        numSubscriptionEstablishedCalls++;
    };

    //
    // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination
    // callbacks.
    //
    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    //
    // Try to issue parallel subscriptions that will exceed the value for app::InteractionModelEngine::kReadHandlerPoolSize.
    // If heap allocation is correctly setup, this should result in it successfully servicing more than the number
    // present in that define.
    //
    for (size_t i = 0; i < (app::InteractionModelEngine::kReadHandlerPoolSize + 1); i++)
    {
        EXPECT_EQ(Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                      &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 20,
                      onSubscriptionEstablishedCb, nullptr, false, true),
                  CHIP_NO_ERROR);
    }

    // There are too many messages and the test (gcc_debug, which includes many sanity checks) will be quite slow. Note: report
    // engine is using ScheduleWork which cannot be handled by DrainAndServiceIO correctly.
    mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(60), [&]() {
        return numSuccessCalls == (app::InteractionModelEngine::kReadHandlerPoolSize + 1) &&
            numSubscriptionEstablishedCalls == (app::InteractionModelEngine::kReadHandlerPoolSize + 1);
    });

    EXPECT_EQ(numSuccessCalls, (app::InteractionModelEngine::kReadHandlerPoolSize + 1));
    EXPECT_EQ(numSubscriptionEstablishedCalls, (app::InteractionModelEngine::kReadHandlerPoolSize + 1));
    EXPECT_EQ(mNumActiveSubscriptions, static_cast<int32_t>(app::InteractionModelEngine::kReadHandlerPoolSize + 1));

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();

    EXPECT_EQ(mNumActiveSubscriptions, 0);
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault);
    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
}

TEST_F(TestRead, TestReadHandler_SubscriptionAppRejection)
{
    auto sessionHandle                       = mpContext->GetSessionBobToAlice();
    uint32_t numSuccessCalls                 = 0;
    uint32_t numFailureCalls                 = 0;
    uint32_t numSubscriptionEstablishedCalls = 0;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&numSuccessCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        numSuccessCalls++;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&numFailureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        numFailureCalls++;
    };

    auto onSubscriptionEstablishedCb = [&numSubscriptionEstablishedCalls](const app::ReadClient & readClient,
                                                                          chip::SubscriptionId aSubscriptionId) {
        numSubscriptionEstablishedCalls++;
    };

    //
    // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination
    // callbacks.
    //
    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    //
    // Test the application rejecting subscriptions.
    //
    mEmitSubscriptionError = true;

    EXPECT_EQ(Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                  &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10,
                  onSubscriptionEstablishedCb, nullptr, false, true),
              CHIP_NO_ERROR);

    mpContext->DrainAndServiceIO();

    EXPECT_EQ(numSuccessCalls, 0u);

    //
    // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute
    // implementation.
    //
    EXPECT_EQ(numFailureCalls, 0u);
    EXPECT_EQ(numSubscriptionEstablishedCalls, 0u);
    EXPECT_EQ(mNumActiveSubscriptions, 0);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
    mEmitSubscriptionError = false;
}

#if CHIP_CONFIG_ENABLE_ICD_SERVER != 1

// Subscriber sends the request with particular max-interval value:
// Max interval equal to client-requested min-interval.
TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest1)
{
    auto sessionHandle                       = mpContext->GetSessionBobToAlice();
    uint32_t numSuccessCalls                 = 0;
    uint32_t numFailureCalls                 = 0;
    uint32_t numSubscriptionEstablishedCalls = 0;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&numSuccessCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        numSuccessCalls++;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&numFailureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        numFailureCalls++;
    };

    auto onSubscriptionEstablishedCb = [&numSubscriptionEstablishedCalls](const app::ReadClient & readClient,
                                                                          chip::SubscriptionId aSubscriptionId) {
        uint16_t minInterval = 0, maxInterval = 0;

        CHIP_ERROR err = readClient.GetReportingIntervals(minInterval, maxInterval);

        EXPECT_EQ(err, CHIP_NO_ERROR);

        EXPECT_EQ(minInterval, 5);
        EXPECT_EQ(maxInterval, 5);

        numSubscriptionEstablishedCalls++;
    };

    //
    // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination
    // callbacks.
    //
    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    //
    // Test the server-side application altering the subscription intervals.
    //
    mAlterSubscriptionIntervals = false;

    EXPECT_EQ(Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                  &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 5, 5,
                  onSubscriptionEstablishedCb, nullptr, true),
              CHIP_NO_ERROR);

    mpContext->DrainAndServiceIO();

    //
    // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute
    // implementation.
    //
    EXPECT_NE(numSuccessCalls, 0u);
    EXPECT_EQ(numFailureCalls, 0u);
    EXPECT_EQ(numSubscriptionEstablishedCalls, 1u);
    EXPECT_EQ(mNumActiveSubscriptions, 1);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();

    EXPECT_EQ(mNumActiveSubscriptions, 0);

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
    mAlterSubscriptionIntervals = false;
}

// Subscriber sends the request with particular max-interval value:
// Max interval greater than client-requested min-interval but lower than 60m:
// With no server adjustment.
TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest2)
{
    auto sessionHandle                       = mpContext->GetSessionBobToAlice();
    uint32_t numSuccessCalls                 = 0;
    uint32_t numFailureCalls                 = 0;
    uint32_t numSubscriptionEstablishedCalls = 0;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&numSuccessCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        numSuccessCalls++;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&numFailureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        numFailureCalls++;
    };

    auto onSubscriptionEstablishedCb = [&numSubscriptionEstablishedCalls](const app::ReadClient & readClient,
                                                                          chip::SubscriptionId aSubscriptionId) {
        uint16_t minInterval = 0, maxInterval = 0;

        CHIP_ERROR err = readClient.GetReportingIntervals(minInterval, maxInterval);

        EXPECT_EQ(err, CHIP_NO_ERROR);

        EXPECT_EQ(minInterval, 0);
        EXPECT_EQ(maxInterval, 10);

        numSubscriptionEstablishedCalls++;
    };

    //
    // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination
    // callbacks.
    //
    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    //
    // Test the server-side application altering the subscription intervals.
    //
    mAlterSubscriptionIntervals = false;

    EXPECT_EQ(Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                  &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10,
                  onSubscriptionEstablishedCb, nullptr, true),
              CHIP_NO_ERROR);

    mpContext->DrainAndServiceIO();

    //
    // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute
    // implementation.
    //
    EXPECT_NE(numSuccessCalls, 0u);
    EXPECT_EQ(numFailureCalls, 0u);
    EXPECT_EQ(numSubscriptionEstablishedCalls, 1u);
    EXPECT_EQ(mNumActiveSubscriptions, 1);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();

    EXPECT_EQ(mNumActiveSubscriptions, 0);

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
    mAlterSubscriptionIntervals = false;
}

// Subscriber sends the request with particular max-interval value:
// Max interval greater than client-requested min-interval but lower than 60m:
// With server adjustment to a value greater than client-requested, but less than 60m (allowed).
TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest3)
{
    auto sessionHandle                       = mpContext->GetSessionBobToAlice();
    uint32_t numSuccessCalls                 = 0;
    uint32_t numFailureCalls                 = 0;
    uint32_t numSubscriptionEstablishedCalls = 0;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&numSuccessCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        numSuccessCalls++;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&numFailureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        numFailureCalls++;
    };

    auto onSubscriptionEstablishedCb = [&numSubscriptionEstablishedCalls](const app::ReadClient & readClient,
                                                                          chip::SubscriptionId aSubscriptionId) {
        uint16_t minInterval = 0, maxInterval = 0;

        CHIP_ERROR err = readClient.GetReportingIntervals(minInterval, maxInterval);

        EXPECT_EQ(err, CHIP_NO_ERROR);

        EXPECT_EQ(minInterval, 0);
        EXPECT_EQ(maxInterval, 3000);

        numSubscriptionEstablishedCalls++;
    };

    //
    // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination
    // callbacks.
    //
    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    //
    // Test the server-side application altering the subscription intervals.
    //
    mAlterSubscriptionIntervals = true;
    mMaxInterval                = 3000;
    EXPECT_EQ(Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                  &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10,
                  onSubscriptionEstablishedCb, nullptr, true),
              CHIP_NO_ERROR);

    mpContext->DrainAndServiceIO();

    //
    // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute
    // implementation.
    //
    EXPECT_NE(numSuccessCalls, 0u);
    EXPECT_EQ(numFailureCalls, 0u);
    EXPECT_EQ(numSubscriptionEstablishedCalls, 1u);
    EXPECT_EQ(mNumActiveSubscriptions, 1);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();

    EXPECT_EQ(mNumActiveSubscriptions, 0);

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
    mAlterSubscriptionIntervals = false;
}

#endif // CHIP_CONFIG_ENABLE_ICD_SERVER

// Subscriber sends the request with particular max-interval value:
// Max interval greater than client-requested min-interval but lower than 60m:
// server adjustment to a value greater than client-requested, but greater than 60 (not allowed).
TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest4)
{
    auto sessionHandle                       = mpContext->GetSessionBobToAlice();
    uint32_t numSuccessCalls                 = 0;
    uint32_t numFailureCalls                 = 0;
    uint32_t numSubscriptionEstablishedCalls = 0;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&numSuccessCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        numSuccessCalls++;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&numFailureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        numFailureCalls++;
    };

    auto onSubscriptionEstablishedCb = [&numSubscriptionEstablishedCalls](const app::ReadClient & readClient,
                                                                          chip::SubscriptionId aSubscriptionId) {
        numSubscriptionEstablishedCalls++;
    };

    //
    // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination
    // callbacks.
    //
    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    //
    // Test the server-side application altering the subscription intervals.
    //
    mAlterSubscriptionIntervals = true;
    mMaxInterval                = 3700;
    EXPECT_EQ(Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                  &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10,
                  onSubscriptionEstablishedCb, nullptr, true),
              CHIP_NO_ERROR);

    mpContext->DrainAndServiceIO();

    //
    // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute
    // implementation.
    //
    EXPECT_EQ(numSuccessCalls, 0u);
    EXPECT_EQ(numSubscriptionEstablishedCalls, 0u);
    EXPECT_EQ(mNumActiveSubscriptions, 0);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();

    EXPECT_EQ(mNumActiveSubscriptions, 0);

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
    mAlterSubscriptionIntervals = false;
}

#if CHIP_CONFIG_ENABLE_ICD_SERVER != 1

// Subscriber sends the request with particular max-interval value:
// Max interval greater than client-requested min-interval but greater than 60m:
// With no server adjustment.
TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest5)
{
    auto sessionHandle                       = mpContext->GetSessionBobToAlice();
    uint32_t numSuccessCalls                 = 0;
    uint32_t numFailureCalls                 = 0;
    uint32_t numSubscriptionEstablishedCalls = 0;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&numSuccessCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        numSuccessCalls++;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&numFailureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        numFailureCalls++;
    };

    auto onSubscriptionEstablishedCb = [&numSubscriptionEstablishedCalls](const app::ReadClient & readClient,
                                                                          chip::SubscriptionId aSubscriptionId) {
        uint16_t minInterval = 0, maxInterval = 0;

        CHIP_ERROR err = readClient.GetReportingIntervals(minInterval, maxInterval);

        EXPECT_EQ(err, CHIP_NO_ERROR);

        EXPECT_EQ(minInterval, 0);
        EXPECT_EQ(maxInterval, 4000);

        numSubscriptionEstablishedCalls++;
    };

    //
    // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination
    // callbacks.
    //
    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    //
    // Test the server-side application altering the subscription intervals.
    //
    mAlterSubscriptionIntervals = false;

    EXPECT_EQ(Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                  &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 4000,
                  onSubscriptionEstablishedCb, nullptr, true),
              CHIP_NO_ERROR);

    mpContext->DrainAndServiceIO();

    //
    // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute
    // implementation.
    //
    EXPECT_NE(numSuccessCalls, 0u);
    EXPECT_EQ(numFailureCalls, 0u);
    EXPECT_EQ(numSubscriptionEstablishedCalls, 1u);
    EXPECT_EQ(mNumActiveSubscriptions, 1);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();

    EXPECT_EQ(mNumActiveSubscriptions, 0);

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
    mAlterSubscriptionIntervals = false;
}

// Subscriber sends the request with particular max-interval value:
// Max interval greater than client-requested min-interval but greater than 60m:
// With server adjustment to a value lower than 60m. Allowed
TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest6)
{
    auto sessionHandle                       = mpContext->GetSessionBobToAlice();
    uint32_t numSuccessCalls                 = 0;
    uint32_t numFailureCalls                 = 0;
    uint32_t numSubscriptionEstablishedCalls = 0;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&numSuccessCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        numSuccessCalls++;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&numFailureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        numFailureCalls++;
    };

    auto onSubscriptionEstablishedCb = [&numSubscriptionEstablishedCalls](const app::ReadClient & readClient,
                                                                          chip::SubscriptionId aSubscriptionId) {
        uint16_t minInterval = 0, maxInterval = 0;

        CHIP_ERROR err = readClient.GetReportingIntervals(minInterval, maxInterval);

        EXPECT_EQ(err, CHIP_NO_ERROR);

        EXPECT_EQ(minInterval, 0);
        EXPECT_EQ(maxInterval, 3000);

        numSubscriptionEstablishedCalls++;
    };

    //
    // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination
    // callbacks.
    //
    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    //
    // Test the server-side application altering the subscription intervals.
    //
    mAlterSubscriptionIntervals = true;
    mMaxInterval                = 3000;
    EXPECT_EQ(Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                  &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 4000,
                  onSubscriptionEstablishedCb, nullptr, true),
              CHIP_NO_ERROR);

    mpContext->DrainAndServiceIO();

    //
    // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute
    // implementation.
    //
    EXPECT_NE(numSuccessCalls, 0u);
    EXPECT_EQ(numFailureCalls, 0u);
    EXPECT_EQ(numSubscriptionEstablishedCalls, 1u);
    EXPECT_EQ(mNumActiveSubscriptions, 1);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();

    EXPECT_EQ(mNumActiveSubscriptions, 0);

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
    mAlterSubscriptionIntervals = false;
}

// Subscriber sends the request with particular max-interval value:
// Max interval greater than client-requested min-interval but greater than 60m:
// With server adjustment to a value larger than 60m, but less than max interval. Allowed
TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest7)
{
    auto sessionHandle                       = mpContext->GetSessionBobToAlice();
    uint32_t numSuccessCalls                 = 0;
    uint32_t numFailureCalls                 = 0;
    uint32_t numSubscriptionEstablishedCalls = 0;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&numSuccessCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        numSuccessCalls++;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&numFailureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        numFailureCalls++;
    };

    auto onSubscriptionEstablishedCb = [&numSubscriptionEstablishedCalls](const app::ReadClient & readClient,
                                                                          chip::SubscriptionId aSubscriptionId) {
        uint16_t minInterval = 0, maxInterval = 0;

        CHIP_ERROR err = readClient.GetReportingIntervals(minInterval, maxInterval);

        EXPECT_EQ(err, CHIP_NO_ERROR);

        EXPECT_EQ(minInterval, 0);
        EXPECT_EQ(maxInterval, 3700);

        numSubscriptionEstablishedCalls++;
    };
    //
    // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination
    // callbacks.
    //
    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    //
    // Test the server-side application altering the subscription intervals.
    //
    mAlterSubscriptionIntervals = true;
    mMaxInterval                = 3700;
    EXPECT_EQ(Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                  &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 4000,
                  onSubscriptionEstablishedCb, nullptr, true),
              CHIP_NO_ERROR);

    mpContext->DrainAndServiceIO();

    //
    // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute
    // implementation.
    //
    EXPECT_NE(numSuccessCalls, 0u);
    EXPECT_EQ(numFailureCalls, 0u);
    EXPECT_EQ(numSubscriptionEstablishedCalls, 1u);
    EXPECT_EQ(mNumActiveSubscriptions, 1);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();

    EXPECT_EQ(mNumActiveSubscriptions, 0);

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
    mAlterSubscriptionIntervals = false;
}

#endif // CHIP_CONFIG_ENABLE_ICD_SERVER

// Subscriber sends the request with particular max-interval value:
// Max interval greater than client-requested min-interval but greater than 60m:
// With server adjustment to a value larger than 60m, but larger than max interval. Disallowed
TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest8)
{
    auto sessionHandle                       = mpContext->GetSessionBobToAlice();
    uint32_t numSuccessCalls                 = 0;
    uint32_t numFailureCalls                 = 0;
    uint32_t numSubscriptionEstablishedCalls = 0;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&numSuccessCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        numSuccessCalls++;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&numFailureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        numFailureCalls++;
    };

    auto onSubscriptionEstablishedCb = [&numSubscriptionEstablishedCalls](const app::ReadClient & readClient,
                                                                          chip::SubscriptionId aSubscriptionId) {
        numSubscriptionEstablishedCalls++;
    };
    //
    // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination
    // callbacks.
    //
    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    //
    // Test the server-side application altering the subscription intervals.
    //
    mAlterSubscriptionIntervals = true;
    mMaxInterval                = 4100;
    EXPECT_EQ(Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                  &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 4000,
                  onSubscriptionEstablishedCb, nullptr, true),
              CHIP_NO_ERROR);

    mpContext->DrainAndServiceIO();

    //
    // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute
    // implementation.
    //
    EXPECT_EQ(numSuccessCalls, 0u);
    EXPECT_EQ(numSubscriptionEstablishedCalls, 0u);
    EXPECT_EQ(mNumActiveSubscriptions, 0);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();

    EXPECT_EQ(mNumActiveSubscriptions, 0);

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
    mAlterSubscriptionIntervals = false;
}

// Subscriber sends the request with particular max-interval value:
// Validate client is not requesting max-interval < min-interval.
TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest9)
{
    auto sessionHandle                       = mpContext->GetSessionBobToAlice();
    uint32_t numSuccessCalls                 = 0;
    uint32_t numFailureCalls                 = 0;
    uint32_t numSubscriptionEstablishedCalls = 0;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&numSuccessCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        numSuccessCalls++;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&numFailureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        numFailureCalls++;
    };

    auto onSubscriptionEstablishedCb = [&numSubscriptionEstablishedCalls](const app::ReadClient & readClient,
                                                                          chip::SubscriptionId aSubscriptionId) {
        numSubscriptionEstablishedCalls++;
    };

    //
    // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination
    // callbacks.
    //
    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    //
    // Test the server-side application altering the subscription intervals.
    //
    mAlterSubscriptionIntervals = false;

    EXPECT_EQ(Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                  &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 5, 4,
                  onSubscriptionEstablishedCb, nullptr, true),
              CHIP_ERROR_INVALID_ARGUMENT);

    //
    // Failures won't get routed to us here since re-subscriptions are enabled by default in the Controller::SubscribeAttribute
    // implementation.
    //
    EXPECT_EQ(numSuccessCalls, 0u);
    EXPECT_EQ(numSubscriptionEstablishedCalls, 0u);
    EXPECT_EQ(mNumActiveSubscriptions, 0);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();

    EXPECT_EQ(mNumActiveSubscriptions, 0);

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
    mAlterSubscriptionIntervals = false;
}

/**
 * When the liveness timeout of a subscription to ICD is reached, the subscription will enter "InactiveICDSubscription" state, the
 * client should call "OnActiveModeNotification" to re-activate it again when the check-in message is received from the ICD.
 */
TEST_F(TestRead, TestSubscribe_OnActiveModeNotification)
{
    auto sessionHandle = mpContext->GetSessionBobToAlice();

    mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive);

    {
        TestResubscriptionCallback callback;
        app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), callback,
                                   app::ReadClient::InteractionType::Subscribe);

        callback.mScheduleLITResubscribeImmediately = false;
        callback.SetReadClient(&readClient);

        app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice());

        // Read full wildcard paths, repeat twice to ensure chunking.
        app::AttributePathParams attributePathParams[1];
        readPrepareParams.mpAttributePathParamsList    = attributePathParams;
        readPrepareParams.mAttributePathParamsListSize = ArraySize(attributePathParams);
        attributePathParams[0].mEndpointId             = kTestEndpointId;
        attributePathParams[0].mClusterId              = app::Clusters::UnitTesting::Id;
        attributePathParams[0].mAttributeId            = app::Clusters::UnitTesting::Attributes::Boolean::Id;

        constexpr uint16_t maxIntervalCeilingSeconds = 1;

        readPrepareParams.mMaxIntervalCeilingSeconds = maxIntervalCeilingSeconds;
        readPrepareParams.mIsPeerLIT                 = true;

        auto err = readClient.SendAutoResubscribeRequest(std::move(readPrepareParams));
        EXPECT_EQ(err, CHIP_NO_ERROR);

        //
        // Drive servicing IO till we have established a subscription.
        //
        mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000),
                                               [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; });
        EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1);
        EXPECT_EQ(callback.mOnError, 0);
        EXPECT_EQ(callback.mOnResubscriptionsAttempted, 0);
        chip::app::ReadHandler * readHandler = app::InteractionModelEngine::GetInstance()->ActiveHandlerAt(0);

        uint16_t minInterval;
        uint16_t maxInterval;
        readHandler->GetReportingIntervals(minInterval, maxInterval);

        //
        // Disable packet transmission, and drive IO till timeout.
        // We won't actually request resubscription, since the device is not active, the resubscription will be deferred until
        // WakeUp() is called.
        //
        //
        mpContext->GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount;
        mpContext->GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)),
                                               [&]() { return false; });
        EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1);
        EXPECT_EQ(callback.mLastError, CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT);

        mpContext->GetLoopback().mNumMessagesToDrop = 0;
        callback.ClearCounters();
        app::InteractionModelEngine::GetInstance()->OnActiveModeNotification(
            ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex()));
        EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1);
        EXPECT_EQ(callback.mLastError, CHIP_ERROR_TIMEOUT);

        //
        // Drive servicing IO till we have established a subscription.
        //
        mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000),
                                               [&]() { return callback.mOnSubscriptionEstablishedCount == 1; });
        EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1);

        //
        // With re-sub enabled, we shouldn't have encountered any errors
        //
        EXPECT_EQ(callback.mOnError, 0);
        EXPECT_EQ(callback.mOnDone, 0);
    }

    mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

/**
 * When the liveness timeout of a subscription to ICD is reached, the subscription will enter "InactiveICDSubscription" state, the
 * client should call "OnActiveModeNotification" to re-activate it again when the check-in message is received from the ICD.
 */
TEST_F(TestRead, TestSubscribe_DynamicLITSubscription)
{
    auto sessionHandle = mpContext->GetSessionBobToAlice();

    mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive);

    {
        TestResubscriptionCallback callback;
        app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), callback,
                                   app::ReadClient::InteractionType::Subscribe);

        responseDirective                           = kSendDataResponse;
        callback.mScheduleLITResubscribeImmediately = false;
        callback.SetReadClient(&readClient);
        isLitIcd = false;

        app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice());

        // Read full wildcard paths, repeat twice to ensure chunking.
        app::AttributePathParams attributePathParams[1];
        readPrepareParams.mpAttributePathParamsList    = attributePathParams;
        readPrepareParams.mAttributePathParamsListSize = ArraySize(attributePathParams);
        attributePathParams[0].mEndpointId             = kRootEndpointId;
        attributePathParams[0].mClusterId              = app::Clusters::IcdManagement::Id;
        attributePathParams[0].mAttributeId            = app::Clusters::IcdManagement::Attributes::OperatingMode::Id;

        constexpr uint16_t maxIntervalCeilingSeconds = 1;

        readPrepareParams.mMaxIntervalCeilingSeconds = maxIntervalCeilingSeconds;
        readPrepareParams.mIsPeerLIT                 = true;

        auto err = readClient.SendAutoResubscribeRequest(std::move(readPrepareParams));
        EXPECT_EQ(err, CHIP_NO_ERROR);

        //
        // Drive servicing IO till we have established a subscription.
        //
        mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000),
                                               [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; });
        EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1);
        EXPECT_EQ(callback.mOnError, 0);
        EXPECT_EQ(callback.mOnResubscriptionsAttempted, 0);
        chip::app::ReadHandler * readHandler = app::InteractionModelEngine::GetInstance()->ActiveHandlerAt(0);

        uint16_t minInterval;
        uint16_t maxInterval;
        readHandler->GetReportingIntervals(minInterval, maxInterval);

        // Part 1. LIT -> SIT

        //
        // Disable packet transmission, and drive IO till timeout.
        // We won't actually request resubscription, since the device is not active, the resubscription will be deferred until
        // WakeUp() is called.
        //
        // Even if we set the peer type to LIT before, the report indicates that the peer is a SIT now, it will just bahve as
        // normal, non-LIT subscriptions.
        mpContext->GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount;
        mpContext->GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)),
                                               [&]() { return callback.mOnResubscriptionsAttempted != 0; });
        EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1);
        EXPECT_EQ(callback.mLastError, CHIP_ERROR_TIMEOUT);

        mpContext->GetLoopback().mNumMessagesToDrop = 0;
        callback.ClearCounters();

        //
        // Drive servicing IO till we have established a subscription.
        //
        mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000),
                                               [&]() { return callback.mOnSubscriptionEstablishedCount == 1; });
        EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1);

        //
        // With re-sub enabled, we shouldn't have encountered any errors
        //
        EXPECT_EQ(callback.mOnError, 0);
        EXPECT_EQ(callback.mOnDone, 0);

        // Part 2. SIT -> LIT

        isLitIcd = true;
        {
            app::AttributePathParams path;
            path.mEndpointId  = kRootEndpointId;
            path.mClusterId   = Clusters::IcdManagement::Id;
            path.mAttributeId = Clusters::IcdManagement::Attributes::OperatingMode::Id;
            app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetDirty(path);
        }
        callback.ClearCounters();
        mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(60), [&]() {
            return app::InteractionModelEngine::GetInstance()->GetNumDirtySubscriptions() == 0;
        });

        // When we received the update that OperatingMode becomes LIT, we automatically set the inner peer type to LIT ICD.
        mpContext->GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount;
        mpContext->GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)),
                                               [&]() { return false; });
        EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1);
        EXPECT_EQ(callback.mLastError, CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT);

        mpContext->GetLoopback().mNumMessagesToDrop = 0;
        callback.ClearCounters();
    }

    mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    isLitIcd = false;
}

/**
 * When the liveness timeout of a subscription to ICD is reached, the app can issue resubscription immediately
 * if they know the peer is active.
 */
TEST_F(TestRead, TestSubscribe_ImmediatelyResubscriptionForLIT)
{
    auto sessionHandle = mpContext->GetSessionBobToAlice();

    mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive);

    {
        TestResubscriptionCallback callback;
        app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), callback,
                                   app::ReadClient::InteractionType::Subscribe);

        callback.mScheduleLITResubscribeImmediately = true;
        callback.SetReadClient(&readClient);

        app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice());

        // Read full wildcard paths, repeat twice to ensure chunking.
        app::AttributePathParams attributePathParams[1];
        readPrepareParams.mpAttributePathParamsList    = attributePathParams;
        readPrepareParams.mAttributePathParamsListSize = ArraySize(attributePathParams);
        attributePathParams[0].mEndpointId             = kTestEndpointId;
        attributePathParams[0].mClusterId              = app::Clusters::UnitTesting::Id;
        attributePathParams[0].mAttributeId            = app::Clusters::UnitTesting::Attributes::Boolean::Id;

        constexpr uint16_t maxIntervalCeilingSeconds = 1;

        readPrepareParams.mMaxIntervalCeilingSeconds = maxIntervalCeilingSeconds;
        readPrepareParams.mIsPeerLIT                 = true;

        auto err = readClient.SendAutoResubscribeRequest(std::move(readPrepareParams));
        EXPECT_EQ(err, CHIP_NO_ERROR);

        //
        // Drive servicing IO till we have established a subscription.
        //
        mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000),
                                               [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; });
        EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1);
        EXPECT_EQ(callback.mOnError, 0);
        EXPECT_EQ(callback.mOnResubscriptionsAttempted, 0);
        chip::app::ReadHandler * readHandler = app::InteractionModelEngine::GetInstance()->ActiveHandlerAt(0);

        uint16_t minInterval;
        uint16_t maxInterval;
        readHandler->GetReportingIntervals(minInterval, maxInterval);

        //
        // Disable packet transmission, and drive IO till timeout.
        // We won't actually request resubscription, since the device is not active, the resubscription will be deferred until
        // WakeUp() is called.
        //
        //
        mpContext->GetLoopback().mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount;
        mpContext->GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxInterval)),
                                               [&]() { return callback.mLastError == CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT; });
        EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1);
        EXPECT_EQ(callback.mLastError, CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT);

        mpContext->GetLoopback().mNumMessagesToDrop = 0;
        callback.ClearCounters();

        //
        // Drive servicing IO till we have established a subscription.
        //
        mpContext->GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000),
                                               [&]() { return callback.mOnSubscriptionEstablishedCount == 1; });
        EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1);

        //
        // With re-sub enabled, we shouldn't have encountered any errors
        //
        EXPECT_EQ(callback.mOnError, 0);
        EXPECT_EQ(callback.mOnDone, 0);
    }

    mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestRead, TestReadHandler_MultipleReads)
{
    static_assert(CHIP_IM_MAX_REPORTS_IN_FLIGHT <= app::InteractionModelEngine::kReadHandlerPoolSize,
                  "How can we have more reports in flight than read handlers?");

    MultipleReadHelper(mpContext, CHIP_IM_MAX_REPORTS_IN_FLIGHT);

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
}

TEST_F(TestRead, TestReadHandler_OneSubscribeMultipleReads)
{
    static_assert(CHIP_IM_MAX_REPORTS_IN_FLIGHT <= app::InteractionModelEngine::kReadHandlerPoolSize,
                  "How can we have more reports in flight than read handlers?");
    static_assert(CHIP_IM_MAX_REPORTS_IN_FLIGHT > 1, "We won't do any reads");

    SubscribeThenReadHelper(mpContext, 1, CHIP_IM_MAX_REPORTS_IN_FLIGHT - 1);

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
}

TEST_F(TestRead, TestReadHandler_TwoSubscribesMultipleReads)
{
    static_assert(CHIP_IM_MAX_REPORTS_IN_FLIGHT <= app::InteractionModelEngine::kReadHandlerPoolSize,
                  "How can we have more reports in flight than read handlers?");
    static_assert(CHIP_IM_MAX_REPORTS_IN_FLIGHT > 2, "We won't do any reads");

    SubscribeThenReadHelper(mpContext, 2, CHIP_IM_MAX_REPORTS_IN_FLIGHT - 2);

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
}

void TestRead::SubscribeThenReadHelper(TestContext * apCtx, size_t aSubscribeCount, size_t aReadCount)
{
    auto sessionHandle                       = apCtx->GetSessionBobToAlice();
    uint32_t numSuccessCalls                 = 0;
    uint32_t numSubscriptionEstablishedCalls = 0;

    uint32_t numReadSuccessCalls = 0;
    uint32_t numReadFailureCalls = 0;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&numSuccessCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        numSuccessCalls++;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        //
        // We shouldn't be encountering any failures in this test.
        //
        EXPECT_TRUE(false);
    };

    auto onSubscriptionEstablishedCb = [&numSubscriptionEstablishedCalls, &apCtx, aSubscribeCount, aReadCount, &numReadSuccessCalls,
                                        &numReadFailureCalls](const app::ReadClient & readClient,
                                                              chip::SubscriptionId aSubscriptionId) {
        numSubscriptionEstablishedCalls++;
        if (numSubscriptionEstablishedCalls == aSubscribeCount)
        {
            MultipleReadHelperInternal(apCtx, aReadCount, numReadSuccessCalls, numReadFailureCalls);
        }
    };

    for (size_t i = 0; i < aSubscribeCount; ++i)
    {
        EXPECT_EQ(Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                      &apCtx->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10,
                      onSubscriptionEstablishedCb, nullptr, false, true),
                  CHIP_NO_ERROR);
    }

    apCtx->DrainAndServiceIO();

    EXPECT_EQ(numSuccessCalls, aSubscribeCount);
    EXPECT_EQ(numSubscriptionEstablishedCalls, aSubscribeCount);
    EXPECT_EQ(numReadSuccessCalls, aReadCount);
    EXPECT_EQ(numReadFailureCalls, 0u);
}

// The guts of MultipleReadHelper which take references to the success/failure
// counts to modify and assume the consumer will be spinning the event loop.
void TestRead::MultipleReadHelperInternal(TestContext * apCtx, size_t aReadCount, uint32_t & aNumSuccessCalls,
                                          uint32_t & aNumFailureCalls)
{
    EXPECT_EQ(aNumSuccessCalls, 0u);
    EXPECT_EQ(aNumFailureCalls, 0u);

    auto sessionHandle = apCtx->GetSessionBobToAlice();

    responseDirective = kSendDataResponse;

    uint16_t firstExpectedResponse = totalReadCount + 1;

    auto onFailureCb = [&aNumFailureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        aNumFailureCalls++;

        EXPECT_EQ(attributePath, nullptr);
    };

    for (size_t i = 0; i < aReadCount; ++i)
    {
        auto onSuccessCb = [&aNumSuccessCalls, firstExpectedResponse, i](const app::ConcreteDataAttributePath & attributePath,
                                                                         const auto & dataResponse) {
            EXPECT_EQ(dataResponse, firstExpectedResponse + i);
            aNumSuccessCalls++;
        };

        EXPECT_EQ(Controller::ReadAttribute<Clusters::UnitTesting::Attributes::Int16u::TypeInfo>(
                      &apCtx->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb),
                  CHIP_NO_ERROR);
    }
}

void TestRead::MultipleReadHelper(TestContext * apCtx, size_t aReadCount)
{
    uint32_t numSuccessCalls = 0;
    uint32_t numFailureCalls = 0;

    MultipleReadHelperInternal(apCtx, aReadCount, numSuccessCalls, numFailureCalls);

    apCtx->DrainAndServiceIO();

    EXPECT_EQ(numSuccessCalls, aReadCount);
    EXPECT_EQ(numFailureCalls, 0u);
}

TEST_F(TestRead, TestReadHandler_MultipleSubscriptionsWithDataVersionFilter)
{
    auto sessionHandle                       = mpContext->GetSessionBobToAlice();
    uint32_t numSuccessCalls                 = 0;
    uint32_t numSubscriptionEstablishedCalls = 0;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&numSuccessCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        EXPECT_TRUE(attributePath.mDataVersion.HasValue() && attributePath.mDataVersion.Value() == kDataVersion);
        numSuccessCalls++;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        //
        // We shouldn't be encountering any failures in this test.
        //
        EXPECT_TRUE(false);
    };

    auto onSubscriptionEstablishedCb = [&numSubscriptionEstablishedCalls](const app::ReadClient & readClient,
                                                                          chip::SubscriptionId aSubscriptionId) {
        numSubscriptionEstablishedCalls++;
    };

    //
    // Try to issue parallel subscriptions that will exceed the value for app::InteractionModelEngine::kReadHandlerPoolSize.
    // If heap allocation is correctly setup, this should result in it successfully servicing more than the number
    // present in that define.
    //
    chip::Optional<chip::DataVersion> dataVersion(1);
    for (size_t i = 0; i < (app::InteractionModelEngine::kReadHandlerPoolSize + 1); i++)
    {
        EXPECT_EQ(Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                      &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10,
                      onSubscriptionEstablishedCb, nullptr, false, true, dataVersion),
                  CHIP_NO_ERROR);
    }

    // There are too many messages and the test (gcc_debug, which includes many sanity checks) will be quite slow. Note: report
    // engine is using ScheduleWork which cannot be handled by DrainAndServiceIO correctly.
    mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(30), [&]() {
        return numSubscriptionEstablishedCalls == (app::InteractionModelEngine::kReadHandlerPoolSize + 1) &&
            numSuccessCalls == (app::InteractionModelEngine::kReadHandlerPoolSize + 1);
    });

    ChipLogError(Zcl, "Success call cnt: %" PRIu32 " (expect %" PRIu32 ") subscription cnt: %" PRIu32 " (expect %" PRIu32 ")",
                 numSuccessCalls, uint32_t(app::InteractionModelEngine::kReadHandlerPoolSize + 1), numSubscriptionEstablishedCalls,
                 uint32_t(app::InteractionModelEngine::kReadHandlerPoolSize + 1));

    EXPECT_EQ(numSuccessCalls, (app::InteractionModelEngine::kReadHandlerPoolSize + 1));
    EXPECT_EQ(numSubscriptionEstablishedCalls, (app::InteractionModelEngine::kReadHandlerPoolSize + 1));
    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestRead, TestReadHandlerResourceExhaustion_MultipleReads)
{
    auto sessionHandle       = mpContext->GetSessionBobToAlice();
    uint32_t numSuccessCalls = 0;
    uint32_t numFailureCalls = 0;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&numSuccessCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        numSuccessCalls++;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&numFailureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        numFailureCalls++;

        EXPECT_EQ(aError, CHIP_IM_GLOBAL_STATUS(Busy));
        EXPECT_EQ(attributePath, nullptr);
    };

    app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForReads(0);
    app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(true);

    EXPECT_EQ(Controller::ReadAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                  &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb),
              CHIP_NO_ERROR);

    mpContext->DrainAndServiceIO();

    app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForReads(-1);
    app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(false);
    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();

    EXPECT_EQ(numSuccessCalls, 0u);
    EXPECT_EQ(numFailureCalls, 1u);

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestRead, TestReadFabricScopedWithoutFabricFilter)
{
    /**
     *  TODO: we cannot implement the e2e read tests w/ fabric filter since the test session has only one session, and the
     * ReadSingleClusterData is not the one in real applications. We should be able to move some logic out of the ember library and
     * make it possible to have more fabrics in test setup so we can have a better test coverage.
     *
     *  NOTE: Based on the TODO above, the test is testing two separate logics:
     *   - When a fabric filtered read request is received, the server is able to pass the required fabric index to the response
     * encoder.
     *   - When a fabric filtered read request is received, the response encoder is able to encode the attribute correctly.
     */
    auto sessionHandle      = mpContext->GetSessionBobToAlice();
    bool onSuccessCbInvoked = false, onFailureCbInvoked = false;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&onSuccessCbInvoked](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        size_t len = 0;

        EXPECT_EQ(dataResponse.ComputeSize(&len), CHIP_NO_ERROR);
        EXPECT_GT(len, 1u);

        onSuccessCbInvoked = true;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&onFailureCbInvoked](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        onFailureCbInvoked = true;
    };

    Controller::ReadAttribute<Clusters::UnitTesting::Attributes::ListFabricScoped::TypeInfo>(
        &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, false /* fabric filtered */);

    mpContext->DrainAndServiceIO();

    EXPECT_TRUE(onSuccessCbInvoked && !onFailureCbInvoked);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u);
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestRead, TestReadFabricScopedWithFabricFilter)
{
    /**
     *  TODO: we cannot implement the e2e read tests w/ fabric filter since the test session has only one session, and the
     * ReadSingleClusterData is not the one in real applications. We should be able to move some logic out of the ember library and
     * make it possible to have more fabrics in test setup so we can have a better test coverage.
     *
     *  NOTE: Based on the TODO above, the test is testing two separate logics:
     *   - When a fabric filtered read request is received, the server is able to pass the required fabric index to the response
     * encoder.
     *   - When a fabric filtered read request is received, the response encoder is able to encode the attribute correctly.
     */
    auto sessionHandle      = mpContext->GetSessionBobToAlice();
    bool onSuccessCbInvoked = false, onFailureCbInvoked = false;

    responseDirective = kSendDataResponse;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&onSuccessCbInvoked](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        size_t len = 0;

        EXPECT_EQ(dataResponse.ComputeSize(&len), CHIP_NO_ERROR);
        EXPECT_EQ(len, 1u);

        // TODO: Uncomment the following code after we have fabric support in unit tests.
        /*
        auto iter = dataResponse.begin();
        if (iter.Next())
        {
            auto & item = iter.GetValue();
            EXPECT_EQ(item.fabricIndex, 1);
        }
        */
        onSuccessCbInvoked = true;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&onFailureCbInvoked](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        onFailureCbInvoked = true;
    };

    Controller::ReadAttribute<Clusters::UnitTesting::Attributes::ListFabricScoped::TypeInfo>(
        &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, true /* fabric filtered */);

    mpContext->DrainAndServiceIO();

    EXPECT_TRUE(onSuccessCbInvoked && !onFailureCbInvoked);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u);
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

namespace SubscriptionPathQuotaHelpers {
class TestReadCallback : public app::ReadClient::Callback
{
public:
    TestReadCallback() {}
    void OnAttributeData(const app::ConcreteDataAttributePath & aPath, TLV::TLVReader * apData,
                         const app::StatusIB & aStatus) override
    {
        if (apData != nullptr)
        {
            mAttributeCount++;
        }
    }

    void OnDone(app::ReadClient *) override { mOnDone++; }

    void OnReportEnd() override { mOnReportEnd++; }

    void OnError(CHIP_ERROR aError) override
    {
        mOnError++;
        mLastError = aError;
    }

    void OnSubscriptionEstablished(SubscriptionId aSubscriptionId) override { mOnSubscriptionEstablishedCount++; }

    void ClearCounters()
    {
        mAttributeCount                 = 0;
        mOnReportEnd                    = 0;
        mOnSubscriptionEstablishedCount = 0;
        mOnDone                         = 0;
        mOnError                        = 0;
        mLastError                      = CHIP_NO_ERROR;
    }

    uint32_t mAttributeCount                 = 0;
    uint32_t mOnReportEnd                    = 0;
    uint32_t mOnSubscriptionEstablishedCount = 0;
    uint32_t mOnDone                         = 0;
    uint32_t mOnError                        = 0;
    CHIP_ERROR mLastError                    = CHIP_NO_ERROR;
};

class TestPerpetualListReadCallback : public app::ReadClient::Callback
{
public:
    TestPerpetualListReadCallback() {}
    void OnAttributeData(const app::ConcreteDataAttributePath & aPath, TLV::TLVReader * apData,
                         const app::StatusIB & aStatus) override
    {
        if (apData != nullptr)
        {
            reportsReceived++;
            app::AttributePathParams path;
            path.mEndpointId  = aPath.mEndpointId;
            path.mClusterId   = aPath.mClusterId;
            path.mAttributeId = aPath.mAttributeId;
            app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetDirty(path);
        }
    }

    void OnDone(chip::app::ReadClient *) override {}

    void ClearCounter() { reportsReceived = 0; }

    int32_t reportsReceived = 0;
};

void EstablishReadOrSubscriptions(const SessionHandle & sessionHandle, size_t numSubs, size_t pathPerSub,
                                  app::AttributePathParams path, app::ReadClient::InteractionType type,
                                  app::ReadClient::Callback * callback, std::vector<std::unique_ptr<app::ReadClient>> & readClients)
{
    std::vector<app::AttributePathParams> attributePaths(pathPerSub, path);

    app::ReadPrepareParams readParams(sessionHandle);
    readParams.mpAttributePathParamsList    = attributePaths.data();
    readParams.mAttributePathParamsListSize = pathPerSub;
    if (type == app::ReadClient::InteractionType::Subscribe)
    {
        readParams.mMaxIntervalCeilingSeconds = 1;
        readParams.mKeepSubscriptions         = true;
    }

    for (uint32_t i = 0; i < numSubs; i++)
    {
        std::unique_ptr<app::ReadClient> readClient =
            std::make_unique<app::ReadClient>(app::InteractionModelEngine::GetInstance(),
                                              app::InteractionModelEngine::GetInstance()->GetExchangeManager(), *callback, type);
        EXPECT_EQ(readClient->SendRequest(readParams), CHIP_NO_ERROR);
        readClients.push_back(std::move(readClient));
    }
}

} // namespace SubscriptionPathQuotaHelpers

TEST_F(TestRead, TestSubscribeAttributeDeniedNotExistPath)
{
    auto sessionHandle = mpContext->GetSessionBobToAlice();

    mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive);

    {
        SubscriptionPathQuotaHelpers::TestReadCallback callback;
        app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), callback,
                                   app::ReadClient::InteractionType::Subscribe);

        app::ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice());

        app::AttributePathParams attributePathParams[1];
        readPrepareParams.mpAttributePathParamsList    = attributePathParams;
        readPrepareParams.mAttributePathParamsListSize = ArraySize(attributePathParams);
        attributePathParams[0].mClusterId              = app::Clusters::UnitTesting::Id;
        attributePathParams[0].mAttributeId            = app::Clusters::UnitTesting::Attributes::ListStructOctetString::Id;

        //
        // Request a max interval that's very small to reduce time to discovering a liveness failure.
        //
        readPrepareParams.mMaxIntervalCeilingSeconds = 1;

        auto err = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();

        EXPECT_EQ(callback.mOnError, 1u);
        EXPECT_EQ(callback.mLastError, CHIP_IM_GLOBAL_STATUS(InvalidAction));
        EXPECT_EQ(callback.mOnDone, 1u);
    }

    mpContext->SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestRead, TestReadHandler_KillOverQuotaSubscriptions)
{
    // Note: We cannot use mpContext->DrainAndServiceIO() since the perpetual read will make DrainAndServiceIO never return.
    using namespace SubscriptionPathQuotaHelpers;
    auto sessionHandle = mpContext->GetSessionBobToAlice();

    const auto kExpectedParallelSubs =
        app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric * mpContext->GetFabricTable().FabricCount();
    const auto kExpectedParallelPaths = kExpectedParallelSubs * app::InteractionModelEngine::kMinSupportedPathsPerSubscription;

    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    // Here, we set up two background perpetual read requests to simulate parallel Read + Subscriptions.
    // We don't care about the data read, we only care about the existence of such read transactions.
    TestReadCallback readCallback;
    TestReadCallback readCallbackFabric2;
    TestPerpetualListReadCallback perpetualReadCallback;
    std::vector<std::unique_ptr<app::ReadClient>> readClients;

    EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, 1,
                                 app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, kPerpetualAttributeid),
                                 app::ReadClient::InteractionType::Read, &perpetualReadCallback, readClients);
    EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1,
                                 app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, kPerpetualAttributeid),
                                 app::ReadClient::InteractionType::Read, &perpetualReadCallback, readClients);
    mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
        return app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read) == 2;
    });
    // Ensure our read transactions are established.
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read), 2u);

    // Intentially establish subscriptions using exceeded resources.
    app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(false);
    //
    // We establish 1 subscription that exceeds the minimum supported paths (but is still established since the
    // target has sufficient resources), and kExpectedParallelSubs subscriptions that conform to the minimum
    // supported paths. This sets the stage to make it possible to test eviction of subscriptions that are in violation
    // of the minimum later below.
    //
    // Subscription A
    EstablishReadOrSubscriptions(
        mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription + 1,
        app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
        app::ReadClient::InteractionType::Subscribe, &readCallback, readClients);
    // Subscription B
    EstablishReadOrSubscriptions(
        mpContext->GetSessionBobToAlice(), kExpectedParallelSubs, app::InteractionModelEngine::kMinSupportedPathsPerSubscription,
        app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
        app::ReadClient::InteractionType::Subscribe, &readCallback, readClients);

    // There are too many messages and the test (gcc_debug, which includes many sanity checks) will be quite slow. Note: report
    // engine is using ScheduleWork which cannot be handled by DrainAndServiceIO correctly.
    mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
        return readCallback.mOnSubscriptionEstablishedCount == kExpectedParallelSubs + 1 &&
            readCallback.mAttributeCount ==
            kExpectedParallelSubs * app::InteractionModelEngine::kMinSupportedPathsPerSubscription +
                app::InteractionModelEngine::kMinSupportedPathsPerSubscription + 1;
    });

    EXPECT_EQ(readCallback.mAttributeCount,
              kExpectedParallelSubs * app::InteractionModelEngine::kMinSupportedPathsPerSubscription +
                  app::InteractionModelEngine::kMinSupportedPathsPerSubscription + 1);
    EXPECT_EQ(readCallback.mOnSubscriptionEstablishedCount, kExpectedParallelSubs + 1);

    // We have set up the environment for testing the evicting logic.
    // We now have a full stable of subscriptions setup AND we've artificially limited the capacity, creation of further
    // subscriptions will require the eviction of existing subscriptions, OR potential rejection of the subscription if it exceeds
    // minimas.
    app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(true);
    app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForSubscriptions(static_cast<int32_t>(kExpectedParallelSubs));
    app::InteractionModelEngine::GetInstance()->SetPathPoolCapacityForSubscriptions(static_cast<int32_t>(kExpectedParallelPaths));

    // Part 1: Test per subscription minimas.
    // Rejection of the subscription that exceeds minimas.
    {
        TestReadCallback callback;
        std::vector<std::unique_ptr<app::ReadClient>> outReadClient;
        EstablishReadOrSubscriptions(
            mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription + 1,
            app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
            app::ReadClient::InteractionType::Subscribe, &callback, outReadClient);

        mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return callback.mOnError == 1; });

        // Over-sized request after used all paths will receive Paths Exhausted status code.
        EXPECT_EQ(callback.mOnError, 1u);
        EXPECT_EQ(callback.mLastError, CHIP_IM_GLOBAL_STATUS(PathsExhausted));
    }

    // This next test validates that a compliant subscription request will kick out an existing subscription (arguably, the one that
    // was previously established with more paths than the limit per fabric)
    {
        EstablishReadOrSubscriptions(
            mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription,
            app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
            app::ReadClient::InteractionType::Subscribe, &readCallback, readClients);

        readCallback.ClearCounters();
        // Run until the new subscription got setup fully as viewed by the client.
        mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
            return readCallback.mOnSubscriptionEstablishedCount == 1 &&
                readCallback.mAttributeCount == app::InteractionModelEngine::kMinSupportedPathsPerSubscription;
        });

        // This read handler should evict some existing subscriptions for enough space.
        // Validate that the new subscription got setup fully as viewed by the client. And we will validate we handled this
        // subscription by evicting the correct subscriptions later.
        EXPECT_EQ(readCallback.mOnSubscriptionEstablishedCount, 1u);
        EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerSubscription);
    }

    // Validate we evicted the right subscription for handling the new subscription above.
    // We should used **exactly** all resources for subscriptions if we have evicted the correct subscription, and we validate the
    // number of used paths by mark all subscriptions as dirty, and count the number of received reports.
    {
        app::AttributePathParams path;
        path.mEndpointId  = kTestEndpointId;
        path.mClusterId   = Clusters::UnitTesting::Id;
        path.mAttributeId = Clusters::UnitTesting::Attributes::Int16u::Id;
        app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetDirty(path);
    }
    readCallback.ClearCounters();

    // Run until all subscriptions are clean.
    mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(60), [&]() {
        return app::InteractionModelEngine::GetInstance()->GetNumDirtySubscriptions() == 0;
    });

    // Before the above subscription, we have one subscription with kMinSupportedPathsPerSubscription + 1 paths, we should evict
    // that subscription before evicting any other subscriptions, which will result we used exactly kExpectedParallelPaths and have
    // exactly kExpectedParallelSubs.
    // We have exactly one subscription than uses more resources than others, so the interaction model must evict it first, and we
    // will have exactly kExpectedParallelPaths only when that subscription have been evicted. We use this indirect method to verify
    // the subscriptions since the read client won't shutdown until the timeout fired.
    EXPECT_EQ(readCallback.mAttributeCount, kExpectedParallelPaths);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Subscribe),
              static_cast<uint32_t>(kExpectedParallelSubs));

    // Part 2: Testing per fabric minimas.
    // Validate we have more than kMinSupportedSubscriptionsPerFabric subscriptions for testing per fabric minimas.
    EXPECT_GT(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Subscribe,
                                                                                   mpContext->GetAliceFabricIndex()),
              app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric);

    // The following check will trigger the logic in im to kill the read handlers that use more paths than the limit per fabric.
    {
        EstablishReadOrSubscriptions(
            mpContext->GetSessionAliceToBob(), app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric,
            app::InteractionModelEngine::kMinSupportedPathsPerSubscription,
            app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
            app::ReadClient::InteractionType::Subscribe, &readCallbackFabric2, readClients);

        // Run until we have established the subscriptions.
        mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
            return readCallbackFabric2.mOnSubscriptionEstablishedCount ==
                app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric &&
                readCallbackFabric2.mAttributeCount ==
                app::InteractionModelEngine::kMinSupportedPathsPerSubscription *
                    app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric;
        });

        // Verify the subscriptions are established successfully. We will check if we evicted the expected subscriptions later.
        EXPECT_EQ(readCallbackFabric2.mOnSubscriptionEstablishedCount,
                  app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric);
        EXPECT_EQ(readCallbackFabric2.mAttributeCount,
                  app::InteractionModelEngine::kMinSupportedPathsPerSubscription *
                      app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric);
    }

    // Validate the subscriptions are handled by evicting one or more subscriptions from Fabric A.
    {
        app::AttributePathParams path;
        path.mEndpointId  = kTestEndpointId;
        path.mClusterId   = Clusters::UnitTesting::Id;
        path.mAttributeId = Clusters::UnitTesting::Attributes::Int16u::Id;
        app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetDirty(path);
    }
    readCallback.ClearCounters();
    readCallbackFabric2.ClearCounters();

    // Run until all subscriptions are clean.
    mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(60), [&]() {
        return app::InteractionModelEngine::GetInstance()->GetNumDirtySubscriptions() == 0;
    });

    // Some subscriptions on fabric 1 should be evicted since fabric 1 is using more resources than the limits.
    EXPECT_EQ(readCallback.mAttributeCount,
              app::InteractionModelEngine::kMinSupportedPathsPerSubscription *
                  app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric);
    EXPECT_EQ(readCallbackFabric2.mAttributeCount,
              app::InteractionModelEngine::kMinSupportedPathsPerSubscription *
                  app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Subscribe,
                                                                                   mpContext->GetAliceFabricIndex()),
              app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Subscribe,
                                                                                   mpContext->GetBobFabricIndex()),
              app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric);

    // Ensure our read transactions are still alive.
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read), 2u);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    mpContext->DrainAndServiceIO();

    // Shutdown all clients
    readClients.clear();

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
    app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(false);
    app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForSubscriptions(-1);
    app::InteractionModelEngine::GetInstance()->SetPathPoolCapacityForSubscriptions(-1);
}

TEST_F(TestRead, TestReadHandler_KillOldestSubscriptions)
{
    using namespace SubscriptionPathQuotaHelpers;
    auto sessionHandle = mpContext->GetSessionBobToAlice();

    const auto kExpectedParallelSubs =
        app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric * mpContext->GetFabricTable().FabricCount();
    const auto kExpectedParallelPaths = kExpectedParallelSubs * app::InteractionModelEngine::kMinSupportedPathsPerSubscription;

    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    TestReadCallback readCallback;
    std::vector<std::unique_ptr<app::ReadClient>> readClients;

    app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(true);
    app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForSubscriptions(static_cast<int32_t>(kExpectedParallelSubs));
    app::InteractionModelEngine::GetInstance()->SetPathPoolCapacityForSubscriptions(static_cast<int32_t>(kExpectedParallelPaths));

    // This should just use all availbale resources.
    EstablishReadOrSubscriptions(
        mpContext->GetSessionBobToAlice(), kExpectedParallelSubs, app::InteractionModelEngine::kMinSupportedPathsPerSubscription,
        app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
        app::ReadClient::InteractionType::Subscribe, &readCallback, readClients);

    mpContext->DrainAndServiceIO();

    EXPECT_EQ(readCallback.mAttributeCount, kExpectedParallelSubs * app::InteractionModelEngine::kMinSupportedPathsPerSubscription);
    EXPECT_EQ(readCallback.mOnSubscriptionEstablishedCount, kExpectedParallelSubs);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), kExpectedParallelSubs);

    // The following check will trigger the logic in im to kill the read handlers that uses more paths than the limit per fabric.
    {
        TestReadCallback callback;
        std::vector<std::unique_ptr<app::ReadClient>> outReadClient;
        EstablishReadOrSubscriptions(
            mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription + 1,
            app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
            app::ReadClient::InteractionType::Subscribe, &callback, outReadClient);

        mpContext->DrainAndServiceIO();

        // Over-sized request after used all paths will receive Paths Exhausted status code.
        EXPECT_EQ(callback.mOnError, 1u);
        EXPECT_EQ(callback.mLastError, CHIP_IM_GLOBAL_STATUS(PathsExhausted));
    }

    // The following check will trigger the logic in im to kill the read handlers that uses more paths than the limit per fabric.
    {
        EstablishReadOrSubscriptions(
            mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription,
            app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
            app::ReadClient::InteractionType::Subscribe, &readCallback, readClients);
        readCallback.ClearCounters();

        mpContext->DrainAndServiceIO();

        // This read handler should evict some existing subscriptions for enough space
        EXPECT_EQ(readCallback.mOnSubscriptionEstablishedCount, 1u);
        EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerSubscription);
        EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(),
                  static_cast<size_t>(kExpectedParallelSubs));
    }

    {
        app::AttributePathParams path;
        path.mEndpointId  = kTestEndpointId;
        path.mClusterId   = Clusters::UnitTesting::Id;
        path.mAttributeId = Clusters::UnitTesting::Attributes::Int16u::Id;
        app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetDirty(path);
    }
    readCallback.ClearCounters();
    mpContext->DrainAndServiceIO();

    EXPECT_LE(readCallback.mAttributeCount, kExpectedParallelPaths);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    mpContext->DrainAndServiceIO();

    // Shutdown all clients
    readClients.clear();

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
    app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(false);
    app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForSubscriptions(-1);
    app::InteractionModelEngine::GetInstance()->SetPathPoolCapacityForSubscriptions(-1);
}

struct TestReadHandler_ParallelReads_TestCase_Parameters
{
    int ReadHandlerCapacity = -1;
    int PathPoolCapacity    = -1;
    int MaxFabrics          = -1;
};

static void TestReadHandler_ParallelReads_TestCase(TestContext * apContext,
                                                   const TestReadHandler_ParallelReads_TestCase_Parameters & params,
                                                   std::function<void()> body)
{
    app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(true);
    app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForReads(params.ReadHandlerCapacity);
    app::InteractionModelEngine::GetInstance()->SetConfigMaxFabrics(params.MaxFabrics);
    app::InteractionModelEngine::GetInstance()->SetPathPoolCapacityForReads(params.PathPoolCapacity);

    body();

    // Clean up
    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    apContext->DrainAndServiceIO();

    // Sanity check
    EXPECT_EQ(apContext->GetExchangeManager().GetNumActiveExchanges(), 0u);

    app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(false);
    app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForReads(-1);
    app::InteractionModelEngine::GetInstance()->SetConfigMaxFabrics(-1);
    app::InteractionModelEngine::GetInstance()->SetPathPoolCapacityForReads(-1);
}

TEST_F(TestRead, TestReadHandler_ParallelReads)
{
    // Note: We cannot use mpContext->DrainAndServiceIO() except at the end of each test case since the perpetual read transactions
    // will never end. Note: We use mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { CONDITION }); and
    // EXPECT_EQ( CONDITION ) to ensure the CONDITION is satisfied.
    using namespace SubscriptionPathQuotaHelpers;
    using Params = TestReadHandler_ParallelReads_TestCase_Parameters;

    auto sessionHandle = mpContext->GetSessionBobToAlice();

    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this);

    auto TestCase = [&](const TestReadHandler_ParallelReads_TestCase_Parameters & params, std::function<void()> body) {
        TestReadHandler_ParallelReads_TestCase(mpContext, params, body);
    };

    // Case 1.1: 2 reads used up the path pool (but not the ReadHandler pool), and one incoming oversized read request =>
    // PathsExhausted.
    TestCase(
        Params{
            .ReadHandlerCapacity = 3,
            .PathPoolCapacity    = 2 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 2,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback backgroundReadCallback1;
            TestPerpetualListReadCallback backgroundReadCallback2;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

            backgroundReadCallback1.ClearCounter();
            backgroundReadCallback2.ClearCounter();

            EstablishReadOrSubscriptions(
                mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The two subscriptions should still alive
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);
            // The new read request should be rejected
            EXPECT_NE(readCallback.mOnError, 0u);
            EXPECT_EQ(readCallback.mLastError, CHIP_IM_GLOBAL_STATUS(PathsExhausted));
        });

    // Case 1.2: 2 reads used up the ReadHandler pool (not the PathPool), and one incoming oversized read request => Busy.
    // Note: This Busy code comes from the check for fabric resource limit (see case 1.3).
    TestCase(
        Params{
            .ReadHandlerCapacity = 2,
            .PathPoolCapacity    = 2 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 2,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback backgroundReadCallback1;
            TestPerpetualListReadCallback backgroundReadCallback2;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

            backgroundReadCallback1.ClearCounter();
            backgroundReadCallback2.ClearCounter();

            EstablishReadOrSubscriptions(
                mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The two subscriptions should still alive
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);
            // The new read request should be rejected
            EXPECT_NE(readCallback.mOnError, 0u);
            EXPECT_EQ(readCallback.mLastError, CHIP_IM_GLOBAL_STATUS(Busy));
        });

    // Case 1.3.1: If we have enough resource, any read requests will be accepted (case for oversized read request).
    TestCase(
        Params{
            .ReadHandlerCapacity = 3,
            .PathPoolCapacity    = 3 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
            .MaxFabrics          = 2,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback backgroundReadCallback1;
            TestPerpetualListReadCallback backgroundReadCallback2;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

            EstablishReadOrSubscriptions(
                mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be accepted
            EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1);
            EXPECT_EQ(readCallback.mOnError, 0u);

            // The two subscriptions should still alive
            backgroundReadCallback1.ClearCounter();
            backgroundReadCallback2.ClearCounter();
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);
        });

    // Case 1.3.2: If we have enough resource, any read requests will be accepted (case for non-oversized read requests)
    TestCase(
        Params{
            .ReadHandlerCapacity = 3,
            .PathPoolCapacity    = 3 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
            .MaxFabrics          = 2,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback backgroundReadCallback1;
            TestPerpetualListReadCallback backgroundReadCallback2;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

            backgroundReadCallback1.ClearCounter();
            backgroundReadCallback2.ClearCounter();

            EstablishReadOrSubscriptions(
                mpContext->GetSessionAliceToBob(), 1, 1,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be accepted
            EXPECT_EQ(readCallback.mAttributeCount, 1u);
            EXPECT_EQ(readCallback.mOnError, 0u);

            // The two subscriptions should still alive
            backgroundReadCallback1.ClearCounter();
            backgroundReadCallback2.ClearCounter();
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);
        });

    // Case 2: 1 oversized read and one non-oversized read, and one incoming read request from __another__ fabric => accept by
    // evicting the oversized read request.
    TestCase(
        Params{
            .ReadHandlerCapacity = 2,
            .PathPoolCapacity    = 2 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 2,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback readCallbackForOversizedRead;
            TestPerpetualListReadCallback backgroundReadCallback;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &readCallbackForOversizedRead, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                                   [&]() { return readCallbackForOversizedRead.reportsReceived > 0; });

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                                   [&]() { return backgroundReadCallback.reportsReceived > 0; });

            EXPECT_TRUE(readCallbackForOversizedRead.reportsReceived > 0 && backgroundReadCallback.reportsReceived > 0);

            EstablishReadOrSubscriptions(
                mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be accepted.
            EXPECT_EQ(readCallback.mOnError, 0u);
            EXPECT_EQ(readCallback.mOnDone, 1u);
            EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest);

            // The oversized read handler should be evicted -> We should have one active read handler.
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 1u);

            backgroundReadCallback.ClearCounter();
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                                   [&]() { return backgroundReadCallback.reportsReceived > 0; });

            // We don't check the readCallbackForOversizedRead, since it cannot prove anything -- it can be 0 even when the
            // oversized read request is alive. We ensure this by checking (1) we have only one active read handler, (2) the one
            // active read handler is the non-oversized one.

            // The non-oversized read handler should not be evicted.
            EXPECT_GT(backgroundReadCallback.reportsReceived, 0);
        });

    // Case 2 (Repeat): we swapped the order of the oversized and non-oversized read handler to ensure we always evict the oversized
    // read handler regardless the order.
    TestCase(
        Params{
            .ReadHandlerCapacity = 2,
            .PathPoolCapacity    = 2 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 2,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback readCallbackForOversizedRead;
            TestPerpetualListReadCallback backgroundReadCallback;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                                   [&]() { return backgroundReadCallback.reportsReceived > 0; });

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &readCallbackForOversizedRead, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                                   [&]() { return readCallbackForOversizedRead.reportsReceived > 0; });

            EXPECT_TRUE(readCallbackForOversizedRead.reportsReceived > 0 && backgroundReadCallback.reportsReceived > 0);

            EstablishReadOrSubscriptions(
                mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be accepted.
            EXPECT_EQ(readCallback.mOnError, 0u);
            EXPECT_EQ(readCallback.mOnDone, 1u);
            EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest);

            // The oversized read handler should be evicted -> We should have one active read handler.
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 1u);

            backgroundReadCallback.ClearCounter();
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                                   [&]() { return backgroundReadCallback.reportsReceived > 0; });

            // We don't check the readCallbackForOversizedRead, since it cannot prove anything -- it can be 0 even when the
            // oversized read request is alive. We ensure this by checking (1) we have only one active read handler, (2) the one
            // active read handler is the non-oversized one.

            // The non-oversized read handler should not be evicted.
            EXPECT_GT(backgroundReadCallback.reportsReceived, 0);
        });

    // Case 3: one oversized read and one non-oversized read, the remaining path in PathPool is suffcient but the ReadHandler pool
    // is full, and one incoming (non-oversized) read request from __the same__ fabric => Reply Status::Busy without evicting any
    // read handlers.
    // Note: If the read handler pool is not full => We have enough resource for handling this request => Case 1.3.2
    TestCase(
        Params{
            .ReadHandlerCapacity = 2,
            .PathPoolCapacity    = 2 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 2,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback readCallbackForOversizedRead;
            TestPerpetualListReadCallback backgroundReadCallback;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &readCallbackForOversizedRead, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback.reportsReceived > 0 && readCallbackForOversizedRead.reportsReceived > 0;
            });

            EXPECT_TRUE(readCallbackForOversizedRead.reportsReceived > 0 && backgroundReadCallback.reportsReceived > 0);

            EstablishReadOrSubscriptions(
                mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be rejected.
            EXPECT_NE(readCallback.mOnError, 0u);
            EXPECT_EQ(readCallback.mLastError, CHIP_IM_GLOBAL_STATUS(Busy));

            // Ensure the two read transactions are not evicted.
            backgroundReadCallback.ClearCounter();
            readCallbackForOversizedRead.ClearCounter();
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return readCallbackForOversizedRead.reportsReceived > 0 && backgroundReadCallback.reportsReceived > 0;
            });
            EXPECT_TRUE(readCallbackForOversizedRead.reportsReceived > 0 && backgroundReadCallback.reportsReceived > 0);
        });

    // Case 4.1: 1 fabric is oversized, and one incoming read request from __another__ fabric => accept by evicting one read request
    // from the oversized fabric.
    // Note: When there are more than one candidate, we will evict the larger one first (case 2), and the younger one (this case).
    TestCase(
        Params{
            .ReadHandlerCapacity = 2,
            .PathPoolCapacity    = 2 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 2,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback backgroundReadCallback1;
            TestPerpetualListReadCallback backgroundReadCallback2;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                                   [&]() { return backgroundReadCallback1.reportsReceived > 0; });

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                                   [&]() { return backgroundReadCallback2.reportsReceived > 0; });
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

            backgroundReadCallback1.ClearCounter();
            backgroundReadCallback2.ClearCounter();

            EstablishReadOrSubscriptions(
                mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be rejected.
            EXPECT_EQ(readCallback.mOnError, 0u);
            EXPECT_EQ(readCallback.mOnDone, 1u);
            EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest);

            // One of the read requests from Bob to Alice should be evicted.
            // We should have only one 1 active read handler, since the transaction from Alice to Bob has finished already, and one
            // of two Bob to Alice transactions has been evicted.
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 1u);

            // Note: Younger read handler will be evicted.
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                                   [&]() { return backgroundReadCallback1.reportsReceived > 0; });
            EXPECT_GT(backgroundReadCallback1.reportsReceived, 0);
        });

    // Case 4.2: Like case 4.1, but now the over sized fabric contains one (older) oversized read request and one (younger)
    // non-oversized read request. We will evict the oversized one instead of the younger one.
    TestCase(
        Params{
            .ReadHandlerCapacity = 2,
            .PathPoolCapacity    = 2 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 2,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback backgroundReadCallback1;
            TestPerpetualListReadCallback backgroundReadCallback2;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                                   [&]() { return backgroundReadCallback1.reportsReceived > 0; });

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                                   [&]() { return backgroundReadCallback2.reportsReceived > 0; });
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

            backgroundReadCallback1.ClearCounter();
            backgroundReadCallback2.ClearCounter();

            EstablishReadOrSubscriptions(
                mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be rejected.
            EXPECT_EQ(readCallback.mOnError, 0u);
            EXPECT_EQ(readCallback.mOnDone, 1u);
            EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest);

            // One of the read requests from Bob to Alice should be evicted.
            // We should have only one 1 active read handler, since the transaction from Alice to Bob has finished already, and one
            // of two Bob to Alice transactions has been evicted.
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 1u);

            // Note: Larger read handler will be evicted before evicting the younger one.
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                                   [&]() { return backgroundReadCallback2.reportsReceived > 0; });
            EXPECT_GT(backgroundReadCallback2.reportsReceived, 0);
        });

    // The following tests are the cases of read transactions on PASE sessions.

    // Case 5.1: The device's fabric table is not full, PASE sessions are counted as a "valid" fabric and can evict existing read
    // transactions. (In the same algorithm as in Test Case 2)
    TestCase(
        Params{
            .ReadHandlerCapacity = 3,
            .PathPoolCapacity    = 3 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 3,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback backgroundReadCallback1;
            TestPerpetualListReadCallback backgroundReadCallback2;
            TestPerpetualListReadCallback backgroundReadCallback3;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback3, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0 &&
                    backgroundReadCallback3.reportsReceived > 0;
            });
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0 &&
                        backgroundReadCallback3.reportsReceived > 0);

            EstablishReadOrSubscriptions(
                mpContext->GetSessionCharlieToDavid(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be accepted.
            EXPECT_EQ(readCallback.mOnError, 0u);
            EXPECT_EQ(readCallback.mOnDone, 1u);
            EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest);
            // Should evict one read request from Bob fabric for enough resources.
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read,
                                                                                           mpContext->GetAliceFabricIndex()),
                      1u);
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read,
                                                                                           mpContext->GetBobFabricIndex()),
                      1u);
        });

    // Case 5.2: The device's fabric table is not full, PASE sessions are counted as a "valid" fabric and can evict existing read
    // transactions. (In the same algorithm as in Test Case 2)
    // Note: The difference between 5.1 and 5.2 is which fabric is oversized, 5.1 and 5.2 also ensures that we will only evict the
    // read handlers from oversized fabric.
    TestCase(
        Params{
            .ReadHandlerCapacity = 3,
            .PathPoolCapacity    = 3 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 3,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback backgroundReadCallback1;
            TestPerpetualListReadCallback backgroundReadCallback2;
            TestPerpetualListReadCallback backgroundReadCallback3;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback3, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0 &&
                    backgroundReadCallback3.reportsReceived > 0;
            });
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0 &&
                        backgroundReadCallback3.reportsReceived > 0);

            EstablishReadOrSubscriptions(
                mpContext->GetSessionCharlieToDavid(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be accepted.
            EXPECT_EQ(readCallback.mOnError, 0u);
            EXPECT_EQ(readCallback.mOnDone, 1u);
            EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest);
            // Should evict one read request from Bob fabric for enough resources.
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read,
                                                                                           mpContext->GetAliceFabricIndex()),
                      1u);
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read,
                                                                                           mpContext->GetBobFabricIndex()),
                      1u);
        });

    // Case 6: The device's fabric table is full, PASE sessions won't be counted as a valid fabric and cannot evict existing read
    // transactions. It will be rejected with Busy status code.
    TestCase(
        Params{
            .ReadHandlerCapacity = 3,
            .PathPoolCapacity    = 3 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 2,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback backgroundReadCallback1;
            TestPerpetualListReadCallback backgroundReadCallback2;
            TestPerpetualListReadCallback backgroundReadCallback3;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback3, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0 &&
                    backgroundReadCallback3.reportsReceived > 0;
            });
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0 &&
                        backgroundReadCallback3.reportsReceived > 0);

            EstablishReadOrSubscriptions(
                mpContext->GetSessionCharlieToDavid(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be rejected.
            EXPECT_EQ(readCallback.mOnError, 1u);
            EXPECT_EQ(readCallback.mLastError, CHIP_IM_GLOBAL_STATUS(Busy));
            // Should evict one read request from Bob fabric for enough resources.
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read,
                                                                                           mpContext->GetAliceFabricIndex()),
                      2u);
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read,
                                                                                           mpContext->GetBobFabricIndex()),
                      1u);
        });

    // Case 7: We will accept read transactions on PASE session when the fabric table is full but we have enough resources for it.
    // Note: The actual size is not important, since this read handler is accepted by the first if-clause in EnsureResourceForRead.
    TestCase(
        Params{
            .ReadHandlerCapacity = 3,
            .PathPoolCapacity    = 3 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 2,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback backgroundReadCallback1;
            TestPerpetualListReadCallback backgroundReadCallback2;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

            EstablishReadOrSubscriptions(
                mpContext->GetSessionCharlieToDavid(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);

            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be accepted.
            EXPECT_EQ(readCallback.mOnError, 0u);
            EXPECT_EQ(readCallback.mOnDone, 1u);
            EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest);
            // No read transactions should be evicted.
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read,
                                                                                           mpContext->GetAliceFabricIndex()),
                      1u);
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read,
                                                                                           mpContext->GetBobFabricIndex()),
                      1u);
        });

    // Case 8.1: If the fabric table on the device is full, read transactions on PASE session will always be evicted when another
    // read comeing in on one of the existing fabrics.
    TestCase(
        Params{
            .ReadHandlerCapacity = 2,
            .PathPoolCapacity    = 2 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 2,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback backgroundReadCallback1;
            TestPerpetualListReadCallback backgroundReadCallback2;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(mpContext->GetSessionCharlieToDavid(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

            EstablishReadOrSubscriptions(
                mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be accepted.
            EXPECT_EQ(readCallback.mOnError, 0u);
            EXPECT_EQ(readCallback.mOnDone, 1u);
            EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest);
            // Should evict the read request on PASE session for enough resources.
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read),
                      1u);
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read,
                                                                                           kUndefinedFabricIndex),
                      0u);
        });

    // Case 8.2: If the fabric table on the device is full, read transactions on PASE session will always be evicted when another
    // read comeing in on one of the existing fabrics.
    // Note: The difference between 8.1 and 8.2 is the whether the existing fabric is oversized.
    TestCase(
        Params{
            .ReadHandlerCapacity = 2,
            .PathPoolCapacity    = 2 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 2,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback backgroundReadCallback1;
            TestPerpetualListReadCallback backgroundReadCallback2;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(mpContext->GetSessionCharlieToDavid(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            EXPECT_TRUE(backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

            EstablishReadOrSubscriptions(
                mpContext->GetSessionBobToAlice(), 1, 1,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be accepted.
            EXPECT_EQ(readCallback.mOnError, 0u);
            EXPECT_EQ(readCallback.mOnDone, 1u);
            EXPECT_EQ(readCallback.mAttributeCount, 1u);
            // Should evict the read request on PASE session for enough resources.
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read),
                      1u);
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read,
                                                                                           kUndefinedFabricIndex),
                      0u);
        });

    // Case 9.1: If the fabric table on the device is not full, read transactions on PASE session will NOT be evicted when the
    // resources used by all PASE sessions ARE NOT exceeding the resources guaranteed to a normal fabric.
    TestCase(
        Params{
            .ReadHandlerCapacity = 3,
            .PathPoolCapacity    = 3 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 3,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback backgroundReadCallbackForPASESession;
            TestPerpetualListReadCallback backgroundReadCallback1;
            TestPerpetualListReadCallback backgroundReadCallback2;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(
                mpContext->GetSessionCharlieToDavid(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                app::ReadClient::InteractionType::Read, &backgroundReadCallbackForPASESession, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallbackForPASESession.reportsReceived > 0 && backgroundReadCallback1.reportsReceived > 0 &&
                    backgroundReadCallback2.reportsReceived > 0;
            });
            EXPECT_TRUE(backgroundReadCallbackForPASESession.reportsReceived > 0 && backgroundReadCallback1.reportsReceived > 0 &&
                        backgroundReadCallback2.reportsReceived > 0);

            EstablishReadOrSubscriptions(
                mpContext->GetSessionBobToAlice(), 1, 1,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be accepted.
            EXPECT_EQ(readCallback.mOnError, 0u);
            EXPECT_EQ(readCallback.mOnDone, 1u);
            EXPECT_EQ(readCallback.mAttributeCount, 1u);

            // The read handler on PASE session should not be evicted since the resources used by all PASE sessions are not
            // exceeding the resources guaranteed to a normal fabric.
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read),
                      2u);
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read,
                                                                                           kUndefinedFabricIndex),
                      1u);
        });

    // Case 9.2: If the fabric table on the device is not full, the read handlers from normal fabrics MAY be evicted before all read
    // transactions from PASE sessions are evicted.
    // Note: With this setup, the interaction model engine guarantees 2 read transactions and 2 * 9 = 18 paths on each fabric.
    TestCase(
        Params{
            .ReadHandlerCapacity = 6,
            .PathPoolCapacity    = 6 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 3,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback backgroundReadCallbackForPASESession;
            TestPerpetualListReadCallback backgroundReadCallback1;
            TestPerpetualListReadCallback backgroundReadCallback2;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(
                mpContext->GetSessionCharlieToDavid(), 3, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest - 1,
                app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read,
                &backgroundReadCallbackForPASESession, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionBobToAlice(), 3,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(
                           app::ReadHandler::InteractionType::Read) == 6;
            });
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read,
                                                                                           kUndefinedFabricIndex),
                      3u);

            // We have to evict one read transaction on PASE session and one read transaction on Alice's fabric.
            EstablishReadOrSubscriptions(
                mpContext->GetSessionAliceToBob(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be accepted.
            EXPECT_EQ(readCallback.mOnError, 0u);
            EXPECT_EQ(readCallback.mOnDone, 1u);
            EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest);

            // No more than one read handler on PASE session should be evicted exceeding the resources guaranteed to a normal
            // fabric. Note: We are using ">=" here since it is also acceptable if we choose to evict one read transaction from
            // Alice fabric.
            EXPECT_GE(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read),
                      4u);
            EXPECT_GE(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read,
                                                                                           kUndefinedFabricIndex),
                      2u);
        });

    // Case 10: If the fabric table on the device is full, we won't evict read requests from normal fabrics before we have evicted
    // ALL read requests from PASE sessions.
    TestCase(
        Params{
            .ReadHandlerCapacity = 4,
            .PathPoolCapacity    = 4 * app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
            .MaxFabrics          = 2,
        },
        [&]() {
            TestReadCallback readCallback;
            TestPerpetualListReadCallback backgroundReadCallbackForPASESession;
            TestPerpetualListReadCallback backgroundReadCallback1;
            TestPerpetualListReadCallback backgroundReadCallback2;
            std::vector<std::unique_ptr<app::ReadClient>> readClients;

            EstablishReadOrSubscriptions(
                mpContext->GetSessionCharlieToDavid(), 2, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest - 1,
                app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read,
                &backgroundReadCallbackForPASESession, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(mpContext->GetSessionAliceToBob(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallbackForPASESession.reportsReceived > 0 && backgroundReadCallback1.reportsReceived > 0 &&
                    backgroundReadCallback2.reportsReceived > 0 &&
                    app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read,
                                                                                         kUndefinedFabricIndex) == 2;
            });
            EXPECT_TRUE(backgroundReadCallbackForPASESession.reportsReceived > 0 && backgroundReadCallback1.reportsReceived > 0 &&
                        backgroundReadCallback2.reportsReceived > 0 &&
                        app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(
                            app::ReadHandler::InteractionType::Read, kUndefinedFabricIndex) == 2);

            // To handle this read request, we must evict both read transactions from the PASE session.
            EstablishReadOrSubscriptions(
                mpContext->GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);
            mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be accepted.
            EXPECT_EQ(readCallback.mOnError, 0u);
            EXPECT_EQ(readCallback.mOnDone, 1u);
            EXPECT_EQ(readCallback.mAttributeCount, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest);

            // The read handler on PASE session should be evicted, and the read transactions on a normal fabric should be untouched
            // although it is oversized.
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read),
                      2u);
            EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read,
                                                                                           kUndefinedFabricIndex),
                      0u);
        });

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    mpContext->DrainAndServiceIO();

    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
    app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(false);
    app::InteractionModelEngine::GetInstance()->SetConfigMaxFabrics(-1);
    app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForReads(-1);
    app::InteractionModelEngine::GetInstance()->SetPathPoolCapacityForReads(-1);
}

// Needs to be larger than our plausible path pool.
constexpr size_t sTooLargePathCount = 200;

TEST_F(TestRead, TestReadHandler_TooManyPaths)
{
    using namespace chip::app;

    chip::Messaging::ReliableMessageMgr * rm = mpContext->GetExchangeManager().GetReliableMessageMgr();
    // Shouldn't have anything in the retransmit table when starting the test.
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    auto * engine = InteractionModelEngine::GetInstance();
    engine->SetForceHandlerQuota(true);

    ReadPrepareParams readPrepareParams(mpContext->GetSessionBobToAlice());
    // Needs to be larger than our plausible path pool.
    chip::app::AttributePathParams attributePathParams[sTooLargePathCount];
    readPrepareParams.mpAttributePathParamsList    = attributePathParams;
    readPrepareParams.mAttributePathParamsListSize = ArraySize(attributePathParams);

    {
        MockInteractionModelApp delegate;
        EXPECT_EQ(delegate.mNumAttributeResponse, 0);
        EXPECT_FALSE(delegate.mReadError);
        ReadClient readClient(InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), delegate,
                              ReadClient::InteractionType::Read);

        CHIP_ERROR err = readClient.SendRequest(readPrepareParams);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();

        EXPECT_EQ(delegate.mNumAttributeResponse, 0);
        EXPECT_TRUE(delegate.mReadError);

        StatusIB status(delegate.mError);
        EXPECT_EQ(status.mStatus, Protocols::InteractionModel::Status::PathsExhausted);
    }

    EXPECT_EQ(engine->GetNumActiveReadClients(), 0u);
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
    engine->SetForceHandlerQuota(false);
}

TEST_F(TestRead, TestReadHandler_TwoParallelReadsSecondTooManyPaths)
{
    using namespace chip::app;

    chip::Messaging::ReliableMessageMgr * rm = mpContext->GetExchangeManager().GetReliableMessageMgr();
    // Shouldn't have anything in the retransmit table when starting the test.
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    auto * engine = InteractionModelEngine::GetInstance();
    engine->SetForceHandlerQuota(true);

    {
        MockInteractionModelApp delegate1;
        EXPECT_EQ(delegate1.mNumAttributeResponse, 0);
        EXPECT_FALSE(delegate1.mReadError);
        ReadClient readClient1(InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), delegate1,
                               ReadClient::InteractionType::Read);

        MockInteractionModelApp delegate2;
        EXPECT_EQ(delegate2.mNumAttributeResponse, 0);
        EXPECT_FALSE(delegate2.mReadError);
        ReadClient readClient2(InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), delegate2,
                               ReadClient::InteractionType::Read);

        ReadPrepareParams readPrepareParams1(mpContext->GetSessionBobToAlice());
        // Read full wildcard paths, repeat twice to ensure chunking.
        chip::app::AttributePathParams attributePathParams1[2];
        readPrepareParams1.mpAttributePathParamsList    = attributePathParams1;
        readPrepareParams1.mAttributePathParamsListSize = ArraySize(attributePathParams1);

        CHIP_ERROR err = readClient1.SendRequest(readPrepareParams1);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        ReadPrepareParams readPrepareParams2(mpContext->GetSessionBobToAlice());
        // Read full wildcard paths, repeat twice to ensure chunking.
        chip::app::AttributePathParams attributePathParams2[sTooLargePathCount];
        readPrepareParams2.mpAttributePathParamsList    = attributePathParams2;
        readPrepareParams2.mAttributePathParamsListSize = ArraySize(attributePathParams2);

        err = readClient2.SendRequest(readPrepareParams2);
        EXPECT_EQ(err, CHIP_NO_ERROR);

        mpContext->DrainAndServiceIO();

        EXPECT_NE(delegate1.mNumAttributeResponse, 0);
        EXPECT_FALSE(delegate1.mReadError);

        EXPECT_EQ(delegate2.mNumAttributeResponse, 0);
        EXPECT_TRUE(delegate2.mReadError);

        StatusIB status(delegate2.mError);
        EXPECT_EQ(status.mStatus, Protocols::InteractionModel::Status::PathsExhausted);
    }

    EXPECT_EQ(engine->GetNumActiveReadClients(), 0u);
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
    engine->SetForceHandlerQuota(false);
}

TEST_F(TestRead, TestReadAttribute_ManyDataValues)
{
    auto sessionHandle  = mpContext->GetSessionBobToAlice();
    size_t successCalls = 0;
    size_t failureCalls = 0;

    responseDirective = kSendManyDataResponses;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&successCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        EXPECT_TRUE(attributePath.mDataVersion.HasValue() && attributePath.mDataVersion.Value() == kDataVersion);

        EXPECT_TRUE(dataResponse);
        ++successCalls;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&failureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) { ++failureCalls; };

    Controller::ReadAttribute<Clusters::UnitTesting::Attributes::Boolean::TypeInfo>(&mpContext->GetExchangeManager(), sessionHandle,
                                                                                    kTestEndpointId, onSuccessCb, onFailureCb);

    mpContext->DrainAndServiceIO();

    EXPECT_EQ(successCalls, 1u);
    EXPECT_EQ(failureCalls, 0u);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u);
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestRead, TestReadAttribute_ManyDataValuesWrongPath)
{
    auto sessionHandle  = mpContext->GetSessionBobToAlice();
    size_t successCalls = 0;
    size_t failureCalls = 0;

    responseDirective = kSendManyDataResponsesWrongPath;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&successCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        EXPECT_TRUE(attributePath.mDataVersion.HasValue() && attributePath.mDataVersion.Value() == kDataVersion);

        EXPECT_TRUE(dataResponse);
        ++successCalls;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&failureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) { ++failureCalls; };

    Controller::ReadAttribute<Clusters::UnitTesting::Attributes::Boolean::TypeInfo>(&mpContext->GetExchangeManager(), sessionHandle,
                                                                                    kTestEndpointId, onSuccessCb, onFailureCb);

    mpContext->DrainAndServiceIO();

    EXPECT_EQ(successCalls, 0u);
    EXPECT_EQ(failureCalls, 1u);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u);
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestRead, TestReadAttribute_ManyErrors)
{
    auto sessionHandle  = mpContext->GetSessionBobToAlice();
    size_t successCalls = 0;
    size_t failureCalls = 0;

    responseDirective = kSendTwoDataErrors;

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onSuccessCb = [&successCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        EXPECT_TRUE(attributePath.mDataVersion.HasValue() && attributePath.mDataVersion.Value() == kDataVersion);

        EXPECT_TRUE(dataResponse);
        ++successCalls;
    };

    // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's
    // not safe to do so.
    auto onFailureCb = [&failureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) { ++failureCalls; };

    Controller::ReadAttribute<Clusters::UnitTesting::Attributes::Boolean::TypeInfo>(&mpContext->GetExchangeManager(), sessionHandle,
                                                                                    kTestEndpointId, onSuccessCb, onFailureCb);

    mpContext->DrainAndServiceIO();

    EXPECT_EQ(successCalls, 0u);
    EXPECT_EQ(failureCalls, 1u);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients(), 0u);
    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u);
    EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u);
}

//
// This validates the KeepSubscriptions flag by first setting up a valid subscription, then sending
// a subsequent SubcribeRequest with empty attribute AND event paths with KeepSubscriptions = false.
//
// This should evict the previous subscription before sending back an error.
//
TEST_F(TestRead, TestReadHandler_KeepSubscriptionTest)
{
    using namespace SubscriptionPathQuotaHelpers;

    TestReadCallback readCallback;
    app::AttributePathParams pathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id);

    app::ReadPrepareParams readParam(mpContext->GetSessionAliceToBob());
    readParam.mpAttributePathParamsList    = &pathParams;
    readParam.mAttributePathParamsListSize = 1;
    readParam.mMaxIntervalCeilingSeconds   = 1;
    readParam.mKeepSubscriptions           = false;

    std::unique_ptr<app::ReadClient> readClient = std::make_unique<app::ReadClient>(
        app::InteractionModelEngine::GetInstance(), app::InteractionModelEngine::GetInstance()->GetExchangeManager(), readCallback,
        app::ReadClient::InteractionType::Subscribe);
    EXPECT_EQ(readClient->SendRequest(readParam), CHIP_NO_ERROR);

    mpContext->DrainAndServiceIO();

    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 1u);

    ChipLogProgress(DataManagement, "Issue another subscription that will evict the first sub...");

    readParam.mAttributePathParamsListSize = 0;
    readClient                             = std::make_unique<app::ReadClient>(app::InteractionModelEngine::GetInstance(),
                                                   app::InteractionModelEngine::GetInstance()->GetExchangeManager(), readCallback,
                                                   app::ReadClient::InteractionType::Subscribe);
    EXPECT_EQ(readClient->SendRequest(readParam), CHIP_NO_ERROR);

    mpContext->DrainAndServiceIO();

    EXPECT_EQ(app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(), 0u);
    EXPECT_NE(readCallback.mOnError, 0u);
    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    mpContext->DrainAndServiceIO();
}

System::Clock::Timeout TestRead::ComputeSubscriptionTimeout(System::Clock::Seconds16 aMaxInterval)
{
    // Add 1000ms of slack to our max interval to make sure we hit the
    // subscription liveness timer.  100ms was tried in the past and is not
    // sufficient: our process can easily lose the timeslice for 100ms.
    const auto & ourMrpConfig = GetDefaultMRPConfig();
    auto publisherTransmissionTimeout =
        GetRetransmissionTimeout(ourMrpConfig.mActiveRetransTimeout, ourMrpConfig.mIdleRetransTimeout,
                                 System::SystemClock().GetMonotonicTimestamp(), ourMrpConfig.mActiveThresholdTime);

    return publisherTransmissionTimeout + aMaxInterval + System::Clock::Milliseconds32(1000);
}

} // namespace
