/*
 *
 *    Copyright (c) 2020-2021 Project CHIP Authors
 *    Copyright (c) 2016-2017 Nest Labs, Inc.
 *
 *    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.
 */

/**
 *    @file
 *      This file implements a unit test suite for
 *      <tt>chip::System::PacketBuffer</tt>, a class that provides
 *      structure for network packet buffer management.
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif

#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <utility>
#include <vector>

#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/UnitTestContext.h>
#include <lib/support/UnitTestRegistration.h>
#include <platform/CHIPDeviceLayer.h>
#include <system/SystemPacketBuffer.h>

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#include <lwip/init.h>
#include <lwip/tcpip.h>
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#include <nlunit-test.h>

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#if (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0)
#define PBUF_TYPE(pbuf) (pbuf)->type
#else // (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0)
#define PBUF_TYPE(pbuf) (pbuf)->type_internal
#endif // (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0)
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

using ::chip::Encoding::PacketBufferWriter;
using ::chip::System::PacketBuffer;
using ::chip::System::PacketBufferHandle;

#if !CHIP_SYSTEM_CONFIG_USE_LWIP
using ::chip::System::pbuf;
#endif

// Utility functions.

#define TO_LWIP_PBUF(x) (reinterpret_cast<struct pbuf *>(reinterpret_cast<void *>(x)))
#define OF_LWIP_PBUF(x) (reinterpret_cast<PacketBuffer *>(reinterpret_cast<void *>(x)))

namespace {
void ScrambleData(uint8_t * start, uint16_t length)
{
    for (uint16_t i = 0; i < length; ++i)
        ++start[i];
}
} // namespace

/*
 * An instance of this class created for the test suite.
 * It is a friend class of `PacketBuffer` and `PacketBufferHandle` because some tests
 * use or check private methods or properties.
 */
class PacketBufferTest
{
public:
    struct TestContext
    {
        const uint16_t * const reserved_sizes;
        size_t reserved_size_count;
        const uint16_t * const lengths;
        size_t length_count;
        PacketBufferTest * test;
    };

    static int TestSetup(void * inContext);
    static int TestTeardown(void * inContext);
    static int TestInitialize(void * inContext);
    static int TestTerminate(void * inContext);

