/*
 *
 *    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 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 (size_t i = 0; i < configurations.size(); ++i)
    {
        configurations[i].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 (size_t i = 0; i < sizeof(lPayload); ++i)
    {
        lPayload[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);
            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)
