/*
 *
 *    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 "system/SystemClock.h"
#include "transport/SecureSession.h"
#include <app-common/zap-generated/cluster-objects.h>
#include <app/ClusterStateCache.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/support/ErrorStr.h>
#include <lib/support/UnitTestContext.h>
#include <lib/support/UnitTestRegistration.h>
#include <lib/support/logging/CHIPLogging.h>
#include <messaging/tests/MessagingContext.h>
#include <nlunit-test.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;

} // namespace

namespace chip {
namespace app {
CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescriptor, bool aIsFabricFiltered,
                                 const ConcreteReadAttributePath & aPath, AttributeReportIBs::Builder & aAttributeReports,
                                 AttributeValueEncoder::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));
            AttributeValueEncoder::AttributeEncodeState state =
                (apEncoderState == nullptr ? AttributeValueEncoder::AttributeEncodeState() : *apEncoderState);
            AttributeValueEncoder valueEncoder(aAttributeReports, aSubjectDescriptor.fabricIndex, path,
                                               kDataVersion /* data version */, 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)
        {
            AttributeValueEncoder::AttributeEncodeState state =
                (apEncoderState == nullptr ? AttributeValueEncoder::AttributeEncodeState() : *apEncoderState);
            AttributeValueEncoder valueEncoder(aAttributeReports, aSubjectDescriptor.fabricIndex, aPath,
                                               kDataVersion /* data version */, 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)
        {
            AttributeValueEncoder::AttributeEncodeState state =
                (apEncoderState == nullptr ? AttributeValueEncoder::AttributeEncodeState() : *apEncoderState);
            AttributeValueEncoder valueEncoder(aAttributeReports, aSubjectDescriptor.fabricIndex, aPath,
                                               kDataVersion /* data version */, aIsFabricFiltered, state);

            return valueEncoder.Encode(++totalReadCount);
        }
        if (aPath.mClusterId == kPerpetualClusterId ||
            (aPath.mClusterId == app::Clusters::UnitTesting::Id && aPath.mAttributeId == kPerpetualAttributeid))
        {
            AttributeValueEncoder::AttributeEncodeState state = AttributeValueEncoder::AttributeEncodeState();
            AttributeValueEncoder valueEncoder(aAttributeReports, aSubjectDescriptor.fabricIndex, aPath,
                                               kDataVersion /* data version */, 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;
            }
        }

        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().GetError());
        return attributeReport.EndOfAttributeReportIB().GetError();
    }

    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().GetError());
    }

    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;
}

} // namespace app
} // namespace chip

namespace {

class TestReadInteraction : public app::ReadHandler::ApplicationCallback
{
public:
    TestReadInteraction() {}