    static void CheckNew(nlTestSuite * inSuite, void * inContext);
    static void CheckStart(nlTestSuite * inSuite, void * inContext);
    static void CheckSetStart(nlTestSuite * inSuite, void * inContext);
    static void CheckDataLength(nlTestSuite * inSuite, void * inContext);
    static void CheckSetDataLength(nlTestSuite * inSuite, void * inContext);
    static void CheckTotalLength(nlTestSuite * inSuite, void * inContext);
    static void CheckMaxDataLength(nlTestSuite * inSuite, void * inContext);
    static void CheckAvailableDataLength(nlTestSuite * inSuite, void * inContext);
    static void CheckReservedSize(nlTestSuite * inSuite, void * inContext);
    static void CheckHasChainedBuffer(nlTestSuite * inSuite, void * inContext);
    static void CheckAddToEnd(nlTestSuite * inSuite, void * inContext);
    static void CheckPopHead(nlTestSuite * inSuite, void * inContext);
    static void CheckCompactHead(nlTestSuite * inSuite, void * inContext);
    static void CheckConsumeHead(nlTestSuite * inSuite, void * inContext);
    static void CheckConsume(nlTestSuite * inSuite, void * inContext);
    static void CheckEnsureReservedSize(nlTestSuite * inSuite, void * inContext);
    static void CheckAlignPayload(nlTestSuite * inSuite, void * inContext);
    static void CheckNext(nlTestSuite * inSuite, void * inContext);
    static void CheckLast(nlTestSuite * inSuite, void * inContext);
    static void CheckRead(nlTestSuite * inSuite, void * inContext);
    static void CheckAddRef(nlTestSuite * inSuite, void * inContext);
    static void CheckFree(nlTestSuite * inSuite, void * inContext);
    static void CheckFreeHead(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleConstruct(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleMove(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleRelease(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleFree(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleRetain(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleAdopt(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleHold(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleAdvance(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleRightSize(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleCloneData(nlTestSuite * inSuite, void * inContext);
    static void CheckPacketBufferWriter(nlTestSuite * inSuite, void * inContext);
    static void CheckBuildFreeList(nlTestSuite * inSuite, void * inContext);

    static void PrintHandle(const char * tag, const PacketBuffer * buffer)
    {
        printf("%s %p ref=%u len=%-4u next=%p\n", tag, buffer, buffer ? buffer->ref : 0, buffer ? buffer->len : 0,
               buffer ? buffer->next : nullptr);
    }
    static void PrintHandle(const char * tag, const PacketBufferHandle & handle) { PrintHandle(tag, handle.mBuffer); }

    static constexpr uint16_t kBlockSize = PacketBuffer::kBlockSize;

private:
    struct BufferConfiguration
    {
        BufferConfiguration(uint16_t aReservedSize = 0) :
            init_len(0), reserved_size(aReservedSize), start_buffer(nullptr), end_buffer(nullptr), payload_ptr(nullptr),
            handle(nullptr)
        {}

        uint16_t init_len;
        uint16_t reserved_size;
        uint8_t * start_buffer;
        uint8_t * end_buffer;
        uint8_t * payload_ptr;
        PacketBufferHandle handle;
    };

    static void PrintHandle(const char * tag, const BufferConfiguration & config) { PrintHandle(tag, config.handle); }
    static void PrintConfig(const char * tag, const BufferConfiguration & config)
    {
        printf("%s pay=%-4zu len=%-4u res=%-4u:", tag, config.payload_ptr - config.start_buffer, config.init_len,
               config.reserved_size);
        PrintHandle("", config.handle);
    }

    PacketBufferTest(TestContext * context);
    ~PacketBufferTest();

    int InitializeTest(TestContext * context);
    int TerminateTest(TestContext * context);

    /*
     * Buffers allocated through PrepareTestBuffer with kRecordHandle set will be recorded in `handles` so that their
     * reference counts can be verified by ResetHandles(). Initially they have two refs: the recorded one and the returned one.
     */
    static constexpr int kRecordHandle     = 0x01;
    static constexpr int kAllowHandleReuse = 0x02;
    void PrepareTestBuffer(BufferConfiguration * config, int flags = 0);

    /*
     * Checks and clears the recorded handles. Returns true if it detects no leaks or double frees.
     * Called from `TerminateTest()`, but tests may choose to call it more often to verify reference counts.
     */
    bool ResetHandles();

    TestContext * mContext;
    std::vector<BufferConfiguration> configurations;
    std::vector<PacketBufferHandle> handles;
};

const uint16_t sTestReservedSizes[] = { 0, 10, 128, 1536, PacketBuffer::kMaxSizeWithoutReserve, PacketBufferTest::kBlockSize };
const uint16_t sTestLengths[]       = { 0, 1, 10, 128, PacketBufferTest::kBlockSize, UINT16_MAX };

PacketBufferTest::TestContext sContext = {
    sTestReservedSizes,
    sizeof(sTestReservedSizes) / sizeof(uint16_t),
    sTestLengths,
    sizeof(sTestLengths) / sizeof(uint16_t),
};

PacketBufferTest::PacketBufferTest(TestContext * context) : mContext(context)
{
    // Set up the buffer configuration vector for this suite.
    configurations.resize(0);
    for (size_t i = 0; i < mContext->reserved_size_count; ++i)
    {
        configurations.emplace_back<BufferConfiguration>(mContext->reserved_sizes[i]);
    }
}

int PacketBufferTest::TestSetup(void * inContext)
{
    chip::Platform::MemoryInit();

    if (chip::DeviceLayer::PlatformMgr().InitChipStack() != CHIP_NO_ERROR)
        return FAILURE;

    TestContext * const theContext = reinterpret_cast<TestContext *>(inContext);
    theContext->test               = new (std::nothrow) PacketBufferTest(theContext);
    if (theContext->test == nullptr)
    {
        return FAILURE;
    }
    return SUCCESS;
}

int PacketBufferTest::TestTeardown(void * inContext)
{
    chip::DeviceLayer::PlatformMgr().Shutdown();

    chip::Platform::MemoryShutdown();

    return SUCCESS;
}

int PacketBufferTest::TestInitialize(void * inContext)
{
    TestContext * const theContext = reinterpret_cast<TestContext *>(inContext);
    if (theContext->test == nullptr)
    {
        return FAILURE;
    }
    return theContext->test->InitializeTest(theContext);
}

int PacketBufferTest::InitializeTest(TestContext * context)
{
    if (context != mContext)
    {
        return FAILURE;
    }
    return SUCCESS;
}

int PacketBufferTest::TestTerminate(void * inContext)
{
    TestContext * const theContext = reinterpret_cast<TestContext *>(inContext);
    if (theContext->test == nullptr)
    {
        return FAILURE;
    }
    return theContext->test->TerminateTest(theContext);
}

int PacketBufferTest::TerminateTest(TestContext * context)
{
    const bool context_ok = (context == mContext);
    // Clear the configurations' bufffer handles.
    for (auto & configuration : configurations)
    {
        configuration.handle = nullptr;
    }
    const bool handles_ok = ResetHandles();
    return (context_ok && handles_ok) ? SUCCESS : FAILURE;
}

/**
 *  Allocate memory for a test buffer and configure according to test buffer configuration.
 */
void PacketBufferTest::PrepareTestBuffer(BufferConfiguration * config, int flags)
{
    if (config->handle.IsNull())
    {
        config->handle = PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
        if (config->handle.IsNull())
        {
            printf("NewPacketBuffer: Failed to allocate packet buffer (%u retained): %s\n",
                   static_cast<unsigned int>(handles.size()), strerror(errno));
            exit(EXIT_FAILURE);
        }
        if (flags & kRecordHandle)
        {
            handles.push_back(config->handle.Retain());
        }
    }
    else if ((flags & kAllowHandleReuse) == 0)
    {
        printf("Dirty test configuration\n");
        exit(EXIT_FAILURE);
    }

    const size_t lInitialSize = PacketBuffer::kStructureSize + config->reserved_size;
    const size_t lAllocSize   = kBlockSize;

    uint8_t * const raw = reinterpret_cast<uint8_t *>(config->handle.Get());
    memset(raw + PacketBuffer::kStructureSize, 0, lAllocSize - PacketBuffer::kStructureSize);

    config->start_buffer = raw;
    config->end_buffer   = raw + lAllocSize;

    if (lInitialSize > lAllocSize)
    {
        config->payload_ptr = config->end_buffer;
    }
    else
    {
        config->payload_ptr = config->start_buffer + lInitialSize;
    }

    if (config->handle->HasChainedBuffer())
    {
        // This should not happen.
        PacketBuffer::Free(config->handle->ChainedBuffer());
        config->handle->next = nullptr;
    }
    config->handle->payload = config->payload_ptr;
    config->handle->len     = config->init_len;
    config->handle->tot_len = config->init_len;
}

bool PacketBufferTest::ResetHandles()
{
    // Check against leaks or double-frees in tests: every handle obtained through
    // PacketBufferTest::NewPacketBuffer should have a reference count of 1.
    bool handles_ok = true;
    for (size_t i = 0; i < handles.size(); ++i)
    {
        const PacketBufferHandle & handle = handles[i];
        if (handle.Get() == nullptr)
        {
            printf("TestTerminate: handle %u null\n", static_cast<unsigned int>(i));
            handles_ok = false;
        }
        else if (handle->ref != 1)
        {
            printf("TestTerminate: handle %u buffer=%p ref=%u\n", static_cast<unsigned int>(i), handle.Get(), handle->ref);
            handles_ok = false;
            while (handle->ref > 1)
            {
                PacketBuffer::Free(handle.Get());
            }
        }
    }
    handles.resize(0);
    return handles_ok;
}

// Test functions invoked from the suite.

/**
 *  Test PacketBufferHandle::New() function.
 *
 *  Description: For every buffer-configuration from inContext, create a buffer's instance
 *               using the New() method. Then, verify that when the size of the reserved space
 *               passed to New() is greater than PacketBuffer::kMaxSizeWithoutReserve,
 *               the method returns nullptr. Otherwise, check for correctness of initializing
 *               the new buffer's internal state.
 */
void PacketBufferTest::CheckNew(nlTestSuite * inSuite, void * inContext)
{
    TestContext * const theContext = static_cast<TestContext *>(inContext);
    PacketBufferTest * const test  = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (const auto & config : test->configurations)
    {
        const PacketBufferHandle buffer = PacketBufferHandle::New(0, config.reserved_size);

        if (config.reserved_size > PacketBuffer::kMaxSizeWithoutReserve)
        {
            NL_TEST_ASSERT(inSuite, buffer.IsNull());
            continue;
        }

        NL_TEST_ASSERT(inSuite, config.reserved_size <= buffer->AllocSize());
        NL_TEST_ASSERT(inSuite, !buffer.IsNull());

        if (!buffer.IsNull())
        {
            const pbuf * const pb = TO_LWIP_PBUF(buffer.Get());

            NL_TEST_ASSERT(inSuite, pb->len == 0);
            NL_TEST_ASSERT(inSuite, pb->tot_len == 0);
            NL_TEST_ASSERT(inSuite, pb->next == nullptr);
            NL_TEST_ASSERT(inSuite, pb->ref == 1);
        }
    }

#if CHIP_SYSTEM_PACKETBUFFER_FROM_LWIP_POOL || CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_POOL
    // Use the rest of the buffer space
    std::vector<PacketBufferHandle> allocate_all_the_things;
    for (;;)
    {
        PacketBufferHandle buffer = PacketBufferHandle::New(0, 0);
        if (buffer.IsNull())
        {
            break;
        }
        // Hold on to the buffer, to use up all the buffer space.
        allocate_all_the_things.push_back(std::move(buffer));
    }
#endif // CHIP_SYSTEM_PACKETBUFFER_FROM_LWIP_POOL || CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_POOL
}

/**
 *  Test PacketBuffer::Start() function.
 */
void PacketBufferTest::CheckStart(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        test->PrepareTestBuffer(&config, kRecordHandle);
        NL_TEST_ASSERT(inSuite, config.handle->Start() == config.payload_ptr);
    }
}

/**
 *  Test PacketBuffer::SetStart() function.
 *
 *  Description: For every buffer-configuration from inContext, create a
 *               buffer's instance according to the configuration. Next,
 *               for any offset value from start_offset[], pass it to the
 *               buffer's instance through SetStart method. Then, verify that
 *               the beginning of the buffer has been correctly internally
 *               adjusted according to the offset value passed into the
 *               SetStart() method.
 */
void PacketBufferTest::CheckSetStart(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    static constexpr ptrdiff_t sSizePacketBuffer = kBlockSize;

    for (auto & config : test->configurations)
    {
        // clang-format off
        static constexpr ptrdiff_t start_offset[] =
        {
            -sSizePacketBuffer,
            -128,
            -1,
            0,
            1,
            128,
            sSizePacketBuffer
        };
        // clang-format on

        for (ptrdiff_t offset : start_offset)
        {
            test->PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
            uint8_t * const test_start = config.payload_ptr + offset;
            uint8_t * verify_start     = test_start;

            config.handle->SetStart(test_start);

            if (verify_start < config.start_buffer + PacketBuffer::kStructureSize)
            {
                // Set start before valid payload beginning.
                verify_start = config.start_buffer + PacketBuffer::kStructureSize;
            }

            if (verify_start > config.end_buffer)
            {
                // Set start after valid payload beginning.
                verify_start = config.end_buffer;
            }

            NL_TEST_ASSERT(inSuite, config.handle->payload == verify_start);

            if ((verify_start - config.payload_ptr) > config.init_len)
            {
                // Set start to the beginning of payload, right after handle's header.
                NL_TEST_ASSERT(inSuite, config.handle->len == 0);
            }
            else
            {
                // Set start to somewhere between the end of the handle's
                // header and the end of payload.
                NL_TEST_ASSERT(inSuite, config.handle->len == (config.init_len - (verify_start - config.payload_ptr)));
            }
        }
    }
}

/**
 *  Test PacketBuffer::DataLength() function.
 */
void PacketBufferTest::CheckDataLength(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        test->PrepareTestBuffer(&config, kRecordHandle);

        NL_TEST_ASSERT(inSuite, config.handle->DataLength() == config.handle->len);
    }
}

/**
 *  Test PacketBuffer::SetDataLength() function.
 *
 *  Description: Take two initial configurations of PacketBuffer from
 *               inContext and create two PacketBuffer instances based on those
 *               configurations. For any two buffers, call SetDataLength with
 *               different value from sLength[]. If two buffers are created with
 *               the same configuration, test SetDataLength on one buffer,
 *               without specifying the head of the buffer chain. Otherwise,
 *               test SetDataLength with one buffer being down the chain and the
 *               other one being passed as the head of the chain. After calling
 *               the method verify that data lengths were correctly adjusted.
 */
void PacketBufferTest::CheckSetDataLength(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            for (size_t i = 0; i < theContext->length_count; ++i)
            {
                const uint16_t length = theContext->lengths[i];
                test->PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
                test->PrepareTestBuffer(&config_2, kRecordHandle | kAllowHandleReuse);

                if (&config_1 == &config_2)
                {
                    // headOfChain (the second arg) is NULL
                    config_2.handle->SetDataLength(length, nullptr);

                    if (length > (config_2.end_buffer - config_2.payload_ptr))
                    {
                        NL_TEST_ASSERT(inSuite, config_2.handle->len == (config_2.end_buffer - config_2.payload_ptr));
                        NL_TEST_ASSERT(inSuite, config_2.handle->tot_len == (config_2.end_buffer - config_2.payload_ptr));
                        NL_TEST_ASSERT(inSuite, config_2.handle->next == nullptr);
                    }
                    else
                    {
                        NL_TEST_ASSERT(inSuite, config_2.handle->len == length);
                        NL_TEST_ASSERT(inSuite, config_2.handle->tot_len == length);
                        NL_TEST_ASSERT(inSuite, config_2.handle->next == nullptr);
                    }
                }
                else
                {
                    // headOfChain (the second arg) is config_1.handle
                    config_2.handle->SetDataLength(length, config_1.handle);

                    if (length > (config_2.end_buffer - config_2.payload_ptr))
                    {
                        NL_TEST_ASSERT(inSuite, config_2.handle->len == (config_2.end_buffer - config_2.payload_ptr));
                        NL_TEST_ASSERT(inSuite, config_2.handle->tot_len == (config_2.end_buffer - config_2.payload_ptr));
                        NL_TEST_ASSERT(inSuite, config_2.handle->next == nullptr);

                        NL_TEST_ASSERT(inSuite,
                                       config_1.handle->tot_len ==
                                           (config_1.init_len + static_cast<int32_t>(config_2.end_buffer - config_2.payload_ptr) -
                                            static_cast<int32_t>(config_2.init_len)));
                    }
                    else
                    {
                        NL_TEST_ASSERT(inSuite, config_2.handle->len == length);
                        NL_TEST_ASSERT(inSuite, config_2.handle->tot_len == length);
                        NL_TEST_ASSERT(inSuite, config_2.handle->next == nullptr);

                        NL_TEST_ASSERT(
                            inSuite,
                            config_1.handle->tot_len ==
                                (config_1.init_len + static_cast<int32_t>(length) - static_cast<int32_t>(config_2.init_len)));
                    }
                }
            }
        }
    }
}

/**
 *  Test PacketBuffer::TotalLength() function.
 */
void PacketBufferTest::CheckTotalLength(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        test->PrepareTestBuffer(&config, kRecordHandle);
        NL_TEST_ASSERT(inSuite, config.handle->TotalLength() == config.init_len);
    }
}

/**
 *  Test PacketBuffer::MaxDataLength() function.
 */
void PacketBufferTest::CheckMaxDataLength(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        test->PrepareTestBuffer(&config, kRecordHandle);

        NL_TEST_ASSERT(inSuite, config.handle->MaxDataLength() == (config.end_buffer - config.payload_ptr));
    }
}

/**
 *  Test PacketBuffer::AvailableDataLength() function.
 */
void PacketBufferTest::CheckAvailableDataLength(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        test->PrepareTestBuffer(&config, kRecordHandle);

        NL_TEST_ASSERT(inSuite,
                       config.handle->AvailableDataLength() == ((config.end_buffer - config.payload_ptr) - config.init_len));
    }
}

/**
 *  Test PacketBuffer::ReservedSize() function.
 */
void PacketBufferTest::CheckReservedSize(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        test->PrepareTestBuffer(&config, kRecordHandle);
        const size_t kAllocSize = config.handle->AllocSize();

        if (config.reserved_size > kAllocSize)
        {
            NL_TEST_ASSERT(inSuite, config.handle->ReservedSize() == kAllocSize);
        }
        else
        {
            NL_TEST_ASSERT(inSuite, config.handle->ReservedSize() == config.reserved_size);
        }
    }
}

/**
 *  Test PacketBuffer::HasChainedBuffer() function.
 */
void PacketBufferTest::CheckHasChainedBuffer(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            test->PrepareTestBuffer(&config_1);
            test->PrepareTestBuffer(&config_2);

            NL_TEST_ASSERT(inSuite, config_1.handle->HasChainedBuffer() == false);
            NL_TEST_ASSERT(inSuite, config_2.handle->HasChainedBuffer() == false);

            config_1.handle->AddToEnd(config_2.handle.Retain());
            NL_TEST_ASSERT(inSuite, config_1.handle->HasChainedBuffer() == true);
            NL_TEST_ASSERT(inSuite, config_2.handle->HasChainedBuffer() == false);

            config_1.handle = nullptr;
            config_2.handle = nullptr;
        }
    }
}

/**
 *  Test PacketBuffer::AddToEnd() function.
 *
 *  Description: Take three initial configurations of PacketBuffer from
 *               inContext, create three PacketBuffers based on those
 *               configurations and then link those buffers together with
 *               PacketBuffer:AddToEnd(). Then, assert that after connecting
 *               buffers together, their internal states are correctly updated.
 *               This test function tests linking any combination of three
 *               buffer-configurations passed within inContext.
 */
void PacketBufferTest::CheckAddToEnd(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            for (auto & config_3 : test->configurations)
            {
                if (&config_1 == &config_2 || &config_1 == &config_3 || &config_2 == &config_3)
                {
                    continue;
                }

                test->PrepareTestBuffer(&config_1);
                test->PrepareTestBuffer(&config_2);
                test->PrepareTestBuffer(&config_3);
                NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1);
                NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);
                NL_TEST_ASSERT(inSuite, config_3.handle->ref == 1);

                config_1.handle->AddToEnd(config_2.handle.Retain());
                NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1); // config_1.handle
                NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next
                NL_TEST_ASSERT(inSuite, config_3.handle->ref == 1); // config_3.handle

                NL_TEST_ASSERT(inSuite, config_1.handle->tot_len == (config_1.init_len + config_2.init_len));
                NL_TEST_ASSERT(inSuite, config_1.handle->next == config_2.handle.Get());
                NL_TEST_ASSERT(inSuite, config_2.handle->next == nullptr);
                NL_TEST_ASSERT(inSuite, config_3.handle->next == nullptr);

                config_1.handle->AddToEnd(config_3.handle.Retain());
                NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1); // config_1.handle
                NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next
                NL_TEST_ASSERT(inSuite, config_3.handle->ref == 2); // config_3.handle and config_2.handle->next

                NL_TEST_ASSERT(inSuite, config_1.handle->tot_len == (config_1.init_len + config_2.init_len + config_3.init_len));
                NL_TEST_ASSERT(inSuite, config_1.handle->next == config_2.handle.Get());
                NL_TEST_ASSERT(inSuite, config_2.handle->next == config_3.handle.Get());
                NL_TEST_ASSERT(inSuite, config_3.handle->next == nullptr);

                config_1.handle = nullptr;
                config_2.handle = nullptr;
                config_3.handle = nullptr;
            }
        }
    }
}

/**
 *  Test PacketBuffer::PopHead() function.
 *
 *  Description: Take two initial configurations of PacketBuffer from
 *               inContext and create two PacketBuffer instances based on those
 *               configurations. Next, link those buffers together, with the first
 *               buffer instance pointing to the second one. Then, call PopHead()
 *               on the first buffer to unlink the second buffer. After the call,
 *               verify correct internal state of the first buffer.
 */
void PacketBufferTest::CheckPopHead(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    // Single buffer test.
    for (auto & config_1 : test->configurations)
    {
        test->PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
        NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);

        const PacketBuffer * const buffer_1 = config_1.handle.mBuffer;

        const PacketBufferHandle popped = config_1.handle.PopHead();

        NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
        NL_TEST_ASSERT(inSuite, popped.mBuffer == buffer_1);
        NL_TEST_ASSERT(inSuite, popped->next == nullptr);
        NL_TEST_ASSERT(inSuite, popped->tot_len == config_1.init_len);
        NL_TEST_ASSERT(inSuite, popped->ref == 2);
    }
    test->ResetHandles();

    // Chained buffers test.
    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            test->PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
            test->PrepareTestBuffer(&config_2, kRecordHandle | kAllowHandleReuse);

            config_1.handle->AddToEnd(config_2.handle.Retain());

            const PacketBufferHandle popped = config_1.handle.PopHead();

            NL_TEST_ASSERT(inSuite, config_1.handle == config_2.handle);
            NL_TEST_ASSERT(inSuite, config_1.handle->next == nullptr);
            NL_TEST_ASSERT(inSuite, config_1.handle->tot_len == config_1.init_len);
        }
    }
}