    static void TestReadAttributeResponse(nlTestSuite * apSuite, void * apContext);
    static void TestReadAttributeError(nlTestSuite * apSuite, void * apContext);
    static void TestReadAttributeTimeout(nlTestSuite * apSuite, void * apContext);
    static void TestSubscribeAttributeTimeout(nlTestSuite * apSuite, void * apContext);
    static void TestResubscribeAttributeTimeout(nlTestSuite * apSuite, void * apContext);
    static void TestReadEventResponse(nlTestSuite * apSuite, void * apContext);
    static void TestReadFabricScopedWithoutFabricFilter(nlTestSuite * apSuite, void * apContext);
    static void TestReadFabricScopedWithFabricFilter(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_MultipleSubscriptions(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_SubscriptionAppRejection(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_MultipleReads(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_OneSubscribeMultipleReads(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_TwoSubscribesMultipleReads(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_MultipleSubscriptionsWithDataVersionFilter(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_SubscriptionReportingIntervalsTest1(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_SubscriptionReportingIntervalsTest2(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_SubscriptionReportingIntervalsTest3(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_SubscriptionReportingIntervalsTest4(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_SubscriptionReportingIntervalsTest5(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_SubscriptionReportingIntervalsTest6(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_SubscriptionReportingIntervalsTest7(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_SubscriptionReportingIntervalsTest8(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_SubscriptionReportingIntervalsTest9(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandlerResourceExhaustion_MultipleReads(nlTestSuite * apSuite, void * apContext);
    static void TestReadSubscribeAttributeResponseWithCache(nlTestSuite * apSuite, void * apContext);
    static void TestReadSubscribeAttributeResponseWithVersionOnlyCache(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_KillOverQuotaSubscriptions(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_KillOldestSubscriptions(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_ParallelReads(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_TooManyPaths(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_TwoParallelReadsSecondTooManyPaths(nlTestSuite * apSuite, void * apContext);
    static void TestReadAttribute_ManyDataValues(nlTestSuite * apSuite, void * apContext);
    static void TestReadAttribute_ManyDataValuesWrongPath(nlTestSuite * apSuite, void * apContext);
    static void TestReadAttribute_ManyErrors(nlTestSuite * apSuite, void * apContext);
    static void TestSubscribeAttributeDeniedNotExistPath(nlTestSuite * apSuite, void * apContext);
    static void TestReadHandler_KeepSubscriptionTest(nlTestSuite * apSuite, void * apContext);

private:
    static uint16_t mMaxInterval;

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

        if (mAlterSubscriptionIntervals)
        {
            ReturnErrorOnFailure(aReadHandler.SetReportingIntervals(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(nlTestSuite * apSuite, TestContext & aCtx, 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(nlTestSuite * apSuite, TestContext & aCtx, 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(nlTestSuite * apSuite, TestContext & aCtx, 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;
};

uint16_t TestReadInteraction::mMaxInterval = 66;

TestReadInteraction gTestReadInteraction;

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;
};

void TestReadInteraction::TestReadAttributeResponse(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx       = *static_cast<TestContext *>(apContext);
    auto sessionHandle      = ctx.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 = [apSuite, &onSuccessCbInvoked](const app::ConcreteDataAttributePath & attributePath,
                                                      const auto & dataResponse) {
        uint8_t i = 0;
        NL_TEST_ASSERT(apSuite, attributePath.mDataVersion.HasValue() && attributePath.mDataVersion.Value() == kDataVersion);
        auto iter = dataResponse.begin();
        while (iter.Next())
        {
            auto & item = iter.GetValue();
            NL_TEST_ASSERT(apSuite, item.member1 == i);
            i++;
        }
        NL_TEST_ASSERT(apSuite, i == 4);
        NL_TEST_ASSERT(apSuite, 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>(
        &ctx.GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb);

    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, onSuccessCbInvoked && !onFailureCbInvoked);
    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients() == 0);
    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers() == 0);
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

void TestReadInteraction::TestReadSubscribeAttributeResponseWithCache(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx = *static_cast<TestContext *>(apContext);
    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(ctx.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(&gTestReadInteraction);

    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(), &ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

        ctx.DrainAndServiceIO();
        NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 6);
        NL_TEST_ASSERT(apSuite, !delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        NL_TEST_ASSERT(apSuite, cache.GetVersion(clusterPath1, version1) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(apSuite, !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(), &ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

        ctx.DrainAndServiceIO();
        NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 3);
        NL_TEST_ASSERT(apSuite, !delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        NL_TEST_ASSERT(apSuite, cache.GetVersion(clusterPath1, version1) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(apSuite, !version1.HasValue());
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));
        NL_TEST_ASSERT(apSuite, cache.GetVersion(clusterPath2, version2) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(apSuite, !version2.HasValue());

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

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

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            NL_TEST_ASSERT(apSuite, cache.Get(attributePath, reader) == CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            NL_TEST_ASSERT(apSuite, 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(), &ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

        ctx.DrainAndServiceIO();
        NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 2);
        NL_TEST_ASSERT(apSuite, !delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        NL_TEST_ASSERT(apSuite, cache.GetVersion(clusterPath1, version1) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(apSuite, !version1.HasValue());
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));
        NL_TEST_ASSERT(apSuite, cache.GetVersion(clusterPath2, version2) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(apSuite, !version2.HasValue());

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

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

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            NL_TEST_ASSERT(apSuite, cache.Get(attributePath, reader) == CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            NL_TEST_ASSERT(apSuite, 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(), &ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

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

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

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

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

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            NL_TEST_ASSERT(apSuite, cache.Get(attributePath, reader) == CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            NL_TEST_ASSERT(apSuite, 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(), &ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

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

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

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

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            NL_TEST_ASSERT(apSuite, cache.Get(attributePath, reader) == CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            NL_TEST_ASSERT(apSuite, 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(), &ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

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

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

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

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

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            NL_TEST_ASSERT(apSuite, cache.Get(attributePath, reader) == CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            NL_TEST_ASSERT(apSuite, 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(), &ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

        ctx.DrainAndServiceIO();
        NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 3);
        NL_TEST_ASSERT(apSuite, !delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        NL_TEST_ASSERT(apSuite, cache.GetVersion(clusterPath1, version1) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(apSuite, !version1.HasValue());
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));
        NL_TEST_ASSERT(apSuite, cache.GetVersion(clusterPath2, version2) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(apSuite, !version2.HasValue());

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

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

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            NL_TEST_ASSERT(apSuite, cache.Get(attributePath, reader) == CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            NL_TEST_ASSERT(apSuite, 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(), &ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

        ctx.DrainAndServiceIO();
        NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 3);
        NL_TEST_ASSERT(apSuite, !delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath1(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(3));
        NL_TEST_ASSERT(apSuite, cache.GetVersion(clusterPath1, version1) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(apSuite, !version1.HasValue());
        Optional<DataVersion> version2;
        app::ConcreteClusterPath clusterPath2(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));
        NL_TEST_ASSERT(apSuite, cache.GetVersion(clusterPath2, version2) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(apSuite, !version2.HasValue());

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

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

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            NL_TEST_ASSERT(apSuite, cache.Get(attributePath, reader) == CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            NL_TEST_ASSERT(apSuite, 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(), &ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

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

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

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

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

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            NL_TEST_ASSERT(apSuite, cache.Get(attributePath, reader) == CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            NL_TEST_ASSERT(apSuite, 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 no enough 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(), &ctx.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;
        readPrepareParams.mEventPathParamsListSize = 64;

        err = readClient.SendRequest(readPrepareParams);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

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

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

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

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

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            NL_TEST_ASSERT(apSuite, cache.Get(attributePath, reader) == CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            NL_TEST_ASSERT(apSuite, 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(), &ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

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

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

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

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

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

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(1));
            TLV::TLVReader reader;
            NL_TEST_ASSERT(apSuite, cache.Get(attributePath, reader) == CHIP_NO_ERROR);
            bool receivedAttribute1;
            reader.Get(receivedAttribute1);
            NL_TEST_ASSERT(apSuite, receivedAttribute1 == expectedAttribute1);
        }
        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            NL_TEST_ASSERT(apSuite, cache.Get(attributePath, reader) == CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            NL_TEST_ASSERT(apSuite, 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(C2, C3, C1) but no enough memory, finally partially rollback data version
    // filter with only C2. 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(), &ctx.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;
        readPrepareParams.mEventPathParamsListSize     = 62;
        err                                            = readClient.SendRequest(readPrepareParams);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

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

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

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

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

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

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

        {
            app::ConcreteAttributePath attributePath(chip::Test::kMockEndpoint2, chip::Test::MockClusterId(2),
                                                     chip::Test::MockAttributeId(2));
            TLV::TLVReader reader;
            NL_TEST_ASSERT(apSuite, cache.Get(attributePath, reader) == CHIP_NO_ERROR);
            int16_t receivedAttribute2;
            reader.Get(receivedAttribute2);
            NL_TEST_ASSERT(apSuite, 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(), &ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

        ctx.DrainAndServiceIO();
        NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 6);
        NL_TEST_ASSERT(apSuite, !delegate.mReadError);
        Optional<DataVersion> version1;
        app::ConcreteClusterPath clusterPath(chip::Test::kMockEndpoint3, chip::Test::MockClusterId(2));

        NL_TEST_ASSERT(apSuite, cache.GetVersion(clusterPath, version1) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(apSuite, version1.HasValue());

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

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

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

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

    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients() == 0);
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

void TestReadInteraction::TestReadSubscribeAttributeResponseWithVersionOnlyCache(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx = *static_cast<TestContext *>(apContext);
    CHIP_ERROR err    = CHIP_NO_ERROR;
    responseDirective = kSendDataResponse;

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

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

    // read of E2C2A* and E3C2A2. Expect cache E2C2 version
    {
        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

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

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

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

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

    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients() == 0);
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

void TestReadInteraction::TestReadEventResponse(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx       = *static_cast<TestContext *>(apContext);
    auto sessionHandle      = ctx.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 = [apSuite, &onSuccessCbInvoked](const app::EventHeader & eventHeader, const auto & EventResponse) {
        // TODO: Need to add check when IM event server integration completes
        IgnoreUnusedVariable(apSuite);
        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>(
        &ctx.GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, onDoneCb);

    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, !onFailureCbInvoked);
    NL_TEST_ASSERT(apSuite, onDoneCbInvoked);

    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients() == 0);
    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers() == 0);
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

void TestReadInteraction::TestReadAttributeError(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx       = *static_cast<TestContext *>(apContext);
    auto sessionHandle      = ctx.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, apSuite](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        NL_TEST_ASSERT(apSuite, aError.IsIMStatus() && app::StatusIB(aError).mStatus == Protocols::InteractionModel::Status::Busy);
        onFailureCbInvoked = true;
    };

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

    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, !onSuccessCbInvoked && onFailureCbInvoked);
    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients() == 0);
    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers() == 0);
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

void TestReadInteraction::TestReadAttributeTimeout(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx       = *static_cast<TestContext *>(apContext);
    auto sessionHandle      = ctx.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, apSuite](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        NL_TEST_ASSERT(apSuite, aError == CHIP_ERROR_TIMEOUT);
        onFailureCbInvoked = true;
    };

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

    ctx.ExpireSessionAliceToBob();

    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 1);

    ctx.ExpireSessionBobToAlice();

    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, !onSuccessCbInvoked && onFailureCbInvoked);

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers() == 0);

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

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

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;
        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;
    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.
//
//
void TestReadInteraction::TestResubscribeAttributeTimeout(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx  = *static_cast<TestContext *>(apContext);
    auto sessionHandle = ctx.GetSessionBobToAlice();

    ctx.SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive);

    {
        TestResubscriptionCallback callback;
        app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &ctx.GetExchangeManager(), callback,
                                   app::ReadClient::InteractionType::Subscribe);

        callback.SetReadClient(&readClient);

        app::ReadPrepareParams readPrepareParams(ctx.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));
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

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

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

        NL_TEST_ASSERT(apSuite, callback.mOnResubscriptionsAttempted == 1);
        NL_TEST_ASSERT(apSuite, callback.mLastError == CHIP_ERROR_TIMEOUT);

        ctx.GetLoopback().mNumMessagesToDrop = 0;
        callback.ClearCounters();

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

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

    ctx.SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

//
// 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.
//
void TestReadInteraction::TestSubscribeAttributeTimeout(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx  = *static_cast<TestContext *>(apContext);
    auto sessionHandle = ctx.GetSessionBobToAlice();

    ctx.SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive);

    {
        TestResubscriptionCallback callback;
        app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &ctx.GetExchangeManager(), callback,
                                   app::ReadClient::InteractionType::Subscribe);

        callback.SetReadClient(&readClient);

        app::ReadPrepareParams readPrepareParams(ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

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

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

        //
        // 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.
        //
        ctx.GetIOContext().DriveIOUntil(ComputeSubscriptionTimeout(System::Clock::Seconds16(maxIntervalCeilingSeconds)),
                                        [&]() { return callback.mOnError >= 1; });

        NL_TEST_ASSERT(apSuite, callback.mOnError == 1);
        NL_TEST_ASSERT(apSuite, callback.mLastError == CHIP_ERROR_TIMEOUT);
        NL_TEST_ASSERT(apSuite, callback.mOnDone == 1);
        NL_TEST_ASSERT(apSuite, callback.mOnResubscriptionsAttempted == 0);
    }

    ctx.SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
    ctx.GetLoopback().mNumMessagesToDrop = 0;
}

void TestReadInteraction::TestReadHandler_MultipleSubscriptions(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx                        = *static_cast<TestContext *>(apContext);
    auto sessionHandle                       = ctx.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 = [&apSuite](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        //
        // We shouldn't be encountering any failures in this test.
        //
        NL_TEST_ASSERT(apSuite, 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(&gTestReadInteraction);

    //
    // 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++)
    {
        NL_TEST_ASSERT(apSuite,
                       Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                           &ctx.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.
    ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(60), [&]() {
        return numSuccessCalls == (app::InteractionModelEngine::kReadHandlerPoolSize + 1) &&
            numSubscriptionEstablishedCalls == (app::InteractionModelEngine::kReadHandlerPoolSize + 1);
    });

    NL_TEST_ASSERT(apSuite, numSuccessCalls == (app::InteractionModelEngine::kReadHandlerPoolSize + 1));
    NL_TEST_ASSERT(apSuite, numSubscriptionEstablishedCalls == (app::InteractionModelEngine::kReadHandlerPoolSize + 1));
    NL_TEST_ASSERT(apSuite,
                   gTestReadInteraction.mNumActiveSubscriptions == (app::InteractionModelEngine::kReadHandlerPoolSize + 1));

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

    NL_TEST_ASSERT(apSuite, gTestReadInteraction.mNumActiveSubscriptions == 0);
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

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

void TestReadInteraction::TestReadHandler_SubscriptionAppRejection(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx                        = *static_cast<TestContext *>(apContext);
    auto sessionHandle                       = ctx.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(&gTestReadInteraction);

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

    NL_TEST_ASSERT(apSuite,
                   Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                       &ctx.GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10,
                       onSubscriptionEstablishedCb, nullptr, false, true) == CHIP_NO_ERROR);

    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, numSuccessCalls == 0);

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

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

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

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

// Subscriber sends the request with particular max-interval value:
// Max interval equal to client-requested min-interval.
void TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest1(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx                        = *static_cast<TestContext *>(apContext);
    auto sessionHandle                       = ctx.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, &apSuite](const app::ReadClient & readClient,
                                                                                    chip::SubscriptionId aSubscriptionId) {
        uint16_t minInterval = 0, maxInterval = 0;

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

        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

        NL_TEST_ASSERT(apSuite, minInterval == 5);
        NL_TEST_ASSERT(apSuite, maxInterval == 5);

        numSubscriptionEstablishedCalls++;
    };

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

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

    NL_TEST_ASSERT(apSuite,
                   Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                       &ctx.GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 5, 5,
                       onSubscriptionEstablishedCb, nullptr, true) == CHIP_NO_ERROR);

    ctx.DrainAndServiceIO();

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

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

    NL_TEST_ASSERT(apSuite, gTestReadInteraction.mNumActiveSubscriptions == 0);

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
    gTestReadInteraction.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.
void TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest2(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx                        = *static_cast<TestContext *>(apContext);
    auto sessionHandle                       = ctx.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, &apSuite](const app::ReadClient & readClient,
                                                                                    chip::SubscriptionId aSubscriptionId) {
        uint16_t minInterval = 0, maxInterval = 0;

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

        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

        NL_TEST_ASSERT(apSuite, minInterval == 0);
        NL_TEST_ASSERT(apSuite, maxInterval == 10);

        numSubscriptionEstablishedCalls++;
    };

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

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

    NL_TEST_ASSERT(apSuite,
                   Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                       &ctx.GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10,
                       onSubscriptionEstablishedCb, nullptr, true) == CHIP_NO_ERROR);

    ctx.DrainAndServiceIO();

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

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

    NL_TEST_ASSERT(apSuite, gTestReadInteraction.mNumActiveSubscriptions == 0);

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
    gTestReadInteraction.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).
void TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest3(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx                        = *static_cast<TestContext *>(apContext);
    auto sessionHandle                       = ctx.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, &apSuite](const app::ReadClient & readClient,
                                                                                    chip::SubscriptionId aSubscriptionId) {
        uint16_t minInterval = 0, maxInterval = 0;

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

        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

        NL_TEST_ASSERT(apSuite, minInterval == 0);
        NL_TEST_ASSERT(apSuite, maxInterval == 3000);

        numSubscriptionEstablishedCalls++;
    };

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

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

    ctx.DrainAndServiceIO();

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

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

    NL_TEST_ASSERT(apSuite, gTestReadInteraction.mNumActiveSubscriptions == 0);

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

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

// 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).
void TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest4(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx                        = *static_cast<TestContext *>(apContext);
    auto sessionHandle                       = ctx.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(&gTestReadInteraction);

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

    ctx.DrainAndServiceIO();

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

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

    NL_TEST_ASSERT(apSuite, gTestReadInteraction.mNumActiveSubscriptions == 0);

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

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

// 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.
void TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest5(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx                        = *static_cast<TestContext *>(apContext);
    auto sessionHandle                       = ctx.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, &apSuite](const app::ReadClient & readClient,
                                                                                    chip::SubscriptionId aSubscriptionId) {
        uint16_t minInterval = 0, maxInterval = 0;

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

        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

        NL_TEST_ASSERT(apSuite, minInterval == 0);
        NL_TEST_ASSERT(apSuite, maxInterval == 4000);

        numSubscriptionEstablishedCalls++;
    };

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

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

    NL_TEST_ASSERT(apSuite,
                   Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                       &ctx.GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 4000,
                       onSubscriptionEstablishedCb, nullptr, true) == CHIP_NO_ERROR);

    ctx.DrainAndServiceIO();

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

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

    NL_TEST_ASSERT(apSuite, gTestReadInteraction.mNumActiveSubscriptions == 0);

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
    gTestReadInteraction.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
void TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest6(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx                        = *static_cast<TestContext *>(apContext);
    auto sessionHandle                       = ctx.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, &apSuite](const app::ReadClient & readClient,
                                                                                    chip::SubscriptionId aSubscriptionId) {
        uint16_t minInterval = 0, maxInterval = 0;

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

        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

        NL_TEST_ASSERT(apSuite, minInterval == 0);
        NL_TEST_ASSERT(apSuite, maxInterval == 3000);

        numSubscriptionEstablishedCalls++;
    };

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

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

    ctx.DrainAndServiceIO();

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

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

    NL_TEST_ASSERT(apSuite, gTestReadInteraction.mNumActiveSubscriptions == 0);

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
    gTestReadInteraction.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
void TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest7(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx                        = *static_cast<TestContext *>(apContext);
    auto sessionHandle                       = ctx.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, &apSuite](const app::ReadClient & readClient,
                                                                                    chip::SubscriptionId aSubscriptionId) {
        uint16_t minInterval = 0, maxInterval = 0;

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

        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

        NL_TEST_ASSERT(apSuite, minInterval == 0);
        NL_TEST_ASSERT(apSuite, maxInterval == 3700);

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

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

    ctx.DrainAndServiceIO();

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

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

    NL_TEST_ASSERT(apSuite, gTestReadInteraction.mNumActiveSubscriptions == 0);

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

    app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback();
    gTestReadInteraction.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 larger than max interval. Disallowed
void TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest8(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx                        = *static_cast<TestContext *>(apContext);
    auto sessionHandle                       = ctx.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(&gTestReadInteraction);

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

    ctx.DrainAndServiceIO();

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

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

    NL_TEST_ASSERT(apSuite, gTestReadInteraction.mNumActiveSubscriptions == 0);

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

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

// Subscriber sends the request with particular max-interval value:
// Validate client is not requesting max-interval < min-interval.
void TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest9(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx                        = *static_cast<TestContext *>(apContext);
    auto sessionHandle                       = ctx.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(&gTestReadInteraction);

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

    NL_TEST_ASSERT(apSuite,
                   Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                       &ctx.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.
    //
    NL_TEST_ASSERT(apSuite, numSuccessCalls == 0);
    NL_TEST_ASSERT(apSuite, numSubscriptionEstablishedCalls == 0);
    NL_TEST_ASSERT(apSuite, gTestReadInteraction.mNumActiveSubscriptions == 0);

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

    NL_TEST_ASSERT(apSuite, gTestReadInteraction.mNumActiveSubscriptions == 0);

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

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

void TestReadInteraction::TestReadHandler_MultipleReads(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx = *static_cast<TestContext *>(apContext);

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

    MultipleReadHelper(apSuite, ctx, CHIP_IM_MAX_REPORTS_IN_FLIGHT);

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

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

void TestReadInteraction::TestReadHandler_OneSubscribeMultipleReads(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx = *static_cast<TestContext *>(apContext);

    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(apSuite, ctx, 1, CHIP_IM_MAX_REPORTS_IN_FLIGHT - 1);

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

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

void TestReadInteraction::TestReadHandler_TwoSubscribesMultipleReads(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx = *static_cast<TestContext *>(apContext);

    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(apSuite, ctx, 2, CHIP_IM_MAX_REPORTS_IN_FLIGHT - 2);

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

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

void TestReadInteraction::SubscribeThenReadHelper(nlTestSuite * apSuite, TestContext & aCtx, size_t aSubscribeCount,
                                                  size_t aReadCount)
{
    auto sessionHandle                       = aCtx.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 = [&apSuite](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        //
        // We shouldn't be encountering any failures in this test.
        //
        NL_TEST_ASSERT(apSuite, false);
    };

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

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

    aCtx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, numSuccessCalls == aSubscribeCount);
    NL_TEST_ASSERT(apSuite, numSubscriptionEstablishedCalls == aSubscribeCount);
    NL_TEST_ASSERT(apSuite, numReadSuccessCalls == aReadCount);
    NL_TEST_ASSERT(apSuite, numReadFailureCalls == 0);
}

// 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 TestReadInteraction::MultipleReadHelperInternal(nlTestSuite * apSuite, TestContext & aCtx, size_t aReadCount,
                                                     uint32_t & aNumSuccessCalls, uint32_t & aNumFailureCalls)
{
    NL_TEST_ASSERT(apSuite, aNumSuccessCalls == 0);
    NL_TEST_ASSERT(apSuite, aNumFailureCalls == 0);

    auto sessionHandle = aCtx.GetSessionBobToAlice();

    responseDirective = kSendDataResponse;

    uint16_t firstExpectedResponse = totalReadCount + 1;

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

        NL_TEST_ASSERT(apSuite, attributePath == nullptr);
    };

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

        NL_TEST_ASSERT(apSuite,
                       Controller::ReadAttribute<Clusters::UnitTesting::Attributes::Int16u::TypeInfo>(
                           &aCtx.GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb) == CHIP_NO_ERROR);
    }
}

void TestReadInteraction::MultipleReadHelper(nlTestSuite * apSuite, TestContext & aCtx, size_t aReadCount)
{
    uint32_t numSuccessCalls = 0;
    uint32_t numFailureCalls = 0;

    MultipleReadHelperInternal(apSuite, aCtx, aReadCount, numSuccessCalls, numFailureCalls);

    aCtx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, numSuccessCalls == aReadCount);
    NL_TEST_ASSERT(apSuite, numFailureCalls == 0);
}

void TestReadInteraction::TestReadHandler_MultipleSubscriptionsWithDataVersionFilter(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx                        = *static_cast<TestContext *>(apContext);
    auto sessionHandle                       = ctx.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 = [apSuite, &numSuccessCalls](const app::ConcreteDataAttributePath & attributePath,
                                                   const auto & dataResponse) {
        NL_TEST_ASSERT(apSuite, 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 = [&apSuite](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        //
        // We shouldn't be encountering any failures in this test.
        //
        NL_TEST_ASSERT(apSuite, 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++)
    {
        NL_TEST_ASSERT(apSuite,
                       Controller::SubscribeAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                           &ctx.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.
    ctx.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));

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

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

void TestReadInteraction::TestReadHandlerResourceExhaustion_MultipleReads(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx        = *static_cast<TestContext *>(apContext);
    auto sessionHandle       = ctx.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 = [&apSuite, &numFailureCalls](const app::ConcreteDataAttributePath * attributePath, CHIP_ERROR aError) {
        numFailureCalls++;

        NL_TEST_ASSERT(apSuite, aError == CHIP_IM_GLOBAL_STATUS(Busy));
        NL_TEST_ASSERT(apSuite, attributePath == nullptr);
    };

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

    NL_TEST_ASSERT(apSuite,
                   Controller::ReadAttribute<Clusters::UnitTesting::Attributes::ListStructOctetString::TypeInfo>(
                       &ctx.GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb) == CHIP_NO_ERROR);

    ctx.DrainAndServiceIO();

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

    NL_TEST_ASSERT(apSuite, numSuccessCalls == 0);
    NL_TEST_ASSERT(apSuite, numFailureCalls == 1);

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

void TestReadInteraction::TestReadFabricScopedWithoutFabricFilter(nlTestSuite * apSuite, void * apContext)
{
    /**
     *  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.
     */
    TestContext & ctx       = *static_cast<TestContext *>(apContext);
    auto sessionHandle      = ctx.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 = [apSuite, &onSuccessCbInvoked](const app::ConcreteDataAttributePath & attributePath,
                                                      const auto & dataResponse) {
        size_t len = 0;

        NL_TEST_ASSERT(apSuite, dataResponse.ComputeSize(&len) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(apSuite, len > 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>(
        &ctx.GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, false /* fabric filtered */);

    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, onSuccessCbInvoked && !onFailureCbInvoked);
    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients() == 0);
    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers() == 0);
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

void TestReadInteraction::TestReadFabricScopedWithFabricFilter(nlTestSuite * apSuite, void * apContext)
{
    /**
     *  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.
     */
    TestContext & ctx       = *static_cast<TestContext *>(apContext);
    auto sessionHandle      = ctx.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 = [apSuite, &onSuccessCbInvoked](const app::ConcreteDataAttributePath & attributePath,
                                                      const auto & dataResponse) {
        size_t len = 0;

        NL_TEST_ASSERT(apSuite, dataResponse.ComputeSize(&len) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(apSuite, len == 1);

        // TODO: Uncomment the following code after we have fabric support in unit tests.
        /*
        auto iter = dataResponse.begin();
        if (iter.Next())
        {
            auto & item = iter.GetValue();
            NL_TEST_ASSERT(apSuite, 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>(
        &ctx.GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, true /* fabric filtered */);

    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, onSuccessCbInvoked && !onFailureCbInvoked);
    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients() == 0);
    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers() == 0);
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

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(nlTestSuite * apSuite, 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);
        NL_TEST_ASSERT(apSuite, readClient->SendRequest(readParams) == CHIP_NO_ERROR);
        readClients.push_back(std::move(readClient));
    }
}

} // namespace SubscriptionPathQuotaHelpers

void TestReadInteraction::TestSubscribeAttributeDeniedNotExistPath(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx  = *static_cast<TestContext *>(apContext);
    auto sessionHandle = ctx.GetSessionBobToAlice();

    ctx.SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive);

    {
        SubscriptionPathQuotaHelpers::TestReadCallback callback;
        app::ReadClient readClient(app::InteractionModelEngine::GetInstance(), &ctx.GetExchangeManager(), callback,
                                   app::ReadClient::InteractionType::Subscribe);

        app::ReadPrepareParams readPrepareParams(ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

        ctx.DrainAndServiceIO();

        NL_TEST_ASSERT(apSuite, callback.mOnError == 1);
        NL_TEST_ASSERT(apSuite, callback.mLastError == CHIP_IM_GLOBAL_STATUS(InvalidAction));
        NL_TEST_ASSERT(apSuite, callback.mOnDone == 1);
    }

    ctx.SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

void TestReadInteraction::TestReadHandler_KillOverQuotaSubscriptions(nlTestSuite * apSuite, void * apContext)
{
    // Note: We cannot use ctx.DrainAndServiceIO() since the perpetual read will make DrainAndServiceIO never return.
    using namespace SubscriptionPathQuotaHelpers;
    TestContext & ctx  = *static_cast<TestContext *>(apContext);
    auto sessionHandle = ctx.GetSessionBobToAlice();

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

    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(&gTestReadInteraction);

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

    // 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(
        apSuite, ctx.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(
        apSuite, ctx.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.
    ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
        return readCallback.mOnSubscriptionEstablishedCount == kExpectedParallelSubs + 1 &&
            readCallback.mAttributeCount ==
            kExpectedParallelSubs * app::InteractionModelEngine::kMinSupportedPathsPerSubscription +
                app::InteractionModelEngine::kMinSupportedPathsPerSubscription + 1;
    });

    NL_TEST_ASSERT(apSuite,
                   readCallback.mAttributeCount ==
                       kExpectedParallelSubs * app::InteractionModelEngine::kMinSupportedPathsPerSubscription +
                           app::InteractionModelEngine::kMinSupportedPathsPerSubscription + 1);
    NL_TEST_ASSERT(apSuite, 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(
            apSuite, ctx.GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription + 1,
            app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
            app::ReadClient::InteractionType::Subscribe, &callback, outReadClient);

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

        // Over-sized request after used all paths will receive Paths Exhausted status code.
        NL_TEST_ASSERT(apSuite, callback.mOnError == 1);
        NL_TEST_ASSERT(apSuite, 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(
            apSuite, ctx.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.
        ctx.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.
        NL_TEST_ASSERT(apSuite, readCallback.mOnSubscriptionEstablishedCount == 1);
        NL_TEST_ASSERT(apSuite, 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.
    ctx.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.
    NL_TEST_ASSERT(apSuite, readCallback.mAttributeCount == kExpectedParallelPaths);
    NL_TEST_ASSERT(apSuite,
                   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.
    NL_TEST_ASSERT(apSuite,
                   app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(
                       app::ReadHandler::InteractionType::Subscribe, ctx.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(
            apSuite, ctx.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.
        ctx.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.
        NL_TEST_ASSERT(apSuite,
                       readCallbackFabric2.mOnSubscriptionEstablishedCount ==
                           app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric);
        NL_TEST_ASSERT(apSuite,
                       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.
    ctx.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.
    NL_TEST_ASSERT(apSuite,
                   readCallback.mAttributeCount ==
                       app::InteractionModelEngine::kMinSupportedPathsPerSubscription *
                           app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric);
    NL_TEST_ASSERT(apSuite,
                   readCallbackFabric2.mAttributeCount ==
                       app::InteractionModelEngine::kMinSupportedPathsPerSubscription *
                           app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric);
    NL_TEST_ASSERT(apSuite,
                   app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(
                       app::ReadHandler::InteractionType::Subscribe, ctx.GetAliceFabricIndex()) ==
                       app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric);
    NL_TEST_ASSERT(apSuite,
                   app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(
                       app::ReadHandler::InteractionType::Subscribe, ctx.GetBobFabricIndex()) ==
                       app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric);

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

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    ctx.DrainAndServiceIO();

    // Shutdown all clients
    readClients.clear();

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
    app::InteractionModelEngine::GetInstance()->SetForceHandlerQuota(false);
    app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForSubscriptions(-1);
    app::InteractionModelEngine::GetInstance()->SetPathPoolCapacityForSubscriptions(-1);
}

void TestReadInteraction::TestReadHandler_KillOldestSubscriptions(nlTestSuite * apSuite, void * apContext)
{
    using namespace SubscriptionPathQuotaHelpers;
    TestContext & ctx  = *static_cast<TestContext *>(apContext);
    auto sessionHandle = ctx.GetSessionBobToAlice();

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

    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(&gTestReadInteraction);

    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(
        apSuite, ctx.GetSessionBobToAlice(), kExpectedParallelSubs, app::InteractionModelEngine::kMinSupportedPathsPerSubscription,
        app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
        app::ReadClient::InteractionType::Subscribe, &readCallback, readClients);

    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite,
                   readCallback.mAttributeCount ==
                       kExpectedParallelSubs * app::InteractionModelEngine::kMinSupportedPathsPerSubscription);
    NL_TEST_ASSERT(apSuite, readCallback.mOnSubscriptionEstablishedCount == kExpectedParallelSubs);
    NL_TEST_ASSERT(apSuite, 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(
            apSuite, ctx.GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription + 1,
            app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
            app::ReadClient::InteractionType::Subscribe, &callback, outReadClient);

        ctx.DrainAndServiceIO();

        // Over-sized request after used all paths will receive Paths Exhausted status code.
        NL_TEST_ASSERT(apSuite, callback.mOnError == 1);
        NL_TEST_ASSERT(apSuite, 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(
            apSuite, ctx.GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerSubscription,
            app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
            app::ReadClient::InteractionType::Subscribe, &readCallback, readClients);
        readCallback.ClearCounters();

        ctx.DrainAndServiceIO();

        // This read handler should evict some existing subscriptions for enough space
        NL_TEST_ASSERT(apSuite, readCallback.mOnSubscriptionEstablishedCount == 1);
        NL_TEST_ASSERT(apSuite, readCallback.mAttributeCount == app::InteractionModelEngine::kMinSupportedPathsPerSubscription);
        NL_TEST_ASSERT(apSuite,
                       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();
    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, readCallback.mAttributeCount <= kExpectedParallelPaths);

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    ctx.DrainAndServiceIO();

    // Shutdown all clients
    readClients.clear();

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
    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(nlTestSuite * apSuite, void * apContext,
                                                   const TestReadHandler_ParallelReads_TestCase_Parameters & params,
                                                   std::function<void()> body)
{
    TestContext & ctx = *static_cast<TestContext *>(apContext);

    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();
    ctx.DrainAndServiceIO();

    // Sanity check
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);

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

void TestReadInteraction::TestReadHandler_ParallelReads(nlTestSuite * apSuite, void * apContext)
{
    // Note: We cannot use ctx.DrainAndServiceIO() except at the end of each test case since the perpetual read transactions will
    // never end.
    // Note: We use ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { CONDITION }); and NL_TEST_ASSERT(apSuite,
    // CONDITION ) to ensure the CONDITION is satisfied.
    using namespace SubscriptionPathQuotaHelpers;
    using Params = TestReadHandler_ParallelReads_TestCase_Parameters;

    TestContext & ctx  = *static_cast<TestContext *>(apContext);
    auto sessionHandle = ctx.GetSessionBobToAlice();

    app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(&gTestReadInteraction);

    auto TestCase = [&](const TestReadHandler_ParallelReads_TestCase_Parameters & params, std::function<void()> body) {
        TestReadHandler_ParallelReads_TestCase(apSuite, apContext, 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(apSuite, ctx.GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);

            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            NL_TEST_ASSERT(apSuite, backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

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

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

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

            // The two subscriptions should still alive
            NL_TEST_ASSERT(apSuite, backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);
            // The new read request should be rejected
            NL_TEST_ASSERT(apSuite, readCallback.mOnError != 0);
            NL_TEST_ASSERT(apSuite, 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(apSuite, ctx.GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);

            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            NL_TEST_ASSERT(apSuite, backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

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

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

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

            // The two subscriptions should still alive
            NL_TEST_ASSERT(apSuite, backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);
            // The new read request should be rejected
            NL_TEST_ASSERT(apSuite, readCallback.mOnError != 0);
            NL_TEST_ASSERT(apSuite, 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(apSuite, ctx.GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionAliceToBob(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);

            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            NL_TEST_ASSERT(apSuite, backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

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

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

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

            // The two subscriptions should still alive
            backgroundReadCallback1.ClearCounter();
            backgroundReadCallback2.ClearCounter();
            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            NL_TEST_ASSERT(apSuite, 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(apSuite, ctx.GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionAliceToBob(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);

            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            NL_TEST_ASSERT(apSuite, backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

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

            EstablishReadOrSubscriptions(
                apSuite, ctx.GetSessionAliceToBob(), 1, 1,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);

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

            // The new read request should be accepted
            NL_TEST_ASSERT(apSuite, readCallback.mAttributeCount == 1);
            NL_TEST_ASSERT(apSuite, readCallback.mOnError == 0);

            // The two subscriptions should still alive
            backgroundReadCallback1.ClearCounter();
            backgroundReadCallback2.ClearCounter();
            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            NL_TEST_ASSERT(apSuite, 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(apSuite, ctx.GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &readCallbackForOversizedRead, readClients);
            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                            [&]() { return readCallbackForOversizedRead.reportsReceived > 0; });

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

            NL_TEST_ASSERT(apSuite, readCallbackForOversizedRead.reportsReceived > 0 && backgroundReadCallback.reportsReceived > 0);

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

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

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

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

            backgroundReadCallback.ClearCounter();
            ctx.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.
            NL_TEST_ASSERT(apSuite, 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(apSuite, ctx.GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback, readClients);
            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                            [&]() { return backgroundReadCallback.reportsReceived > 0; });

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

            NL_TEST_ASSERT(apSuite, readCallbackForOversizedRead.reportsReceived > 0 && backgroundReadCallback.reportsReceived > 0);

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

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

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

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

            backgroundReadCallback.ClearCounter();
            ctx.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.
            NL_TEST_ASSERT(apSuite, 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(apSuite, ctx.GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &readCallbackForOversizedRead, readClients);
            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback.reportsReceived > 0 && readCallbackForOversizedRead.reportsReceived > 0;
            });

            NL_TEST_ASSERT(apSuite, readCallbackForOversizedRead.reportsReceived > 0 && backgroundReadCallback.reportsReceived > 0);

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

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

            // The new read request should be rejected.
            NL_TEST_ASSERT(apSuite, readCallback.mOnError != 0);
            NL_TEST_ASSERT(apSuite, readCallback.mLastError == CHIP_IM_GLOBAL_STATUS(Busy));

            // Ensure the two read transactions are not evicted.
            backgroundReadCallback.ClearCounter();
            readCallbackForOversizedRead.ClearCounter();
            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return readCallbackForOversizedRead.reportsReceived > 0 && backgroundReadCallback.reportsReceived > 0;
            });
            NL_TEST_ASSERT(apSuite, 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(apSuite, ctx.GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                            [&]() { return backgroundReadCallback1.reportsReceived > 0; });

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

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

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

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

            // The new read request should be rejected.
            NL_TEST_ASSERT(apSuite, readCallback.mOnError == 0);
            NL_TEST_ASSERT(apSuite, readCallback.mOnDone == 1);
            NL_TEST_ASSERT(apSuite, 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.
            NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers() == 1);

            // Note: Younger read handler will be evicted.
            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                            [&]() { return backgroundReadCallback1.reportsReceived > 0; });
            NL_TEST_ASSERT(apSuite, 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(apSuite, ctx.GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                            [&]() { return backgroundReadCallback1.reportsReceived > 0; });

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

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

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

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

            // The new read request should be rejected.
            NL_TEST_ASSERT(apSuite, readCallback.mOnError == 0);
            NL_TEST_ASSERT(apSuite, readCallback.mOnDone == 1);
            NL_TEST_ASSERT(apSuite, 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.
            NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers() == 1);

            // Note: Larger read handler will be evicted before evicting the younger one.
            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
                                            [&]() { return backgroundReadCallback2.reportsReceived > 0; });
            NL_TEST_ASSERT(apSuite, 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(apSuite, ctx.GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionAliceToBob(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback3, readClients);

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

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

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

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

    // 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(apSuite, ctx.GetSessionAliceToBob(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionAliceToBob(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionBobToAlice(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback3, readClients);

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

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

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

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

    // 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(apSuite, ctx.GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionAliceToBob(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback3, readClients);

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

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

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

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

    // 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(apSuite, ctx.GetSessionBobToAlice(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionAliceToBob(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);

            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            NL_TEST_ASSERT(apSuite, backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

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

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

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

    // 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(apSuite, ctx.GetSessionCharlieToDavid(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionAliceToBob(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            NL_TEST_ASSERT(apSuite, backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

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

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

    // 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(apSuite, ctx.GetSessionCharlieToDavid(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionAliceToBob(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0;
            });
            NL_TEST_ASSERT(apSuite, backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

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

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

    // 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(
                apSuite, ctx.GetSessionCharlieToDavid(), 1, 1, app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                app::ReadClient::InteractionType::Read, &backgroundReadCallbackForPASESession, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionAliceToBob(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionAliceToBob(), 1, 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return backgroundReadCallbackForPASESession.reportsReceived > 0 && backgroundReadCallback1.reportsReceived > 0 &&
                    backgroundReadCallback2.reportsReceived > 0;
            });
            NL_TEST_ASSERT(apSuite,
                           backgroundReadCallbackForPASESession.reportsReceived > 0 &&
                               backgroundReadCallback1.reportsReceived > 0 && backgroundReadCallback2.reportsReceived > 0);

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

            // The new read request should be accepted.
            NL_TEST_ASSERT(apSuite, readCallback.mOnError == 0);
            NL_TEST_ASSERT(apSuite, readCallback.mOnDone == 1);
            NL_TEST_ASSERT(apSuite, readCallback.mAttributeCount == 1);

            // 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.
            NL_TEST_ASSERT(
                apSuite,
                app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read) == 2);
            NL_TEST_ASSERT(apSuite,
                           app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(
                               app::ReadHandler::InteractionType::Read, kUndefinedFabricIndex) == 1);
        });

    // 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(
                apSuite, ctx.GetSessionCharlieToDavid(), 3, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest - 1,
                app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read,
                &backgroundReadCallbackForPASESession, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionBobToAlice(), 3,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() {
                return app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(
                           app::ReadHandler::InteractionType::Read) == 6;
            });
            NL_TEST_ASSERT(apSuite,
                           app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(
                               app::ReadHandler::InteractionType::Read, kUndefinedFabricIndex) == 3);

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

            // The new read request should be accepted.
            NL_TEST_ASSERT(apSuite, readCallback.mOnError == 0);
            NL_TEST_ASSERT(apSuite, readCallback.mOnDone == 1);
            NL_TEST_ASSERT(apSuite, 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.
            NL_TEST_ASSERT(
                apSuite,
                app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read) >= 4);
            NL_TEST_ASSERT(apSuite,
                           app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(
                               app::ReadHandler::InteractionType::Read, kUndefinedFabricIndex) >= 2);
        });

    // 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(
                apSuite, ctx.GetSessionCharlieToDavid(), 2, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest - 1,
                app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1), app::ReadClient::InteractionType::Read,
                &backgroundReadCallbackForPASESession, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionAliceToBob(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback1, readClients);
            EstablishReadOrSubscriptions(apSuite, ctx.GetSessionAliceToBob(), 1,
                                         app::InteractionModelEngine::kMinSupportedPathsPerReadRequest + 1,
                                         app::AttributePathParams(kTestEndpointId, kPerpetualClusterId, 1),
                                         app::ReadClient::InteractionType::Read, &backgroundReadCallback2, readClients);
            ctx.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;
            });
            NL_TEST_ASSERT(apSuite,
                           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(
                apSuite, ctx.GetSessionBobToAlice(), 1, app::InteractionModelEngine::kMinSupportedPathsPerReadRequest,
                app::AttributePathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id),
                app::ReadClient::InteractionType::Read, &readCallback, readClients);
            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.mOnDone != 0; });

            // The new read request should be accepted.
            NL_TEST_ASSERT(apSuite, readCallback.mOnError == 0);
            NL_TEST_ASSERT(apSuite, readCallback.mOnDone == 1);
            NL_TEST_ASSERT(apSuite, 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.
            NL_TEST_ASSERT(
                apSuite,
                app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(app::ReadHandler::InteractionType::Read) == 2);
            NL_TEST_ASSERT(apSuite,
                           app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers(
                               app::ReadHandler::InteractionType::Read, kUndefinedFabricIndex) == 0);
        });

    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
    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;

void TestReadInteraction::TestReadHandler_TooManyPaths(nlTestSuite * apSuite, void * apContext)
{
    using namespace chip::app;

    TestContext & ctx = *static_cast<TestContext *>(apContext);

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

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

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

    {
        MockInteractionModelApp delegate;
        NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 0);
        NL_TEST_ASSERT(apSuite, !delegate.mReadError);
        ReadClient readClient(InteractionModelEngine::GetInstance(), &ctx.GetExchangeManager(), delegate,
                              ReadClient::InteractionType::Read);

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

        ctx.DrainAndServiceIO();

        NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 0);
        NL_TEST_ASSERT(apSuite, delegate.mReadError);

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

    NL_TEST_ASSERT(apSuite, engine->GetNumActiveReadClients() == 0);
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
    engine->SetForceHandlerQuota(false);
}

void TestReadInteraction::TestReadHandler_TwoParallelReadsSecondTooManyPaths(nlTestSuite * apSuite, void * apContext)
{
    using namespace chip::app;

    TestContext & ctx = *static_cast<TestContext *>(apContext);

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

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

    {
        MockInteractionModelApp delegate1;
        NL_TEST_ASSERT(apSuite, delegate1.mNumAttributeResponse == 0);
        NL_TEST_ASSERT(apSuite, !delegate1.mReadError);
        ReadClient readClient1(InteractionModelEngine::GetInstance(), &ctx.GetExchangeManager(), delegate1,
                               ReadClient::InteractionType::Read);

        MockInteractionModelApp delegate2;
        NL_TEST_ASSERT(apSuite, delegate2.mNumAttributeResponse == 0);
        NL_TEST_ASSERT(apSuite, !delegate2.mReadError);
        ReadClient readClient2(InteractionModelEngine::GetInstance(), &ctx.GetExchangeManager(), delegate2,
                               ReadClient::InteractionType::Read);

        ReadPrepareParams readPrepareParams1(ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

        ReadPrepareParams readPrepareParams2(ctx.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);
        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

        ctx.DrainAndServiceIO();

        NL_TEST_ASSERT(apSuite, delegate1.mNumAttributeResponse != 0);
        NL_TEST_ASSERT(apSuite, !delegate1.mReadError);

        NL_TEST_ASSERT(apSuite, delegate2.mNumAttributeResponse == 0);
        NL_TEST_ASSERT(apSuite, delegate2.mReadError);

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

    NL_TEST_ASSERT(apSuite, engine->GetNumActiveReadClients() == 0);
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
    engine->SetForceHandlerQuota(false);
}

void TestReadInteraction::TestReadAttribute_ManyDataValues(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx   = *static_cast<TestContext *>(apContext);
    auto sessionHandle  = ctx.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 = [apSuite, &successCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        NL_TEST_ASSERT(apSuite, attributePath.mDataVersion.HasValue() && attributePath.mDataVersion.Value() == kDataVersion);

        NL_TEST_ASSERT(apSuite, 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>(&ctx.GetExchangeManager(), sessionHandle,
                                                                                    kTestEndpointId, onSuccessCb, onFailureCb);

    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, successCalls == 1);
    NL_TEST_ASSERT(apSuite, failureCalls == 0);
    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients() == 0);
    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers() == 0);
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

void TestReadInteraction::TestReadAttribute_ManyDataValuesWrongPath(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx   = *static_cast<TestContext *>(apContext);
    auto sessionHandle  = ctx.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 = [apSuite, &successCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        NL_TEST_ASSERT(apSuite, attributePath.mDataVersion.HasValue() && attributePath.mDataVersion.Value() == kDataVersion);

        NL_TEST_ASSERT(apSuite, 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>(&ctx.GetExchangeManager(), sessionHandle,
                                                                                    kTestEndpointId, onSuccessCb, onFailureCb);

    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, successCalls == 0);
    NL_TEST_ASSERT(apSuite, failureCalls == 1);
    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients() == 0);
    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers() == 0);
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

void TestReadInteraction::TestReadAttribute_ManyErrors(nlTestSuite * apSuite, void * apContext)
{
    TestContext & ctx   = *static_cast<TestContext *>(apContext);
    auto sessionHandle  = ctx.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 = [apSuite, &successCalls](const app::ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
        NL_TEST_ASSERT(apSuite, attributePath.mDataVersion.HasValue() && attributePath.mDataVersion.Value() == kDataVersion);

        NL_TEST_ASSERT(apSuite, 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>(&ctx.GetExchangeManager(), sessionHandle,
                                                                                    kTestEndpointId, onSuccessCb, onFailureCb);

    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, successCalls == 0);
    NL_TEST_ASSERT(apSuite, failureCalls == 1);
    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadClients() == 0);
    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers() == 0);
    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

//
// 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.
//
void TestReadInteraction::TestReadHandler_KeepSubscriptionTest(nlTestSuite * apSuite, void * apContext)
{
    using namespace SubscriptionPathQuotaHelpers;

    TestContext & ctx = *static_cast<TestContext *>(apContext);
    TestReadCallback readCallback;
    app::AttributePathParams pathParams(kTestEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Attributes::Int16u::Id);

    app::ReadPrepareParams readParam(ctx.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);
    NL_TEST_ASSERT(apSuite, readClient->SendRequest(readParam) == CHIP_NO_ERROR);

    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers() == 1);

    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);
    NL_TEST_ASSERT(apSuite, readClient->SendRequest(readParam) == CHIP_NO_ERROR);

    ctx.DrainAndServiceIO();

    NL_TEST_ASSERT(apSuite, app::InteractionModelEngine::GetInstance()->GetNumActiveReadHandlers() == 0);
    NL_TEST_ASSERT(apSuite, readCallback.mOnError != 0);
    app::InteractionModelEngine::GetInstance()->ShutdownActiveReads();
    ctx.DrainAndServiceIO();
}

System::Clock::Timeout TestReadInteraction::ComputeSubscriptionTimeout(System::Clock::Seconds16 aMaxInterval)
{
    // Add 50ms of slack to our max interval to make sure we hit the
    // subscription liveness timer.
    const auto & ourMrpConfig = GetDefaultMRPConfig();
    auto publisherTransmissionTimeout =
        GetRetransmissionTimeout(ourMrpConfig.mActiveRetransTimeout, ourMrpConfig.mIdleRetransTimeout,
                                 System::SystemClock().GetMonotonicTimestamp(), Transport::kMinActiveTime);

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

// clang-format off
const nlTest sTests[] =
{
    NL_TEST_DEF("TestReadAttributeResponse", TestReadInteraction::TestReadAttributeResponse),
    NL_TEST_DEF("TestReadEventResponse", TestReadInteraction::TestReadEventResponse),
    NL_TEST_DEF("TestReadAttributeError", TestReadInteraction::TestReadAttributeError),
    NL_TEST_DEF("TestReadFabricScopedWithoutFabricFilter", TestReadInteraction::TestReadFabricScopedWithoutFabricFilter),
    NL_TEST_DEF("TestReadFabricScopedWithFabricFilter", TestReadInteraction::TestReadFabricScopedWithFabricFilter),
    NL_TEST_DEF("TestReadHandler_MultipleSubscriptions", TestReadInteraction::TestReadHandler_MultipleSubscriptions),
    NL_TEST_DEF("TestReadHandler_SubscriptionAppRejection", TestReadInteraction::TestReadHandler_SubscriptionAppRejection),
    NL_TEST_DEF("TestReadHandler_MultipleSubscriptionsWithDataVersionFilter", TestReadInteraction::TestReadHandler_MultipleSubscriptionsWithDataVersionFilter),
    NL_TEST_DEF("TestReadHandler_MultipleReads", TestReadInteraction::TestReadHandler_MultipleReads),
    NL_TEST_DEF("TestReadHandler_OneSubscribeMultipleReads", TestReadInteraction::TestReadHandler_OneSubscribeMultipleReads),
    NL_TEST_DEF("TestReadHandler_TwoSubscribesMultipleReads", TestReadInteraction::TestReadHandler_TwoSubscribesMultipleReads),
    NL_TEST_DEF("TestReadHandlerResourceExhaustion_MultipleReads", TestReadInteraction::TestReadHandlerResourceExhaustion_MultipleReads),
    NL_TEST_DEF("TestReadAttributeTimeout", TestReadInteraction::TestReadAttributeTimeout),
    NL_TEST_DEF("TestReadHandler_SubscriptionReportingIntervalsTest1", TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest1),
    NL_TEST_DEF("TestReadHandler_SubscriptionReportingIntervalsTest2", TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest2),
    NL_TEST_DEF("TestReadHandler_SubscriptionReportingIntervalsTest3", TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest3),
    NL_TEST_DEF("TestReadHandler_SubscriptionReportingIntervalsTest4", TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest4),
    NL_TEST_DEF("TestReadHandler_SubscriptionReportingIntervalsTest5", TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest5),
    NL_TEST_DEF("TestReadHandler_SubscriptionReportingIntervalsTest6", TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest6),
    NL_TEST_DEF("TestReadHandler_SubscriptionReportingIntervalsTest7", TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest7),
    NL_TEST_DEF("TestReadHandler_SubscriptionReportingIntervalsTest8", TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest8),
    NL_TEST_DEF("TestReadHandler_SubscriptionReportingIntervalsTest9", TestReadInteraction::TestReadHandler_SubscriptionReportingIntervalsTest9),
        NL_TEST_DEF("TestReadSubscribeAttributeResponseWithVersionOnlyCache", TestReadInteraction::TestReadSubscribeAttributeResponseWithVersionOnlyCache),
    NL_TEST_DEF("TestReadSubscribeAttributeResponseWithCache", TestReadInteraction::TestReadSubscribeAttributeResponseWithCache),
    NL_TEST_DEF("TestReadHandler_KillOverQuotaSubscriptions", TestReadInteraction::TestReadHandler_KillOverQuotaSubscriptions),
    NL_TEST_DEF("TestReadHandler_KillOldestSubscriptions", TestReadInteraction::TestReadHandler_KillOldestSubscriptions),
    NL_TEST_DEF("TestReadHandler_ParallelReads", TestReadInteraction::TestReadHandler_ParallelReads),
    NL_TEST_DEF("TestReadHandler_TooManyPaths", TestReadInteraction::TestReadHandler_TooManyPaths),
    NL_TEST_DEF("TestReadHandler_TwoParallelReadsSecondTooManyPaths", TestReadInteraction::TestReadHandler_TwoParallelReadsSecondTooManyPaths),
    NL_TEST_DEF("TestReadAttribute_ManyDataValues", TestReadInteraction::TestReadAttribute_ManyDataValues),
    NL_TEST_DEF("TestReadAttribute_ManyDataValuesWrongPath", TestReadInteraction::TestReadAttribute_ManyDataValuesWrongPath),
    NL_TEST_DEF("TestReadAttribute_ManyErrors", TestReadInteraction::TestReadAttribute_ManyErrors),
    NL_TEST_DEF("TestSubscribeAttributeDeniedNotExistPath", TestReadInteraction::TestSubscribeAttributeDeniedNotExistPath),
    NL_TEST_DEF("TestResubscribeAttributeTimeout", TestReadInteraction::TestResubscribeAttributeTimeout),
    NL_TEST_DEF("TestSubscribeAttributeTimeout", TestReadInteraction::TestSubscribeAttributeTimeout),
    NL_TEST_DEF("TestReadHandler_KeepSubscriptionTest", TestReadInteraction::TestReadHandler_KeepSubscriptionTest),
    NL_TEST_SENTINEL()
};
// clang-format on

// clang-format off
nlTestSuite sSuite =
{
    "TestRead",
    &sTests[0],
    TestContext::Initialize,
    TestContext::Finalize
};
// clang-format on

} // namespace

int TestReadInteractionTest()
{
    return chip::ExecuteTestsWithContext<TestContext>(&sSuite);
}

CHIP_REGISTER_TEST_SUITE(TestReadInteractionTest)