/**
 *  Test PacketBuffer::CompactHead() function.
 *
 *  Description: Take two initial configurations of PacketBuffer from
 *               inContext and create two PacketBuffer instances based on those
 *               configurations. Next, set both buffers' data length to any
 *               combination of values from sLengths[] and link those buffers
 *               into a chain. Then, call CompactHead() on the first buffer in
 *               the chain. After calling the method, verify correctly adjusted
 *               state of the first buffer.
 */
void PacketBufferTest::CheckCompactHead(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    // Single buffer test.
    for (auto & config : test->configurations)
    {
        for (size_t i = 0; i < theContext->length_count; ++i)
        {
            const uint16_t length = theContext->lengths[i];

            test->PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
            config.handle->SetDataLength(length, config.handle);
            const uint16_t data_length = config.handle->DataLength();

            config.handle->CompactHead();

            NL_TEST_ASSERT(inSuite, config.handle->payload == (config.start_buffer + PacketBuffer::kStructureSize));
            NL_TEST_ASSERT(inSuite, config.handle->tot_len == data_length);
        }

        config.handle = nullptr;
    }
    NL_TEST_ASSERT(inSuite, test->ResetHandles());

    // Chained buffers test.
    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            // start with various initial length for the first buffer
            for (size_t i = 0; i < theContext->length_count; ++i)
            {
                const uint16_t length_1 = theContext->lengths[i];

                // start with various initial length for the second buffer
                for (size_t j = 0; j < theContext->length_count; ++j)
                {
                    const uint16_t length_2 = theContext->lengths[j];

                    test->PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
                    NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);

                    // CompactHead requires that there be no other references to the chained buffer,
                    // so we manage it manually.
                    test->PrepareTestBuffer(&config_2);
                    NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);
                    PacketBuffer * buffer_2 = std::move(config_2.handle).UnsafeRelease();
                    NL_TEST_ASSERT(inSuite, config_2.handle.IsNull());

                    config_1.handle->SetDataLength(length_1, config_1.handle);
                    const uint16_t data_length_1 = config_1.handle->DataLength();

                    // This chain will cause buffer_2 to be freed.
                    config_1.handle->next = buffer_2;

                    // Add various lengths to the second buffer
                    buffer_2->SetDataLength(length_2, config_1.handle);
                    const uint16_t data_length_2 = buffer_2->DataLength();

                    config_1.handle->CompactHead();

                    NL_TEST_ASSERT(inSuite, config_1.handle->payload == (config_1.start_buffer + PacketBuffer::kStructureSize));

                    if (config_1.handle->tot_len > config_1.handle->MaxDataLength())
                    {
                        NL_TEST_ASSERT(inSuite, config_1.handle->len == config_1.handle->MaxDataLength());
                        NL_TEST_ASSERT(inSuite, buffer_2->len == config_1.handle->tot_len - config_1.handle->MaxDataLength());
                        NL_TEST_ASSERT(inSuite, config_1.handle->next == buffer_2);
                        NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);
                        NL_TEST_ASSERT(inSuite, buffer_2->ref == 1);
                    }
                    else
                    {
                        NL_TEST_ASSERT(inSuite, config_1.handle->len == config_1.handle->tot_len);
                        if (data_length_1 >= config_1.handle->MaxDataLength() && data_length_2 == 0)
                        {
                            /* make sure the second buffer is not freed */
                            NL_TEST_ASSERT(inSuite, config_1.handle->next == buffer_2);
                            NL_TEST_ASSERT(inSuite, buffer_2->ref == 1);
                        }
                        else
                        {
                            /* make sure the second buffer is freed */
                            NL_TEST_ASSERT(inSuite, config_1.handle->next == nullptr);
                            buffer_2 = nullptr;
                        }
                    }

                    NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);
                    config_1.handle = nullptr;

                    // Verify and release handles.
                    NL_TEST_ASSERT(inSuite, test->ResetHandles());
                }
            }
        }
    }
}

/**
 *  Test PacketBuffer::ConsumeHead() function.
 *
 *  Description: For every buffer-configuration from inContext, create a
 *               buffer's instance according to the configuration. Next,
 *               for any value from sLengths[], pass it to the buffer's
 *               instance through ConsumeHead() method. Then, verify that
 *               the internal state of the buffer has been correctly
 *               adjusted according to the value passed into the method.
 */
void PacketBufferTest::CheckConsumeHead(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        for (size_t i = 0; i < theContext->length_count; ++i)
        {
            const uint16_t length = theContext->lengths[i];
            test->PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);

            config.handle->ConsumeHead(length);

            if (length > config.init_len)
            {
                NL_TEST_ASSERT(inSuite, config.handle->payload == (config.payload_ptr + config.init_len));
                NL_TEST_ASSERT(inSuite, config.handle->len == 0);
                NL_TEST_ASSERT(inSuite, config.handle->tot_len == 0);
            }
            else
            {
                NL_TEST_ASSERT(inSuite, config.handle->payload == (config.payload_ptr + length));
                NL_TEST_ASSERT(inSuite, config.handle->len == (config.handle->len - length));
                NL_TEST_ASSERT(inSuite, config.handle->tot_len == (config.handle->tot_len - length));
            }
        }
    }
}

/**
 *  Test PacketBuffer::Consume() function.
 *
 *  Description: Take two different initial configurations of PacketBuffer from
 *               inContext and create two PacketBuffer instances based on those
 *               configurations. Next, set both buffers' data length to any
 *               combination of values from sLengths[]  and link those buffers
 *               into a chain. Then, call Consume() on the first buffer in
 *               the chain with all values from sLengths[]. After calling the
 *               method, verify correctly adjusted the state of the first
 *               buffer and appropriate return pointer from the method's call.
 */
void PacketBufferTest::CheckConsume(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            // consume various amounts of memory
            for (size_t i = 0; i < theContext->length_count; ++i)
            {
                const uint16_t consumeLength = theContext->lengths[i];
                // start with various initial length for the first buffer
                for (size_t j = 0; j < theContext->length_count; ++j)
                {
                    const uint16_t len_1 = theContext->lengths[j];
                    // start with various initial length for the second buffer
                    for (size_t k = 0; k < theContext->length_count; ++k)
                    {
                        const uint16_t len_2 = theContext->lengths[k];

                        test->PrepareTestBuffer(&config_1);
                        test->PrepareTestBuffer(&config_2);
                        NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1);
                        NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);

                        config_1.handle->AddToEnd(config_2.handle.Retain());

                        // Add various lengths to buffers
                        config_1.handle->SetDataLength(len_1, config_1.handle);
                        config_2.handle->SetDataLength(len_2, config_1.handle);

                        const uint16_t buf_1_len = config_1.handle->len;
                        const uint16_t buf_2_len = config_2.handle->len;

                        PacketBufferHandle original_handle_1 = config_1.handle.Retain();
                        NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2); // config_1.handle and original_handle_1
                        NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next

                        config_1.handle.Consume(consumeLength);

                        if (consumeLength == 0)
                        {
                            NL_TEST_ASSERT(inSuite, config_1.handle == original_handle_1);
                            NL_TEST_ASSERT(inSuite, config_1.handle->len == buf_1_len);
                            NL_TEST_ASSERT(inSuite, config_2.handle->len == buf_2_len);
                            NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2); // config_1.handle and original_handle_1
                            NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next
                        }
                        else if (consumeLength < buf_1_len)
                        {
                            NL_TEST_ASSERT(inSuite, config_1.handle == original_handle_1);
                            NL_TEST_ASSERT(inSuite, config_1.handle->len == buf_1_len - consumeLength);
                            NL_TEST_ASSERT(inSuite, config_2.handle->len == buf_2_len);
                            NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2); // config_1.handle and original_handle_1
                            NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next
                        }
                        else if ((consumeLength < buf_1_len + buf_2_len ||
                                  (consumeLength == buf_1_len + buf_2_len && buf_2_len == 0)))
                        {
                            NL_TEST_ASSERT(inSuite, config_1.handle == config_2.handle);
                            NL_TEST_ASSERT(inSuite, config_2.handle->len == buf_1_len + buf_2_len - consumeLength);
                            NL_TEST_ASSERT(inSuite, original_handle_1->ref == 1); // original_handle_1
                            NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2);   // config_1.handle and config_2.handle
                        }
                        else
                        {
                            NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
                            NL_TEST_ASSERT(inSuite, original_handle_1->ref == 1); // original_handle_1
                            NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);   // config_2.handle
                        }

                        original_handle_1 = nullptr;
                        config_1.handle   = nullptr;
                        config_2.handle   = nullptr;
                    }
                }
            }
        }
    }
}

/**
 *  Test PacketBuffer::EnsureReservedSize() function.
 *
 *  Description: For every buffer-configuration from inContext, create a
 *               buffer's instance according to the configuration. Next,
 *               manually specify how much space is reserved in the buffer.
 *               Then, verify that EnsureReservedSize() method correctly
 *               retrieves the amount of the reserved space.
 */
void PacketBufferTest::CheckEnsureReservedSize(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        for (size_t i = 0; i < theContext->length_count; ++i)
        {
            const uint16_t length = theContext->lengths[i];

            test->PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
            const uint16_t kAllocSize = config.handle->AllocSize();
            uint16_t reserved_size    = config.reserved_size;

            if (PacketBuffer::kStructureSize + config.reserved_size > kAllocSize)
            {
                reserved_size = static_cast<uint16_t>(kAllocSize - PacketBuffer::kStructureSize);
            }

            if (length <= reserved_size)
            {
                NL_TEST_ASSERT(inSuite, config.handle->EnsureReservedSize(length) == true);
                continue;
            }

            if ((length + config.init_len) > (kAllocSize - PacketBuffer::kStructureSize))
            {
                NL_TEST_ASSERT(inSuite, config.handle->EnsureReservedSize(length) == false);
                continue;
            }

            NL_TEST_ASSERT(inSuite, config.handle->EnsureReservedSize(length) == true);
            NL_TEST_ASSERT(inSuite, config.handle->payload == (config.payload_ptr + length - reserved_size));
        }
    }
}

/**
 *  Test PacketBuffer::AlignPayload() function.
 *
 *  Description: For every buffer-configuration from inContext, create a
 *               buffer's instance according to the configuration. Next,
 *               manually specify how much space is reserved and the
 *               required payload shift. Then, verify that AlignPayload()
 *               method correctly aligns the payload start pointer.
 */
void PacketBufferTest::CheckAlignPayload(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        for (size_t n = 0; n < theContext->length_count; ++n)
        {
            test->PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
            const uint16_t kAllocSize = config.handle->AllocSize();

            if (theContext->lengths[n] == 0)
            {
                NL_TEST_ASSERT(inSuite, config.handle->AlignPayload(theContext->lengths[n]) == false);
                continue;
            }

            uint16_t reserved_size = config.reserved_size;
            if (config.reserved_size > kAllocSize)
            {
                reserved_size = kAllocSize;
            }

            const uint16_t payload_offset =
                static_cast<uint16_t>(reinterpret_cast<uintptr_t>(config.handle->Start()) % theContext->lengths[n]);
            uint16_t payload_shift = 0;
            if (payload_offset > 0)
                payload_shift = static_cast<uint16_t>(theContext->lengths[n] - payload_offset);

            if (payload_shift <= kAllocSize - reserved_size)
            {
                NL_TEST_ASSERT(inSuite, config.handle->AlignPayload(theContext->lengths[n]) == true);
                NL_TEST_ASSERT(inSuite, ((unsigned long) config.handle->Start() % theContext->lengths[n]) == 0);
            }
            else
            {
                NL_TEST_ASSERT(inSuite, config.handle->AlignPayload(theContext->lengths[n]) == false);
            }
        }
    }
}

/**
 *  Test PacketBuffer::Next() function.
 */
void PacketBufferTest::CheckNext(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            test->PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
            test->PrepareTestBuffer(&config_2, kRecordHandle | kAllowHandleReuse);

            if (&config_1 != &config_2)
            {
                NL_TEST_ASSERT(inSuite, config_1.handle->Next().IsNull());

                config_1.handle->AddToEnd(config_2.handle.Retain());

                NL_TEST_ASSERT(inSuite, config_1.handle->Next() == config_2.handle);
                NL_TEST_ASSERT(inSuite, config_1.handle->ChainedBuffer() == config_2.handle.Get());
            }
            else
            {
                NL_TEST_ASSERT(inSuite, !config_1.handle->HasChainedBuffer());
            }

            NL_TEST_ASSERT(inSuite, !config_2.handle->HasChainedBuffer());
        }
    }
}

/**
 *  Test PacketBuffer::Last() function.
 */
void PacketBufferTest::CheckLast(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            for (auto & config_3 : test->configurations)
            {
                if (&config_1 == &config_2 || &config_1 == &config_3 || &config_2 == &config_3)
                {
                    continue;
                }

                test->PrepareTestBuffer(&config_1);
                test->PrepareTestBuffer(&config_2);
                test->PrepareTestBuffer(&config_3);

                NL_TEST_ASSERT(inSuite, config_1.handle->Last() == config_1.handle);
                NL_TEST_ASSERT(inSuite, config_2.handle->Last() == config_2.handle);
                NL_TEST_ASSERT(inSuite, config_3.handle->Last() == config_3.handle);

                config_1.handle->AddToEnd(config_2.handle.Retain());

                NL_TEST_ASSERT(inSuite, config_1.handle->Last() == config_2.handle);
                NL_TEST_ASSERT(inSuite, config_2.handle->Last() == config_2.handle);
                NL_TEST_ASSERT(inSuite, config_3.handle->Last() == config_3.handle);

                config_1.handle->AddToEnd(config_3.handle.Retain());

                NL_TEST_ASSERT(inSuite, config_1.handle->Last() == config_3.handle);
                NL_TEST_ASSERT(inSuite, config_2.handle->Last() == config_3.handle);
                NL_TEST_ASSERT(inSuite, config_3.handle->Last() == config_3.handle);

                config_1.handle = nullptr;
                config_2.handle = nullptr;
                config_3.handle = nullptr;
            }
        }
    }
}

/**
 *  Test PacketBuffer::Read() function.
 */
void PacketBufferTest::CheckRead(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    uint8_t payloads[2 * kBlockSize] = { 1 };
    uint8_t result[2 * kBlockSize];
    for (size_t i = 1; i < sizeof(payloads); ++i)
    {
        payloads[i] = static_cast<uint8_t>(random());
    }

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            test->PrepareTestBuffer(&config_1, kAllowHandleReuse);
            test->PrepareTestBuffer(&config_2, kAllowHandleReuse);

            const uint16_t length_1     = config_1.handle->MaxDataLength();
            const uint16_t length_2     = config_2.handle->MaxDataLength();
            const size_t length_sum     = length_1 + length_2;
            const uint16_t length_total = static_cast<uint16_t>(length_sum);
            NL_TEST_ASSERT(inSuite, length_total == length_sum);

            memcpy(config_1.handle->Start(), payloads, length_1);
            memcpy(config_2.handle->Start(), payloads + length_1, length_2);
            config_1.handle->SetDataLength(length_1);
            config_2.handle->SetDataLength(length_2);
            config_1.handle->AddToEnd(config_2.handle.Retain());
            NL_TEST_ASSERT(inSuite, config_1.handle->TotalLength() == length_total);

            if (length_1 >= 1)
            {
                // Check a read that does not span packet buffers.
                CHIP_ERROR err = config_1.handle->Read(result, 1);
                NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
                NL_TEST_ASSERT(inSuite, result[0] == payloads[0]);
            }

            // Check a read that spans packet buffers.
            CHIP_ERROR err = config_1.handle->Read(result, length_total);
            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, memcmp(payloads, result, length_total) == 0);

            // Check a read that is too long fails.
            err = config_1.handle->Read(result, length_total + 1);
            NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);

            // Check that running off the end of a corrupt buffer chain is detected.
            if (length_total < UINT16_MAX)
            {
                // First case: TotalLength() is wrong.
                config_1.handle->tot_len = static_cast<uint16_t>(config_1.handle->tot_len + 1);
                err                      = config_1.handle->Read(result, length_total + 1);
                NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INTERNAL);
                config_1.handle->tot_len = static_cast<uint16_t>(config_1.handle->tot_len - 1);
            }
            if (length_1 >= 1)
            {
                // Second case: an individual buffer's DataLength() is wrong.
                config_1.handle->len = static_cast<uint16_t>(config_1.handle->len - 1);
                err                  = config_1.handle->Read(result, length_total);
                NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INTERNAL);
                config_1.handle->len = static_cast<uint16_t>(config_1.handle->len + 1);
            }

            config_1.handle = nullptr;
            config_2.handle = nullptr;
        }
    }
}

/**
 *  Test PacketBuffer::AddRef() function.
 */
void PacketBufferTest::CheckAddRef(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        test->PrepareTestBuffer(&config, kRecordHandle);
        const auto refs = config.handle->ref;
        config.handle->AddRef();
        NL_TEST_ASSERT(inSuite, config.handle->ref == refs + 1);
        config.handle->ref = refs; // Don't leak buffers.
    }
}

/**
 *  Test PacketBuffer::Free() function.
 *
 *  Description: Take two different initial configurations of PacketBuffer from
 *               inContext and create two PacketBuffer instances based on those
 *               configurations. Next, chain two buffers together and set each
 *               buffer's reference count to one of the values from
 *               init_ret_count[]. Then, call Free() on the first buffer in
 *               the chain and verify correctly adjusted states of the two
 *               buffers.
 */
void PacketBufferTest::CheckFree(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    const decltype(PacketBuffer::ref) init_ref_count[] = { 1, 2, 3 };
    constexpr size_t kRefs                             = sizeof(init_ref_count) / sizeof(init_ref_count[0]);

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            // start with various buffer ref counts
            for (size_t r = 0; r < kRefs; r++)
            {
                config_1.handle = PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
                config_2.handle = PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
                NL_TEST_ASSERT(inSuite, !config_1.handle.IsNull());
                NL_TEST_ASSERT(inSuite, !config_2.handle.IsNull());

                test->PrepareTestBuffer(&config_1, kAllowHandleReuse);
                test->PrepareTestBuffer(&config_2, kAllowHandleReuse);
                NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1);
                NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);

                // Chain buffers.
                config_1.handle->next = config_2.handle.Get();

                // Add various buffer ref counts.
                const auto initial_refs_1 = config_1.handle->ref = init_ref_count[r];
                const auto initial_refs_2 = config_2.handle->ref = init_ref_count[(r + 1) % kRefs];

                // Free head.
                PacketBuffer::Free(config_1.handle.mBuffer);
                if (initial_refs_1 == 1)
                {
                    config_1.handle.mBuffer = nullptr;
                }

                // Verification.
                if (initial_refs_1 > 1)
                {
                    // Verify that head ref count is decremented.
                    NL_TEST_ASSERT(inSuite, config_1.handle->ref == initial_refs_1 - 1);
                    // Verify that chain is maintained.
                    NL_TEST_ASSERT(inSuite, config_1.handle->next == config_2.handle.Get());
                    // Verify that chained buffer ref count has not changed.
                    NL_TEST_ASSERT(inSuite, config_2.handle->ref == initial_refs_2);
                }
                else
                {
                    if (initial_refs_2 > 1)
                    {
                        // Verify that chained buffer ref count is decremented.
                        NL_TEST_ASSERT(inSuite, config_2.handle->ref == initial_refs_2 - 1);
                    }
                    else
                    {
                        // Since the test used fake ref counts, config_2.handle now points
                        // to a freed buffer; clear the handle's internal pointer.
                        config_2.handle.mBuffer = nullptr;
                    }
                }

                // Clean up.
                if (!config_1.handle.IsNull())
                {
                    config_1.handle->next = nullptr;
                    config_1.handle->ref  = 1;
                    config_1.handle       = nullptr;
                }
                if (!config_2.handle.IsNull())
                {
                    config_2.handle->ref = 1;
                    config_2.handle      = nullptr;
                }
            }
        }
    }
}

/**
 *  Test PacketBuffer::FreeHead() function.
 *
 *  Description: Take two different initial configurations of PacketBuffer from
 *               inContext and create two PacketBuffer instances based on those
 *               configurations. Next, chain two buffers together. Then, call
 *               FreeHead() on the first buffer in the chain and verify that
 *               the method returned pointer to the second buffer.
 */
void PacketBufferTest::CheckFreeHead(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            // Test PacketBuffer::FreeHead

            test->PrepareTestBuffer(&config_1, kAllowHandleReuse);
            test->PrepareTestBuffer(&config_2, kAllowHandleReuse);
            NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1);
            NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);

            PacketBufferHandle handle_1 = config_1.handle.Retain();
            config_1.handle->AddToEnd(config_2.handle.Retain());
            NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);
            NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next

            PacketBuffer * const returned = PacketBuffer::FreeHead(std::move(config_1.handle).UnsafeRelease());

            NL_TEST_ASSERT(inSuite, handle_1->ref == 1);
            NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and returned
            NL_TEST_ASSERT(inSuite, returned == config_2.handle.Get());

            config_1.handle = nullptr;
            NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2);
            config_2.handle = nullptr;
            NL_TEST_ASSERT(inSuite, returned->ref == 1);
            PacketBuffer::Free(returned);

            // Test PacketBufferHandle::FreeHead

            test->PrepareTestBuffer(&config_1, kAllowHandleReuse);
            test->PrepareTestBuffer(&config_2, kAllowHandleReuse);
            NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1);
            NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);

            handle_1 = config_1.handle.Retain();
            config_1.handle->AddToEnd(config_2.handle.Retain());
            NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);
            NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next

            PacketBuffer * const buffer_1 = config_1.handle.Get();

            config_1.handle.FreeHead();

            NL_TEST_ASSERT(inSuite, buffer_1->ref == 1);
            NL_TEST_ASSERT(inSuite, config_1.handle == config_2.handle);
            NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle

            config_1.handle = nullptr;
            config_2.handle = nullptr;
        }
    }
}

void PacketBufferTest::CheckHandleConstruct(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    PacketBufferHandle handle_1;
    NL_TEST_ASSERT(inSuite, handle_1.IsNull());

    PacketBufferHandle handle_2(nullptr);
    NL_TEST_ASSERT(inSuite, handle_2.IsNull());

    PacketBufferHandle handle_3(PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize));
    NL_TEST_ASSERT(inSuite, !handle_3.IsNull());

    // Private constructor.
    PacketBuffer * const buffer_3 = std::move(handle_3).UnsafeRelease();
    PacketBufferHandle handle_4(buffer_3);
    NL_TEST_ASSERT(inSuite, handle_4.Get() == buffer_3);
}

void PacketBufferTest::CheckHandleMove(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            test->PrepareTestBuffer(&config_1, kRecordHandle);
            test->PrepareTestBuffer(&config_2, kRecordHandle);

            const PacketBuffer * const buffer_1 = config_1.handle.Get();
            const PacketBuffer * const buffer_2 = config_2.handle.Get();
            NL_TEST_ASSERT(inSuite, buffer_1 != buffer_2);
            NL_TEST_ASSERT(inSuite, buffer_1->ref == 2); // test.handles and config_1.handle
            NL_TEST_ASSERT(inSuite, buffer_2->ref == 2); // test.handles and config_2.handle

            config_1.handle = std::move(config_2.handle);
            NL_TEST_ASSERT(inSuite, config_1.handle.Get() == buffer_2);
            NL_TEST_ASSERT(inSuite, config_2.handle.Get() == nullptr);
            NL_TEST_ASSERT(inSuite, buffer_1->ref == 1); // test.handles
            NL_TEST_ASSERT(inSuite, buffer_2->ref == 2); // test.handles and config_1.handle

            config_1.handle = nullptr;
        }
        // Verify and release handles.
        NL_TEST_ASSERT(inSuite, test->ResetHandles());
    }
}

void PacketBufferTest::CheckHandleRelease(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        test->PrepareTestBuffer(&config_1);

        PacketBuffer * const buffer_1 = config_1.handle.Get();
        PacketBuffer * const taken_1  = std::move(config_1.handle).UnsafeRelease();

        NL_TEST_ASSERT(inSuite, buffer_1 == taken_1);
        NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
        NL_TEST_ASSERT(inSuite, buffer_1->ref == 1);
        PacketBuffer::Free(buffer_1);
    }
}

void PacketBufferTest::CheckHandleFree(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        test->PrepareTestBuffer(&config_1, kRecordHandle);

        const PacketBuffer * const buffer_1 = config_1.handle.Get();
        NL_TEST_ASSERT(inSuite, buffer_1->ref == 2); // test.handles and config_1.handle

        config_1.handle = nullptr;
        NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
        NL_TEST_ASSERT(inSuite, config_1.handle.Get() == nullptr);
        NL_TEST_ASSERT(inSuite, buffer_1->ref == 1); // test.handles only
    }
}

void PacketBufferTest::CheckHandleRetain(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        test->PrepareTestBuffer(&config_1, kRecordHandle);

        NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2); // test.handles and config_1.handle

        PacketBufferHandle handle_1 = config_1.handle.Retain();

        NL_TEST_ASSERT(inSuite, config_1.handle == handle_1);
        NL_TEST_ASSERT(inSuite, config_1.handle->ref == 3); // test.handles and config_1.handle and handle_1
    }
}

void PacketBufferTest::CheckHandleAdopt(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        test->PrepareTestBuffer(&config_1, kRecordHandle);
        PacketBuffer * buffer_1 = std::move(config_1.handle).UnsafeRelease();

        NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
        NL_TEST_ASSERT(inSuite, buffer_1->ref == 2); // test.handles and buffer_1

        config_1.handle = PacketBufferHandle::Adopt(buffer_1);
        NL_TEST_ASSERT(inSuite, config_1.handle.Get() == buffer_1);
        NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2); // test.handles and config_1.handle

        config_1.handle = nullptr;
        NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
        NL_TEST_ASSERT(inSuite, buffer_1->ref == 1); // test.handles only
    }
}

void PacketBufferTest::CheckHandleHold(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        test->PrepareTestBuffer(&config_1, kRecordHandle);
        PacketBuffer * buffer_1 = std::move(config_1.handle).UnsafeRelease();

        NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
        NL_TEST_ASSERT(inSuite, buffer_1->ref == 2); // test.handles and buffer_1

        config_1.handle = PacketBufferHandle::Hold(buffer_1);
        NL_TEST_ASSERT(inSuite, config_1.handle.Get() == buffer_1);
        NL_TEST_ASSERT(inSuite, config_1.handle->ref == 3); // test.handles and config_1.handle and buffer_1

        config_1.handle = nullptr;
        NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
        NL_TEST_ASSERT(inSuite, buffer_1->ref == 2); // test.handles only and buffer_1

        PacketBuffer::Free(buffer_1);
    }
}

void PacketBufferTest::CheckHandleAdvance(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            for (auto & config_3 : test->configurations)
            {
                if (&config_1 == &config_2 || &config_1 == &config_3 || &config_2 == &config_3)
                {
                    continue;
                }

                test->PrepareTestBuffer(&config_1);
                test->PrepareTestBuffer(&config_2);
                test->PrepareTestBuffer(&config_3);

                PacketBufferHandle handle_1 = config_1.handle.Retain();
                PacketBufferHandle handle_2 = config_2.handle.Retain();
                PacketBufferHandle handle_3 = config_3.handle.Retain();

                config_1.handle->AddToEnd(config_2.handle.Retain());
                config_1.handle->AddToEnd(config_3.handle.Retain());

                NL_TEST_ASSERT(inSuite, config_1.handle->ChainedBuffer() == config_2.handle.Get());
                NL_TEST_ASSERT(inSuite, config_2.handle->ChainedBuffer() == config_3.handle.Get());
                NL_TEST_ASSERT(inSuite, config_3.handle->HasChainedBuffer() == false);
                NL_TEST_ASSERT(inSuite, handle_1->ref == 2); // handle_1 and config_1.handle
                NL_TEST_ASSERT(inSuite, handle_2->ref == 3); // handle_2 and config_2.handle and config_1.handle->next
                NL_TEST_ASSERT(inSuite, handle_3->ref == 3); // handle_3 and config_3.handle and config_2.handle->next

                config_1.handle.Advance();

                NL_TEST_ASSERT(inSuite, config_1.handle == handle_2);
                NL_TEST_ASSERT(inSuite, handle_1->ref == 1); // handle_1 only
                NL_TEST_ASSERT(inSuite, handle_2->ref == 4); // handle_2, config_[12].handle, handle_1->next
                NL_TEST_ASSERT(inSuite, handle_3->ref == 3); // handle_3, config_3.handle, config_2.handle->next

                config_1.handle.Advance();

                NL_TEST_ASSERT(inSuite, config_1.handle == handle_3);
                NL_TEST_ASSERT(inSuite, handle_1->ref == 1); // handle_1 only
                NL_TEST_ASSERT(inSuite, handle_2->ref == 3); // handle_2, config_2.handle, handle_1->next
                NL_TEST_ASSERT(inSuite, handle_3->ref == 4); // handle_3, config_[13].handle, handle_2->next

                config_1.handle = nullptr;
                config_2.handle = nullptr;
                config_3.handle = nullptr;
            }
        }
    }
}

void PacketBufferTest::CheckHandleRightSize(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    const char kPayload[]     = "Joy!";
    PacketBufferHandle handle = PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
    PacketBuffer * buffer     = handle.mBuffer;

    memcpy(handle->Start(), kPayload, sizeof kPayload);
    buffer->SetDataLength(sizeof kPayload);
    NL_TEST_ASSERT(inSuite, handle->ref == 1);

    // RightSize should do nothing if there is another reference to the buffer.
    {
        PacketBufferHandle anotherHandle = handle.Retain();
        handle.RightSize();
        NL_TEST_ASSERT(inSuite, handle.mBuffer == buffer);
    }

#if CHIP_SYSTEM_PACKETBUFFER_HAS_RIGHTSIZE

    handle.RightSize();
    NL_TEST_ASSERT(inSuite, handle.mBuffer != buffer);
    NL_TEST_ASSERT(inSuite, handle->DataLength() == sizeof kPayload);
    NL_TEST_ASSERT(inSuite, memcmp(handle->Start(), kPayload, sizeof kPayload) == 0);

#else // CHIP_SYSTEM_PACKETBUFFER_HAS_RIGHTSIZE

    // For this configuration, RightSize() does nothing.
    handle.RightSize();
    NL_TEST_ASSERT(inSuite, handle.mBuffer == buffer);

#endif // CHIP_SYSTEM_PACKETBUFFER_HAS_RIGHTSIZE
}

void PacketBufferTest::CheckHandleCloneData(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    uint8_t lPayload[2 * PacketBuffer::kMaxSizeWithoutReserve];
    for (uint8_t & payload : lPayload)
    {
        payload = static_cast<uint8_t>(random());
    }

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            test->PrepareTestBuffer(&config_1);
            test->PrepareTestBuffer(&config_2);

            const uint8_t * payload_1 = lPayload;
            memcpy(config_1.handle->Start(), payload_1, config_1.handle->MaxDataLength());
            config_1.handle->SetDataLength(config_1.handle->MaxDataLength());

            const uint8_t * payload_2 = lPayload + config_1.handle->MaxDataLength();
            memcpy(config_2.handle->Start(), payload_2, config_2.handle->MaxDataLength());
            config_2.handle->SetDataLength(config_2.handle->MaxDataLength());

            // Clone single buffer.
            PacketBufferHandle clone_1 = config_1.handle.CloneData();
            NL_TEST_ASSERT(inSuite, !clone_1.IsNull());
            NL_TEST_ASSERT(inSuite, clone_1->DataLength() == config_1.handle->DataLength());
            NL_TEST_ASSERT(inSuite, memcmp(clone_1->Start(), payload_1, clone_1->DataLength()) == 0);
            if (clone_1->DataLength())
            {
                // Verify that modifying the clone does not affect the original.
                ScrambleData(clone_1->Start(), clone_1->DataLength());
                NL_TEST_ASSERT(inSuite, memcmp(clone_1->Start(), payload_1, clone_1->DataLength()) != 0);
                NL_TEST_ASSERT(inSuite, memcmp(config_1.handle->Start(), payload_1, config_1.handle->DataLength()) == 0);
            }

            // Clone buffer chain.
            config_1.handle->AddToEnd(config_2.handle.Retain());
            NL_TEST_ASSERT(inSuite, config_1.handle->HasChainedBuffer());
            clone_1                         = config_1.handle.CloneData();
            PacketBufferHandle clone_1_next = clone_1->Next();
            NL_TEST_ASSERT(inSuite, !clone_1.IsNull());
            NL_TEST_ASSERT(inSuite, clone_1->HasChainedBuffer());
            NL_TEST_ASSERT(inSuite, clone_1->DataLength() == config_1.handle->DataLength());
            NL_TEST_ASSERT(inSuite, clone_1->TotalLength() == config_1.handle->TotalLength());
            NL_TEST_ASSERT(inSuite, clone_1_next->DataLength() == config_2.handle->DataLength());
            NL_TEST_ASSERT(inSuite, memcmp(clone_1->Start(), payload_1, clone_1->DataLength()) == 0);
            NL_TEST_ASSERT(inSuite, memcmp(clone_1_next->Start(), payload_2, clone_1_next->DataLength()) == 0);
            if (clone_1->DataLength())
            {
                ScrambleData(clone_1->Start(), clone_1->DataLength());
                NL_TEST_ASSERT(inSuite, memcmp(clone_1->Start(), payload_1, clone_1->DataLength()) != 0);
                NL_TEST_ASSERT(inSuite, memcmp(config_1.handle->Start(), payload_1, config_1.handle->DataLength()) == 0);
            }
            if (clone_1_next->DataLength())
            {
                ScrambleData(clone_1_next->Start(), clone_1_next->DataLength());
                NL_TEST_ASSERT(inSuite, memcmp(clone_1_next->Start(), payload_2, clone_1_next->DataLength()) != 0);
                NL_TEST_ASSERT(inSuite, memcmp(config_2.handle->Start(), payload_2, config_2.handle->DataLength()) == 0);
            }

            config_1.handle = nullptr;
            config_2.handle = nullptr;
        }
    }

#if CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_HEAP

    // It is possible for a packet buffer allocation to return a larger block than requested (e.g. when using a shared pool)
    // and in particular to return a larger block than it is possible to request from PackBufferHandle::New().
    // In that case, (a) it is incorrect to actually use the extra space, and (b) if it is not used, the clone will
    // be the maximum possible size.
    //
    // This is only testable on heap allocation configurations, where pbuf records the allocation size and we can manually
    // construct an oversize buffer.

    constexpr uint16_t kOversizeDataSize = PacketBuffer::kMaxSizeWithoutReserve + 99;
    PacketBuffer * p =
        reinterpret_cast<PacketBuffer *>(chip::Platform::MemoryAlloc(PacketBuffer::kStructureSize + kOversizeDataSize));
    NL_TEST_ASSERT(inSuite, p != nullptr);

    p->next       = nullptr;
    p->payload    = reinterpret_cast<uint8_t *>(p) + PacketBuffer::kStructureSize;
    p->tot_len    = 0;
    p->len        = 0;
    p->ref        = 1;
    p->alloc_size = kOversizeDataSize;

    PacketBufferHandle handle = PacketBufferHandle::Adopt(p);

    // Fill the buffer to maximum and verify that it can be cloned.

    memset(handle->Start(), 1, PacketBuffer::kMaxSizeWithoutReserve);
    handle->SetDataLength(PacketBuffer::kMaxSizeWithoutReserve);
    NL_TEST_ASSERT(inSuite, handle->DataLength() == PacketBuffer::kMaxSizeWithoutReserve);

    PacketBufferHandle clone = handle.CloneData();
    NL_TEST_ASSERT(inSuite, !clone.IsNull());
    NL_TEST_ASSERT(inSuite, clone->DataLength() == PacketBuffer::kMaxSizeWithoutReserve);
    NL_TEST_ASSERT(inSuite, memcmp(handle->Start(), clone->Start(), PacketBuffer::kMaxSizeWithoutReserve) == 0);

    // Overfill the buffer and verify that it can not be cloned.
    memset(handle->Start(), 2, kOversizeDataSize);
    handle->SetDataLength(kOversizeDataSize);
    NL_TEST_ASSERT(inSuite, handle->DataLength() == kOversizeDataSize);

    clone = handle.CloneData();
    NL_TEST_ASSERT(inSuite, clone.IsNull());

    // Free the packet buffer memory ourselves, since we allocated it ourselves.
    chip::Platform::MemoryFree(std::move(handle).UnsafeRelease());

#endif // CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_HEAP
}

void PacketBufferTest::CheckPacketBufferWriter(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    const char kPayload[] = "Hello, world!";

    PacketBufferWriter yay(PacketBufferHandle::New(sizeof(kPayload)));
    PacketBufferWriter nay(PacketBufferHandle::New(sizeof(kPayload)), sizeof(kPayload) - 2);
    NL_TEST_ASSERT(inSuite, !yay.IsNull());
    NL_TEST_ASSERT(inSuite, !nay.IsNull());

    yay.Put(kPayload);
    yay.Put('\0');
    nay.Put(kPayload);
    nay.Put('\0');
    NL_TEST_ASSERT(inSuite, yay.Fit());
    NL_TEST_ASSERT(inSuite, !nay.Fit());

    PacketBufferHandle yayBuffer = yay.Finalize();
    PacketBufferHandle nayBuffer = nay.Finalize();
    NL_TEST_ASSERT(inSuite, yay.IsNull());
    NL_TEST_ASSERT(inSuite, nay.IsNull());
    NL_TEST_ASSERT(inSuite, !yayBuffer.IsNull());
    NL_TEST_ASSERT(inSuite, nayBuffer.IsNull());
    NL_TEST_ASSERT(inSuite, memcmp(yayBuffer->Start(), kPayload, sizeof kPayload) == 0);
}

/**
 *   Test Suite. It lists all the test functions.
 */
// clang-format off
const nlTest sTests[] =
{
    NL_TEST_DEF("PacketBuffer::New",                    PacketBufferTest::CheckNew),
    NL_TEST_DEF("PacketBuffer::Start",                  PacketBufferTest::CheckStart),
    NL_TEST_DEF("PacketBuffer::SetStart",               PacketBufferTest::CheckSetStart),
    NL_TEST_DEF("PacketBuffer::DataLength",             PacketBufferTest::CheckDataLength),
    NL_TEST_DEF("PacketBuffer::SetDataLength",          PacketBufferTest::CheckSetDataLength),
    NL_TEST_DEF("PacketBuffer::TotalLength",            PacketBufferTest::CheckTotalLength),
    NL_TEST_DEF("PacketBuffer::MaxDataLength",          PacketBufferTest::CheckMaxDataLength),
    NL_TEST_DEF("PacketBuffer::AvailableDataLength",    PacketBufferTest::CheckAvailableDataLength),
    NL_TEST_DEF("PacketBuffer::HasChainedBuffer",       PacketBufferTest::CheckHasChainedBuffer),
    NL_TEST_DEF("PacketBuffer::ReservedSize",           PacketBufferTest::CheckReservedSize),
    NL_TEST_DEF("PacketBuffer::AddToEnd",               PacketBufferTest::CheckAddToEnd),
    NL_TEST_DEF("PacketBuffer::PopHead",                PacketBufferTest::CheckPopHead),
    NL_TEST_DEF("PacketBuffer::CompactHead",            PacketBufferTest::CheckCompactHead),
    NL_TEST_DEF("PacketBuffer::ConsumeHead",            PacketBufferTest::CheckConsumeHead),
    NL_TEST_DEF("PacketBuffer::Consume",                PacketBufferTest::CheckConsume),
    NL_TEST_DEF("PacketBuffer::EnsureReservedSize",     PacketBufferTest::CheckEnsureReservedSize),
    NL_TEST_DEF("PacketBuffer::AlignPayload",           PacketBufferTest::CheckAlignPayload),
    NL_TEST_DEF("PacketBuffer::Next",                   PacketBufferTest::CheckNext),
    NL_TEST_DEF("PacketBuffer::Last",                   PacketBufferTest::CheckLast),
    NL_TEST_DEF("PacketBuffer::Read",                   PacketBufferTest::CheckRead),
    NL_TEST_DEF("PacketBuffer::AddRef",                 PacketBufferTest::CheckAddRef),
    NL_TEST_DEF("PacketBuffer::Free",                   PacketBufferTest::CheckFree),
    NL_TEST_DEF("PacketBuffer::FreeHead",               PacketBufferTest::CheckFreeHead),
    NL_TEST_DEF("PacketBuffer::HandleConstruct",        PacketBufferTest::CheckHandleConstruct),
    NL_TEST_DEF("PacketBuffer::HandleMove",             PacketBufferTest::CheckHandleMove),
    NL_TEST_DEF("PacketBuffer::HandleRelease",          PacketBufferTest::CheckHandleRelease),
    NL_TEST_DEF("PacketBuffer::HandleFree",             PacketBufferTest::CheckHandleFree),
    NL_TEST_DEF("PacketBuffer::HandleRetain",           PacketBufferTest::CheckHandleRetain),
    NL_TEST_DEF("PacketBuffer::HandleAdopt",            PacketBufferTest::CheckHandleAdopt),
    NL_TEST_DEF("PacketBuffer::HandleHold",             PacketBufferTest::CheckHandleHold),
    NL_TEST_DEF("PacketBuffer::HandleAdvance",          PacketBufferTest::CheckHandleAdvance),
    NL_TEST_DEF("PacketBuffer::HandleRightSize",        PacketBufferTest::CheckHandleRightSize),
    NL_TEST_DEF("PacketBuffer::HandleCloneData",        PacketBufferTest::CheckHandleCloneData),
    NL_TEST_DEF("PacketBuffer::PacketBufferWriter",     PacketBufferTest::CheckPacketBufferWriter),

    NL_TEST_SENTINEL()
};
// clang-format on

int TestSystemPacketBuffer(void)
{
    // clang-format off
    nlTestSuite theSuite = {
        .name ="chip-system-packetbuffer",
        .tests = &sTests[0],
        .setup = PacketBufferTest::TestSetup,
        .tear_down = PacketBufferTest::TestTeardown,
        // .initialize = PacketBufferTest::TestInitialize,
        .terminate = PacketBufferTest::TestTerminate
    };
    // clang-format on

    // Run test suit againt one context.
    nlTestRunner(&theSuite, &sContext);

    return (nlTestRunnerStats(&theSuite));
}

CHIP_REGISTER_TEST_SUITE(TestSystemPacketBuffer)
