/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      This file implements unit tests for FabricTable implementation.
 */

#include <errno.h>
#include <nlunit-test.h>

#include <lib/core/CHIPCore.h>

#include <credentials/FabricTable.h>

#include <credentials/PersistentStorageOpCertStore.h>
#include <credentials/TestOnlyLocalCertificateAuthority.h>
#include <credentials/tests/CHIPCert_test_vectors.h>
#include <crypto/CHIPCryptoPAL.h>
#include <crypto/PersistentStorageOperationalKeystore.h>
#include <lib/asn1/ASN1.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/TestPersistentStorageDelegate.h>
#include <lib/support/UnitTestExtendedAssertions.h>
#include <lib/support/UnitTestRegistration.h>
#include <platform/ConfigurationManager.h>

#include <lib/support/BytesToHex.h>

#include <stdarg.h>

using namespace chip;
using namespace chip::Credentials;

namespace {

class ScopedFabricTable
{
public:
    ScopedFabricTable() {}
    ~ScopedFabricTable()
    {
        mFabricTable.Shutdown();
        mOpCertStore.Finish();
        mOpKeyStore.Finish();
    }

    CHIP_ERROR Init(chip::TestPersistentStorageDelegate * storage)
    {
        chip::FabricTable::InitParams initParams;
        initParams.storage             = storage;
        initParams.operationalKeystore = &mOpKeyStore;
        initParams.opCertStore         = &mOpCertStore;

        ReturnErrorOnFailure(mOpKeyStore.Init(storage));
        ReturnErrorOnFailure(mOpCertStore.Init(storage));
        return mFabricTable.Init(initParams);
    }

    FabricTable & GetFabricTable() { return mFabricTable; }

private:
    chip::FabricTable mFabricTable;
    chip::PersistentStorageOperationalKeystore mOpKeyStore;
    chip::Credentials::PersistentStorageOpCertStore mOpCertStore;
};

/**
 * Load a single test fabric with with the Root01:ICA01:Node01_01 identity.
 */
static CHIP_ERROR LoadTestFabric_Node01_01(nlTestSuite * inSuite, FabricTable & fabricTable, bool doCommit)
{
    Crypto::P256SerializedKeypair opKeysSerialized;
    static Crypto::P256Keypair opKey_Node01_01;

    FabricIndex fabricIndex;
    memcpy(opKeysSerialized.Bytes(), TestCerts::sTestCert_Node01_01_PublicKey.data(),
           TestCerts::sTestCert_Node01_01_PublicKey.size());
    memcpy(opKeysSerialized.Bytes() + TestCerts::sTestCert_Node01_01_PublicKey.size(),
           TestCerts::sTestCert_Node01_01_PrivateKey.data(), TestCerts::sTestCert_Node01_01_PrivateKey.size());

    ByteSpan rcacSpan(TestCerts::sTestCert_Root01_Chip);
    ByteSpan icacSpan(TestCerts::sTestCert_ICA01_Chip);
    ByteSpan nocSpan(TestCerts::sTestCert_Node01_01_Chip);

    ReturnErrorOnFailure(opKeysSerialized.SetLength(TestCerts::sTestCert_Node01_01_PublicKey.size() +
                                                    TestCerts::sTestCert_Node01_01_PrivateKey.size()));
    ReturnErrorOnFailure(opKey_Node01_01.Deserialize(opKeysSerialized));
    ReturnErrorOnFailure(fabricTable.AddNewPendingTrustedRootCert(rcacSpan));

    ReturnErrorOnFailure(fabricTable.AddNewPendingFabricWithProvidedOpKey(nocSpan, icacSpan, VendorId::TestVendor1,
                                                                          &opKey_Node01_01,
                                                                          /*isExistingOpKeyExternallyOwned =*/true, &fabricIndex));
    if (doCommit)
    {
        ReturnErrorOnFailure(fabricTable.CommitPendingFabricData());
    }

    return CHIP_NO_ERROR;
}

static CHIP_ERROR LoadTestFabric_Node01_02(nlTestSuite * inSuite, FabricTable & fabricTable, bool doCommit)
{
    Crypto::P256SerializedKeypair opKeysSerialized;
    FabricIndex fabricIndex;
    static Crypto::P256Keypair opKey_Node01_02;

    memcpy(opKeysSerialized.Bytes(), TestCerts::sTestCert_Node01_02_PublicKey.data(),
           TestCerts::sTestCert_Node01_02_PublicKey.size());
    memcpy(opKeysSerialized.Bytes() + TestCerts::sTestCert_Node01_02_PublicKey.size(),
           TestCerts::sTestCert_Node01_02_PrivateKey.data(), TestCerts::sTestCert_Node01_02_PrivateKey.size());

    ByteSpan rcacSpan(TestCerts::sTestCert_Root01_Chip);
    ByteSpan nocSpan(TestCerts::sTestCert_Node01_02_Chip);

    ReturnErrorOnFailure(opKeysSerialized.SetLength(TestCerts::sTestCert_Node01_02_PublicKey.size() +
                                                    TestCerts::sTestCert_Node01_02_PrivateKey.size()));
    ReturnErrorOnFailure(opKey_Node01_02.Deserialize(opKeysSerialized));

    ReturnErrorOnFailure(fabricTable.AddNewPendingTrustedRootCert(rcacSpan));

    ReturnErrorOnFailure(fabricTable.AddNewPendingFabricWithProvidedOpKey(nocSpan, {}, VendorId::TestVendor1, &opKey_Node01_02,
                                                                          /*isExistingOpKeyExternallyOwned =*/true, &fabricIndex));
    if (doCommit)
    {
        ReturnErrorOnFailure(fabricTable.CommitPendingFabricData());
    }

    return CHIP_NO_ERROR;
}

/**
 * Load a single test fabric with with the Root02:ICA02:Node02_01 identity.
 */
static CHIP_ERROR LoadTestFabric_Node02_01(nlTestSuite * inSuite, FabricTable & fabricTable, bool doCommit,
                                           FabricTable::AdvertiseIdentity advertiseIdentity = FabricTable::AdvertiseIdentity::Yes)
{
    Crypto::P256SerializedKeypair opKeysSerialized;
    FabricIndex fabricIndex;
    static Crypto::P256Keypair opKey_Node02_01;

    memcpy(opKeysSerialized.Bytes(), TestCerts::sTestCert_Node02_01_PublicKey.data(),
           TestCerts::sTestCert_Node02_01_PublicKey.size());
    memcpy(opKeysSerialized.Bytes() + TestCerts::sTestCert_Node02_01_PublicKey.size(),
           TestCerts::sTestCert_Node02_01_PrivateKey.data(), TestCerts::sTestCert_Node02_01_PrivateKey.size());

    ByteSpan rcacSpan(TestCerts::sTestCert_Root02_Chip);
    ByteSpan icacSpan(TestCerts::sTestCert_ICA02_Chip);
    ByteSpan nocSpan(TestCerts::sTestCert_Node02_01_Chip);

    NL_TEST_ASSERT(inSuite,
                   opKeysSerialized.SetLength(TestCerts::sTestCert_Node02_01_PublicKey.size() +
                                              TestCerts::sTestCert_Node02_01_PrivateKey.size()) == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, opKey_Node02_01.Deserialize(opKeysSerialized) == CHIP_NO_ERROR);

    NL_TEST_ASSERT(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcacSpan) == CHIP_NO_ERROR);

    CHIP_ERROR err =
        fabricTable.AddNewPendingFabricWithProvidedOpKey(nocSpan, icacSpan, VendorId::TestVendor1, &opKey_Node02_01,
                                                         /*isExistingOpKeyExternallyOwned =*/true, &fabricIndex, advertiseIdentity);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

    if (doCommit)
    {
        err = fabricTable.CommitPendingFabricData();
        NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    }

    return err;
}
void TestLastKnownGoodTimeInit(nlTestSuite * inSuite, void * inContext)
{
    // Fabric table init should init Last Known Good Time to the firmware build time.
    chip::TestPersistentStorageDelegate testStorage;
    ScopedFabricTable fabricTableHolder;

    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
    System::Clock::Seconds32 lastKnownGoodChipEpochTime;

    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();
    NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodChipEpochTime) == CHIP_NO_ERROR);
    System::Clock::Seconds32 firmwareBuildTime;
    NL_TEST_ASSERT(inSuite, DeviceLayer::ConfigurationMgr().GetFirmwareBuildChipEpochTime(firmwareBuildTime) == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, lastKnownGoodChipEpochTime == firmwareBuildTime);
}

void TestCollidingFabrics(nlTestSuite * inSuite, void * inContext)
{
    chip::TestPersistentStorageDelegate testStorage;
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    //
    // Start by loading NOCs for two nodes on the same fabric. The second one should fail since the FabricTable by default
    // doesn't permit colliding fabrics.
    //
    NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit = */ true) == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_02(inSuite, fabricTable, /* doCommit = */ true) != CHIP_NO_ERROR);

    //
    // Revert the partially added NOC from the last call, permit colliding fabrics in the FabricTable and try again.
    // This time, it should succeed
    //
    fabricTable.RevertPendingFabricData();
    fabricTable.PermitCollidingFabrics();
    NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_02(inSuite, fabricTable, /* doCommit = */ true) == CHIP_NO_ERROR);

    ByteSpan rcacSpan(TestCerts::sTestCert_Root01_Chip);
    Credentials::P256PublicKeySpan rootPublicKeySpan;

    NL_TEST_ASSERT(inSuite, Credentials::ExtractPublicKeyFromChipCert(rcacSpan, rootPublicKeySpan) == CHIP_NO_ERROR);

    //
    // Ensure we can find both node identities in the FabricTable.
    //
    {
        chip::Platform::ScopedMemoryBuffer<uint8_t> nocBuf;
        ByteSpan origNocSpan(TestCerts::sTestCert_Node01_01_Chip);
        NodeId nodeId;
        FabricId fabricId;

        NL_TEST_ASSERT(inSuite, ExtractNodeIdFabricIdFromOpCert(origNocSpan, &nodeId, &fabricId) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(inSuite, fabricTable.FindIdentity(rootPublicKeySpan, fabricId, nodeId) != nullptr);
    }

    {
        chip::Platform::ScopedMemoryBuffer<uint8_t> nocBuf;
        ByteSpan origNocSpan(TestCerts::sTestCert_Node01_02_Chip);
        NodeId nodeId;
        FabricId fabricId;

        NL_TEST_ASSERT(inSuite, ExtractNodeIdFabricIdFromOpCert(origNocSpan, &nodeId, &fabricId) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(inSuite, fabricTable.FindIdentity(rootPublicKeySpan, fabricId, nodeId) != nullptr);
    }
}

void TestUpdateLastKnownGoodTime(nlTestSuite * inSuite, void * inContext)
{
    // Adding a fabric should advance Last Known Good Time if any certificate's
    // NotBefore time is later than the build time, and else should leave it
    // to the initial build time value.

    // Test certs all have this NotBefore: Oct 15 14:23:43 2020 GMT
    const ASN1::ASN1UniversalTime asn1Expected = { 2020, 10, 15, 14, 23, 43 };
    uint32_t testCertNotBeforeSeconds;
    NL_TEST_ASSERT(inSuite, Credentials::ASN1ToChipEpochTime(asn1Expected, testCertNotBeforeSeconds) == CHIP_NO_ERROR);
    System::Clock::Seconds32 testCertNotBeforeTime = System::Clock::Seconds32(testCertNotBeforeSeconds);

    // Test that certificate NotBefore times that are before the Firmware build time
    // do not advance Last Known Good Time.
    System::Clock::Seconds32 afterNotBeforeBuildTimes[] = { System::Clock::Seconds32(testCertNotBeforeTime.count() + 1),
                                                            System::Clock::Seconds32(testCertNotBeforeTime.count() + 1000),
                                                            System::Clock::Seconds32(testCertNotBeforeTime.count() + 1000000) };
    for (auto buildTime : afterNotBeforeBuildTimes)
    {
        // Set build time to the desired value.
        NL_TEST_ASSERT(inSuite, DeviceLayer::ConfigurationMgr().SetFirmwareBuildChipEpochTime(buildTime) == CHIP_NO_ERROR);
        chip::TestPersistentStorageDelegate testStorage;

        {
            // Initialize a fabric table.
            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

            // Read back Last Known Good Time, which will have been initialized to firmware build time.
            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == buildTime);

            // Load a test fabric, but do not commit.
            NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit = */ false) == CHIP_NO_ERROR);

            // Read Last Known Good Time and verify that it hasn't moved forward.
            // This test case was written after the test certs' NotBefore time and we
            // are using a configuration manager that should reflect a real build time.
            // Therefore, we expect that build time is after NotBefore and so Last
            // Known Good Time will be set to the later of these, build time, even
            // after installing the new fabric.
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == buildTime);

            // Verify that calling the fail-safe roll back interface does not change
            // last known good time, as it hadn't been updated in the first place.
            fabricTable.RevertPendingFabricData();
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == buildTime);

            // Now reload the test fabric and commit this time.
            NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit = */ true) == CHIP_NO_ERROR);

            // Read Last Known Good Time and verify that it hasn't moved forward.
            // This test case was written after the test certs' NotBefore time and we
            // are using a configuration manager that should reflect a real build time.
            // Therefore, we expect that build time is after NotBefore and so Last
            // Known Good Time will be set to the later of these, build time, even
            // after installing the new fabric.
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == buildTime);

            // Call revert again.  Since we've committed, this is a no-op.
            // Last known good time should again be unchanged.
            fabricTable.RevertPendingFabricData();
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == buildTime);
        }
        {
            // Test reloading last known good time from persistence.
            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

            // Verify that last known good time was retained.
            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == buildTime);
        }
    }

    System::Clock::Seconds32 beforeNotBeforeBuildTimes[] = { testCertNotBeforeTime,
                                                             System::Clock::Seconds32(testCertNotBeforeTime.count() - 1),
                                                             System::Clock::Seconds32(testCertNotBeforeTime.count() - 1000),
                                                             System::Clock::Seconds32(testCertNotBeforeTime.count() - 1000000) };
    // Test that certificate NotBefore times that are at or after the Firmware
    // build time do result in Last Known Good Times set to these.
    // Verify behavior both for fail-safe roll back and commit scenarios.
    for (auto buildTime : beforeNotBeforeBuildTimes)
    {
        // Set build time to the desired value.
        NL_TEST_ASSERT(inSuite, DeviceLayer::ConfigurationMgr().SetFirmwareBuildChipEpochTime(buildTime) == CHIP_NO_ERROR);
        chip::TestPersistentStorageDelegate testStorage;
        {
            // Initialize a fabric table.
            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

            // Load a test fabric, but do not commit.
            NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit = */ false) == CHIP_NO_ERROR);

            // Read Last Known Good Time and verify that it is now set to the certificate
            // NotBefore time, as this should be at or after firmware build time.
            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == testCertNotBeforeTime);

            // Now test revert.  Last known good time should change back to the
            // previous value.
            fabricTable.RevertPendingFabricData();
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == buildTime);
        }
        {
            // Test reloading last known good time from persistence.
            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

            // Verify that the original last known good time was retained, since
            // we reverted before.
            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
        }
        {
            // Now test loading a fabric and committing.
            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();
            NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit = */ true) == CHIP_NO_ERROR);

            // Read Last Known Good Time and verify that it is now set to the certificate
            // NotBefore time, as this should be at or after firmware build time.
            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == testCertNotBeforeTime);

            // Now test revert, which will be a no-op because we already
            // committed.  Verify that Last Known Good time is retained.
            fabricTable.RevertPendingFabricData();
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == testCertNotBeforeTime);
        }
        {
            // Test reloading last known good time from persistence.
            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

            // Verify that the new last known good time was retained, since
            // we committed.
            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == testCertNotBeforeTime);
        }
    }
}

void TestSetLastKnownGoodTime(nlTestSuite * inSuite, void * inContext)
{
    // It is desirable for nodes to set Last Known Good Time whenever a good
    // time source is available, including cases where this would set the time
    // backward.  However, it is impermissible to set last known good time to
    // any time before the Firmware Build time or the latest NotBefore of any
    // installed certificate.

    // Test certs all have this NotBefore: Oct 15 14:23:43 2020 GMT
    const ASN1::ASN1UniversalTime asn1Expected = { 2020, 10, 15, 14, 23, 43 };
    uint32_t testCertNotBeforeSeconds;
    NL_TEST_ASSERT(inSuite, Credentials::ASN1ToChipEpochTime(asn1Expected, testCertNotBeforeSeconds) == CHIP_NO_ERROR);
    System::Clock::Seconds32 testCertNotBeforeTime = System::Clock::Seconds32(testCertNotBeforeSeconds);

    // Iterate over two cases: one with build time prior to our certificates' NotBefore, one with build time after.
    System::Clock::Seconds32 testCaseFirmwareBuildTimes[] = { System::Clock::Seconds32(testCertNotBeforeTime.count() - 100000),
                                                              System::Clock::Seconds32(testCertNotBeforeTime.count() + 100000) };

    for (auto buildTime : testCaseFirmwareBuildTimes)
    {
        // Set build time to the desired value.
        NL_TEST_ASSERT(inSuite, DeviceLayer::ConfigurationMgr().SetFirmwareBuildChipEpochTime(buildTime) == CHIP_NO_ERROR);
        chip::TestPersistentStorageDelegate testStorage;
        System::Clock::Seconds32 newTime;
        {
            // Initialize a fabric table.
            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

            // Load a test fabric
            NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit= */ true) == CHIP_NO_ERROR);

            // Verify the Last Known Good Time matches our expected initial value.
            System::Clock::Seconds32 initialLastKnownGoodTime =
                buildTime > testCertNotBeforeTime ? buildTime : testCertNotBeforeTime;
            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == initialLastKnownGoodTime);

            // Read Last Known Good Time and verify that it hasn't moved forward, since
            // build time is later than the test certs' NotBefore times.
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == initialLastKnownGoodTime);

            // Attempt to set a Last Known Good Time that is before the firmware build time.  This should fail.
            newTime = System::Clock::Seconds32(buildTime.count() - 1000);
            NL_TEST_ASSERT(inSuite, fabricTable.SetLastKnownGoodChipEpochTime(newTime) != CHIP_NO_ERROR);

            // Verify Last Known Good Time is unchanged.
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == initialLastKnownGoodTime);

            // Attempt to set a Last Known Good Time that is before our certificates' NotBefore times.  This should fail.
            newTime = System::Clock::Seconds32(testCertNotBeforeTime.count() - 1000);
            NL_TEST_ASSERT(inSuite, fabricTable.SetLastKnownGoodChipEpochTime(newTime) != CHIP_NO_ERROR);

            // Verify Last Known Good Time is unchanged.
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == initialLastKnownGoodTime);

            // Attempt to set a Last Known Good Time that at our current value.
            NL_TEST_ASSERT(inSuite, fabricTable.SetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);

            // Verify Last Known Good Time is unchanged.
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == initialLastKnownGoodTime);

            // Attempt to set Last Known Good Times that is after our current value.
            newTime = System::Clock::Seconds32(initialLastKnownGoodTime.count() + 1000);
            NL_TEST_ASSERT(inSuite, fabricTable.SetLastKnownGoodChipEpochTime(newTime) == CHIP_NO_ERROR);

            // Verify Last Known Good Time is updated.
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == newTime);
        }
        {
            // Verify that Last Known Good Time was persisted.

            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == newTime);
        }
    }
}

// Test adding 2 fabrics, updating 1, removing 1
void TestBasicAddNocUpdateNocFlow(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabric11CertAuthority;
    Credentials::TestOnlyLocalCertificateAuthority fabric44CertAuthority;

    chip::TestPersistentStorageDelegate storage;

    // Uncomment the next line for superior debugging powers if you blow-up this test
    // storage.SetLoggingLevel(chip::TestPersistentStorageDelegate::LoggingLevel::kLogMutation);

    // Initialize test CA and a Fabric 11 externally owned key
    NL_TEST_ASSERT(inSuite, fabric11CertAuthority.Init().IsSuccess());
    NL_TEST_ASSERT(inSuite, fabric44CertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    chip::Crypto::P256Keypair fabric11Node55Keypair; // Fabric ID 11,
    NL_TEST_ASSERT(inSuite, fabric11Node55Keypair.Initialize(Crypto::ECPKeyTarget::ECDSA) == CHIP_NO_ERROR);

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    {
        FabricIndex nextFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
        NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 1);
    }

    size_t numFabricsIterated = 0;

    size_t numStorageKeysAtStart = storage.GetNumKeys();

    // Sequence 1: Add node ID 55 on fabric 11, using externally owned key and no ICAC --> Yield fabricIndex 1
    {
        FabricId fabricId = 11;
        NodeId nodeId     = 55;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric11CertAuthority.SetIncludeIcac(false)
                                   .GenerateNocChain(fabricId, nodeId, fabric11Node55Keypair.Pubkey())
                                   .GetStatus());
        ByteSpan rcac = fabric11CertAuthority.GetRcac();
        ByteSpan noc  = fabric11CertAuthority.GetNoc();

        // Validate iterator sees nothing yet
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 0);
            NL_TEST_ASSERT(inSuite, saw1 == false);
        }

        uint8_t rcacBuf[Credentials::kMaxCHIPCertLength];
        {
            // No pending root cert yet.
            MutableByteSpan fetchedSpan{ rcacBuf };
            NL_TEST_ASSERT(inSuite, fabricTable.FetchPendingNonFabricAssociatedRootCert(fetchedSpan) == CHIP_ERROR_NOT_FOUND);
        }

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        {
            // Now have a pending root cert.
            MutableByteSpan fetchedSpan{ rcacBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchPendingNonFabricAssociatedRootCert(fetchedSpan));
            NL_TEST_ASSERT(inSuite, fetchedSpan.data_equal(rcac));
        }

        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        bool keyIsExternallyOwned  = true;

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithProvidedOpKey(noc, ByteSpan{}, kVendorId, &fabric11Node55Keypair,
                                                                                keyIsExternallyOwned, &newFabricIndex));
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        {
            // No more pending root cert; it's associated with a fabric now.
            MutableByteSpan fetchedSpan{ rcacBuf };
            NL_TEST_ASSERT(inSuite, fabricTable.FetchPendingNonFabricAssociatedRootCert(fetchedSpan) == CHIP_ERROR_NOT_FOUND);
        }

        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageKeysAtStart);

        // Next fabric index has not been updated yet.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 1);
        }

        // Validate iterator sees pending
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == nodeId);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == fabricId);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }

        // Commit, now storage should have keys
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == (numStorageKeysAtStart + 4)); // 2 opcerts + fabric metadata + index

        // Next fabric index has been updated.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 2);
        }

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == newFabricIndex);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == nodeId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == fabricId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        Crypto::P256ECDSASignature sig;
        uint8_t message[] = { 'm', 's', 'g' };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(newFabricIndex, ByteSpan{ message }, sig));
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric11Node55Keypair.Pubkey().ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));

        // Validate iterator sees committed
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == nodeId);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == fabricId);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }
    }

    size_t numStorageAfterFirstAdd = storage.GetNumKeys();

    // Sequence 2: Add node ID 999 on fabric 44, using operational keystore and ICAC --> Yield fabricIndex 2
    {
        FabricId fabricId = 44;
        NodeId nodeId     = 999;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric44CertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabric44CertAuthority.GetRcac();
        ByteSpan icac = fabric44CertAuthority.GetIcac();
        ByteSpan noc  = fabric44CertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        // Next fabric index should still be the same as before.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 2);
        }

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 2);
        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageAfterFirstAdd);
        // Next fabric index has not been updated yet.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 2);
        }

        // Commit, now storage should have keys
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);

        NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(),
                              (numStorageAfterFirstAdd + 5)); // 3 opcerts + fabric metadata + 1 operational key

        // Next fabric index has been updated.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 3);
        }

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == newFabricIndex);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == nodeId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == fabricId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        {
            Crypto::P256ECDSASignature sig;
            uint8_t message[] = { 'm', 's', 'g' };

            Crypto::P256PublicKey nocPubKey;
            NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), nocPubKey));

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(newFabricIndex, ByteSpan{ message }, sig));
            NL_TEST_ASSERT_SUCCESS(inSuite, nocPubKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
        }

        // Verify we can now see 2 fabrics with the iterator
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            bool saw2          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 55);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 11);
                    saw1 = true;
                }
                if (iterFabricInfo.GetFabricIndex() == 2)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 999);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw2 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 2);
            NL_TEST_ASSERT(inSuite, saw1 == true);
            NL_TEST_ASSERT(inSuite, saw2 == true);
        }
    }

    size_t numStorageAfterSecondAdd = storage.GetNumKeys();

    // Sequence 3: Update node ID 999 to 1000 on fabric 44, using operational keystore and no ICAC --> Stays fabricIndex 2
    {
        FabricId fabricId       = 44;
        NodeId nodeId           = 1000;
        FabricIndex fabricIndex = 2;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };

        // Make sure to tag fabric index to pending opkey: otherwise the UpdateNOC fails
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AllocatePendingOperationalKey(chip::MakeOptional(static_cast<FabricIndex>(2)), csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric44CertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabric44CertAuthority.GetRcac();
        ByteSpan noc  = fabric44CertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
        NL_TEST_ASSERT_SUCCESS(
            inSuite,
            fabricTable.UpdatePendingFabricWithOperationalKeystore(2, noc, ByteSpan{}, FabricTable::AdvertiseIdentity::No));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);

        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageAfterSecondAdd);

        // Validate iterator sees the pending data
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            bool saw2          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 55);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 11);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.ShouldAdvertiseIdentity());
                    saw1 = true;
                }
                if (iterFabricInfo.GetFabricIndex() == 2)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 1000);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    NL_TEST_ASSERT(inSuite, !iterFabricInfo.ShouldAdvertiseIdentity());
                    saw2 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 2);
            NL_TEST_ASSERT(inSuite, saw1 == true);
            NL_TEST_ASSERT(inSuite, saw2 == true);
        }

        // Commit, now storage should have keys
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);

        NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(), (numStorageAfterSecondAdd - 1)); // ICAC got deleted

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == fabricIndex);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == nodeId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == fabricId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(fabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        {
            Crypto::P256ECDSASignature sig;
            uint8_t message[] = { 'm', 's', 'g' };

            Crypto::P256PublicKey nocPubKey;
            NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), nocPubKey));

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(fabricIndex, ByteSpan{ message }, sig));
            NL_TEST_ASSERT_SUCCESS(inSuite, nocPubKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
        }

        // Validate iterator sees the committed update
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            bool saw2          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 55);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 11);
                    saw1 = true;
                }
                if (iterFabricInfo.GetFabricIndex() == 2)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 1000);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw2 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 2);
            NL_TEST_ASSERT(inSuite, saw1 == true);
            NL_TEST_ASSERT(inSuite, saw2 == true);
        }

        // Next fabric index has stayed the same.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 3);
        }
    }

    size_t numStorageAfterUpdate = storage.GetNumKeys();

    // Sequence 4: Rename fabric index 2, applies immediately when nothing pending
    {
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SetFabricLabel(2, "roboto"_span));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);

        NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(), numStorageAfterUpdate); // Number of keys unchanged

        // Validate basic contents
        {
            const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
            NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
            if (fabricInfo != nullptr)
            {
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 1000);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 44);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().data_equal(CharSpan{ "roboto", strlen("roboto") }));
            }
        }

        // Next fabric index has stayed the same.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 3);
        }
    }

    // Sequence 5: Remove FabricIndex 1 (FabricId 11, NodeId 55), make sure FabricIndex 2 (FabricId 44, NodeId 1000) still exists
    {
        // Remove the fabric: no commit needed
        {
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.Delete(1));
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

            NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(), (numStorageAfterUpdate - 3)); // Deleted NOC, RCAC, Metadata
        }

        // Next fabric index has stayed the same.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 3);
        }

        // Validate contents of Fabric Index 2 is still OK
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 1000);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 44);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().data_equal(CharSpan{ "roboto", strlen("roboto") }));

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(2, rootPublicKeyOfFabric));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        {
            uint8_t nocBuf[Credentials::kMaxCHIPCertLength];
            MutableByteSpan nocSpan{ nocBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchNOCCert(2, nocSpan));

            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(nocSpan, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey nocPubKey(certificates.GetCertSet()[0].mPublicKey);

            Crypto::P256ECDSASignature sig;
            uint8_t message[] = { 'm', 's', 'g' };

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(2, ByteSpan{ message }, sig));
            NL_TEST_ASSERT_SUCCESS(inSuite, nocPubKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
        }

        // Validate iterator only sees the remaining fabric
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            bool saw2          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    saw1 = true;
                }
                if (iterFabricInfo.GetFabricIndex() == 2)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 1000);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw2 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == false);
            NL_TEST_ASSERT(inSuite, saw2 == true);
        }
    }
}

void TestAddMultipleSameRootDifferentFabricId(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority;

    chip::TestPersistentStorageDelegate storage;
    NL_TEST_ASSERT(inSuite, fabricCertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    uint8_t rcac1Buf[kMaxCHIPCertLength];
    MutableByteSpan rcac1Span{ rcac1Buf };

    // First scope: add FabricID 1111, node ID 55
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabricCertAuthority.GetRcac();
        // Keep a copy for second scope check
        CopySpanToMutableSpan(rcac, rcac1Span);

        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);
        }
    }
    size_t numStorageKeysAfterFirstAdd = storage.GetNumKeys();
    NL_TEST_ASSERT(inSuite, numStorageKeysAfterFirstAdd == 7); // Metadata, index, 3 certs, 1 opkey, last known good time

    // Second scope: add FabricID 2222, node ID 66, same root as first
    {
        FabricId fabricId = 2222;
        NodeId nodeId     = 66;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac2 = fabricCertAuthority.GetRcac();
        NL_TEST_ASSERT(inSuite, rcac2.data_equal(rcac1Span));

        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac2));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 2);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 66);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 2222);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);
        }
    }
    size_t numStorageKeysAfterSecondAdd = storage.GetNumKeys();
    NL_TEST_ASSERT(inSuite, numStorageKeysAfterSecondAdd == (numStorageKeysAfterFirstAdd + 5)); // Add 3 certs, 1 metadata, 1 opkey
}

void TestAddMultipleSameFabricIdDifferentRoot(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority1;
    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority2;

    chip::TestPersistentStorageDelegate storage;
    NL_TEST_ASSERT(inSuite, fabricCertAuthority1.Init().IsSuccess());
    NL_TEST_ASSERT(inSuite, fabricCertAuthority2.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    uint8_t rcac1Buf[kMaxCHIPCertLength];
    MutableByteSpan rcac1Span{ rcac1Buf };

    // First scope: add FabricID 1111, node ID 55
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority1.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabricCertAuthority1.GetRcac();
        // Keep a copy for second scope check
        CopySpanToMutableSpan(rcac, rcac1Span);

        ByteSpan icac = fabricCertAuthority1.GetIcac();
        ByteSpan noc  = fabricCertAuthority1.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);
        }
    }
    size_t numStorageKeysAfterFirstAdd = storage.GetNumKeys();
    NL_TEST_ASSERT(inSuite, numStorageKeysAfterFirstAdd == 7); // Metadata, index, 3 certs, 1 opkey, last known good time

    // Second scope: add FabricID 1111, node ID 66, different root from first
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 66;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority2.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac2 = fabricCertAuthority2.GetRcac();
        NL_TEST_ASSERT(inSuite, !rcac2.data_equal(rcac1Span));

        ByteSpan icac = fabricCertAuthority2.GetIcac();
        ByteSpan noc  = fabricCertAuthority2.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac2));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 2);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 66);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);
        }
    }
    size_t numStorageKeysAfterSecondAdd = storage.GetNumKeys();
    NL_TEST_ASSERT(inSuite, numStorageKeysAfterSecondAdd == (numStorageKeysAfterFirstAdd + 5)); // Add 3 certs, 1 metadata, 1 opkey
}

void TestPersistence(nlTestSuite * inSuite, void * inContext)
{
    /**
     *
     * - Create an outer scope with storage delegate
     *   - Keep buffer slots for the operational public keys of the 2 fabrics added in the next scope
     *
     * - Create a new scope with a ScopedFabricTable
     *   - Add 2 fabrics, fully committed, using OperationalKeystore-based storage (e.g. CSR for opkey)
     *   - Make sure to save public keys in other scope for next step
     *
     * - Create a new scope with a ScopedFabricTable
     *   - Validate that after init, it has 2 fabrics and the 2 fabrics match fabric indices expected,
     *     and that the fabric tables are usable, and that NOC can be extracted for each, and that
     *     its public key matches expectation, and that they match the public keys stored in outer scope
     *     and verify you can sign and verify messages with the opkey
     *
     */

    Crypto::P256PublicKey fIdx1PublicKey;
    Crypto::P256PublicKey fIdx2PublicKey;

    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority;

    chip::TestPersistentStorageDelegate storage;

    NL_TEST_ASSERT(inSuite, fabricCertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // First scope: add 2 fabrics with same root: (1111, 2222), commit them, keep track of public keys
    {
        // Initialize a FabricTable
        ScopedFabricTable fabricTableHolder;
        NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
        FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

        // Add Fabric 1111 Node Id 55
        {
            FabricId fabricId = 1111;
            NodeId nodeId     = 55;

            uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
            MutableByteSpan csrSpan{ csrBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

            NL_TEST_ASSERT_SUCCESS(
                inSuite, fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
            ByteSpan rcac = fabricCertAuthority.GetRcac();
            ByteSpan icac = fabricCertAuthority.GetIcac();
            ByteSpan noc  = fabricCertAuthority.GetNoc();

            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
            NL_TEST_ASSERT(inSuite, newFabricIndex == 1);

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

            // Validate contents
            const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
            NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
            if (fabricInfo != nullptr)
            {
                Credentials::ChipCertificateSet certificates;
                NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
                NL_TEST_ASSERT_SUCCESS(inSuite,
                                       certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
                Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

                Crypto::P256PublicKey rootPublicKeyOfFabric;
                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
                NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
            }

            // Validate that fabric has the correct operational key by verifying a signature
            {
                Crypto::P256ECDSASignature sig;
                uint8_t message[] = { 'm', 's', 'g' };

                NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), fIdx1PublicKey));

                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(newFabricIndex, ByteSpan{ message }, sig));
                NL_TEST_ASSERT_SUCCESS(inSuite, fIdx1PublicKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
            }
        }

        // Add Fabric 2222 Node Id 66, no ICAC
        {
            FabricId fabricId = 2222;
            NodeId nodeId     = 66;

            uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
            MutableByteSpan csrSpan{ csrBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

            NL_TEST_ASSERT_SUCCESS(
                inSuite, fabricCertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
            ByteSpan rcac = fabricCertAuthority.GetRcac();
            ByteSpan noc  = fabricCertAuthority.GetNoc();

            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT_SUCCESS(
                inSuite, fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, ByteSpan{}, kVendorId, &newFabricIndex));
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
            NL_TEST_ASSERT(inSuite, newFabricIndex == 2);

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

            // Validate contents
            const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
            NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
            if (fabricInfo != nullptr)
            {
                Credentials::ChipCertificateSet certificates;
                NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
                NL_TEST_ASSERT_SUCCESS(inSuite,
                                       certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
                Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 66);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 2222);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

                Crypto::P256PublicKey rootPublicKeyOfFabric;
                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
                NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
            }

            // Validate that fabric has the correct operational key by verifying a signature
            {
                Crypto::P256ECDSASignature sig;
                uint8_t message[] = { 'm', 's', 'g' };

                NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), fIdx2PublicKey));

                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(newFabricIndex, ByteSpan{ message }, sig));
                NL_TEST_ASSERT_SUCCESS(inSuite, fIdx2PublicKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
            }
        }

        NL_TEST_ASSERT(inSuite, fabricTable.FabricCount() == 2);

        // Verify we can now see 2 fabrics with the iterator
        {
            size_t numFabricsIterated = 0;
            bool saw1                 = false;
            bool saw2                 = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 55);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 1111);
                    saw1 = true;
                }
                if (iterFabricInfo.GetFabricIndex() == 2)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 66);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 2222);
                    saw2 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 2);
            NL_TEST_ASSERT(inSuite, saw1 == true);
            NL_TEST_ASSERT(inSuite, saw2 == true);
        }

        // Next fabric index should now be 3, since we added 1 and 2 above.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 3);
        }
    }

    // Global: Last known good time + fabric index = 2
    // Fabric 1111: Metadata, 1 opkey, RCAC/ICAC/NOC = 5
    // Fabric 2222: Metadata, 1 opkey, RCAC/NOC = 4
    NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == (2 + 5 + 4));

    // Second scope: Validate that a fresh FabricTable loads the previously committed fabrics on Init.
    {
        // Initialize a FabricTable
        ScopedFabricTable fabricTableHolder;
        NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
        FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);

        // Verify we can see 2 fabrics with the iterator
        {
            size_t numFabricsIterated = 0;
            bool saw1                 = false;
            bool saw2                 = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 55);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 1111);
                    saw1 = true;
                }
                if (iterFabricInfo.GetFabricIndex() == 2)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 66);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 2222);
                    saw2 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 2);
            NL_TEST_ASSERT(inSuite, saw1 == true);
            NL_TEST_ASSERT(inSuite, saw2 == true);
        }

        // Validate contents of Fabric 2222
        {
            uint8_t rcacBuf[Credentials::kMaxCHIPCertLength];
            MutableByteSpan rcacSpan{ rcacBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootCert(2, rcacSpan));

            const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
            NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
            if (fabricInfo != nullptr)
            {
                Credentials::ChipCertificateSet certificates;
                NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
                NL_TEST_ASSERT_SUCCESS(inSuite,
                                       certificates.LoadCert(rcacSpan, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
                Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 66);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 2222);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

                Crypto::P256PublicKey rootPublicKeyOfFabric;
                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(2, rootPublicKeyOfFabric));
                NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
            }

            // Validate that fabric has the correct operational key by verifying a signature
            {
                Crypto::P256ECDSASignature sig;
                uint8_t message[] = { 'm', 's', 'g' };

                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(2, ByteSpan{ message }, sig));
                NL_TEST_ASSERT_SUCCESS(inSuite, fIdx2PublicKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
            }
        }

        // Validate contents of Fabric 1111
        {
            uint8_t rcacBuf[Credentials::kMaxCHIPCertLength];
            MutableByteSpan rcacSpan{ rcacBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootCert(1, rcacSpan));

            const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
            NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
            if (fabricInfo != nullptr)
            {
                Credentials::ChipCertificateSet certificates;
                NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
                NL_TEST_ASSERT_SUCCESS(inSuite,
                                       certificates.LoadCert(rcacSpan, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
                Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

                Crypto::P256PublicKey rootPublicKeyOfFabric;
                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(1, rootPublicKeyOfFabric));
                NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
            }

            // Validate that fabric has the correct operational key by verifying a signature
            {
                Crypto::P256ECDSASignature sig;
                uint8_t message[] = { 'm', 's', 'g' };

                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(1, ByteSpan{ message }, sig));
                NL_TEST_ASSERT_SUCCESS(inSuite, fIdx1PublicKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
            }

            // Validate that signing with Fabric index 2 fails to verify with fabric index 1
            {
                Crypto::P256ECDSASignature sig;
                uint8_t message[] = { 'm', 's', 'g' };

                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(2, ByteSpan{ message }, sig));
                NL_TEST_ASSERT(inSuite,
                               fIdx1PublicKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig) ==
                                   CHIP_ERROR_INVALID_SIGNATURE);
            }
        }

        // Validate that next fabric index is still 3;
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 3);
        }
    }
}

void TestAddNocFailSafe(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabric11CertAuthority;
    Credentials::TestOnlyLocalCertificateAuthority fabric44CertAuthority;

    chip::TestPersistentStorageDelegate storage;

    NL_TEST_ASSERT(inSuite, fabric11CertAuthority.Init().IsSuccess());
    NL_TEST_ASSERT(inSuite, fabric44CertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    size_t numFabricsIterated = 0;

    size_t numStorageKeysAtStart = storage.GetNumKeys();

    // Sequence 1: Add node ID 55 on fabric 11, see that pending works, and that revert works
    {
        FabricId fabricId = 11;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric11CertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabric11CertAuthority.GetRcac();
        ByteSpan noc  = fabric11CertAuthority.GetNoc();

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;

        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 1);
        }

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, ByteSpan{}, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageKeysAtStart); // Nothing yet

        // Validate iterator sees pending
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == nodeId);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == fabricId);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }

        // Revert, should see nothing yet
        fabricTable.RevertPendingFabricData();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

        // No started except fabric index metadata
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == (numStorageKeysAtStart + 1));

        // Validate iterator sees nothing
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 0);
            NL_TEST_ASSERT(inSuite, saw1 == false);
        }

        // Validate next fabric index has not changed.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 1);
        }
    }

    size_t numStorageAfterRevert = storage.GetNumKeys();

    // Sequence 2: Add node ID 999 on fabric 44, using operational keystore and ICAC --> Yield fabricIndex 1
    {
        FabricId fabricId = 44;
        NodeId nodeId     = 999;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric44CertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabric44CertAuthority.GetRcac();
        ByteSpan icac = fabric44CertAuthority.GetIcac();
        ByteSpan noc  = fabric44CertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);
        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageAfterRevert);

        // Commit, now storage should have keys
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(),
                              (numStorageAfterRevert + 5)); // 3 opcerts + fabric metadata + 1 operational key

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == newFabricIndex);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == nodeId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == fabricId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        {
            Crypto::P256ECDSASignature sig;
            uint8_t message[] = { 'm', 's', 'g' };

            Crypto::P256PublicKey nocPubKey;
            NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), nocPubKey));

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(newFabricIndex, ByteSpan{ message }, sig));
            NL_TEST_ASSERT_SUCCESS(inSuite, nocPubKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
        }

        // Verify we can now see the fabric with the iterator
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 999);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }
    }

    size_t numStorageAfterAdd = storage.GetNumKeys();

    // Sequence 3: Do a RevertPendingFabricData() again, see that it doesn't affect existing fabric

    {
        // Revert, should should look like a no-op
        fabricTable.RevertPendingFabricData();

        // No change of storage
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageAfterAdd);

        // Verify we can still see the fabric with the iterator
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 999);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }
    }
}

void TestUpdateNocFailSafe(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabric11CertAuthority;
    Credentials::TestOnlyLocalCertificateAuthority fabric44CertAuthority;

    chip::TestPersistentStorageDelegate storage;

    storage.SetLoggingLevel(chip::TestPersistentStorageDelegate::LoggingLevel::kLogMutation);

    NL_TEST_ASSERT(inSuite, fabric11CertAuthority.Init().IsSuccess());
    NL_TEST_ASSERT(inSuite, fabric44CertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    size_t numFabricsIterated = 0;

    size_t numStorageKeysAtStart = storage.GetNumKeys();

    // Sequence 1: Add node ID 999 on fabric 44, using operational keystore and ICAC --> Yield fabricIndex 1
    {
        FabricId fabricId = 44;
        NodeId nodeId     = 999;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric44CertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabric44CertAuthority.GetRcac();
        ByteSpan icac = fabric44CertAuthority.GetIcac();
        ByteSpan noc  = fabric44CertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);
        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageKeysAtStart);

        // Commit, now storage should have keys
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(),
                              (numStorageKeysAtStart + 6)); // 3 opcerts + fabric metadata + 1 operational key + LKGT + fabric index

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == newFabricIndex);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == nodeId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == fabricId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        {
            Crypto::P256ECDSASignature sig;
            uint8_t message[] = { 'm', 's', 'g' };

            Crypto::P256PublicKey nocPubKey;
            NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), nocPubKey));

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(newFabricIndex, ByteSpan{ message }, sig));
            NL_TEST_ASSERT_SUCCESS(inSuite, nocPubKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
        }

        // Verify we can now see the fabric with the iterator
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 999);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }
    }

    size_t numStorageAfterAdd = storage.GetNumKeys();

    // Sequence 2: Do an Update to NodeId 1000, with no ICAC, but revert it
    {
        FabricId fabricId       = 44;
        NodeId nodeId           = 1000;
        FabricIndex fabricIndex = 1;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };

        // Make sure to tag fabric index to pending opkey: otherwise the UpdateNOC fails
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AllocatePendingOperationalKey(chip::MakeOptional(static_cast<FabricIndex>(1)), csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric44CertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabric44CertAuthority.GetRcac();
        ByteSpan noc  = fabric44CertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.UpdatePendingFabricWithOperationalKeystore(1, noc, ByteSpan{}));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageAfterAdd);

        // Validate iterator sees the pending data
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 1000);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.ShouldAdvertiseIdentity());
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }

        // Revert, should see Node ID 999 again
        fabricTable.RevertPendingFabricData();
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(), numStorageAfterAdd);

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == fabricIndex);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 999);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 44);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(fabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        {
            uint8_t nocBuf[Credentials::kMaxCHIPCertLength];
            MutableByteSpan nocSpan{ nocBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchNOCCert(1, nocSpan));

            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(nocSpan, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey nocPubKey(certificates.GetCertSet()[0].mPublicKey);

            Crypto::P256ECDSASignature sig;
            uint8_t message[] = { 'm', 's', 'g' };

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(fabricIndex, ByteSpan{ message }, sig));
            NL_TEST_ASSERT_SUCCESS(inSuite, nocPubKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
        }

        // Validate iterator sees the previous fabric
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 999);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }
    }

    // Sequence 3: Do an Update to NodeId 1001, with no ICAC, but commit it
    {
        FabricId fabricId       = 44;
        NodeId nodeId           = 1001;
        FabricIndex fabricIndex = 1;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };

        // Make sure to tag fabric index to pending opkey: otherwise the UpdateNOC fails
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AllocatePendingOperationalKey(chip::MakeOptional(static_cast<FabricIndex>(1)), csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric44CertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabric44CertAuthority.GetRcac();
        ByteSpan noc  = fabric44CertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.UpdatePendingFabricWithOperationalKeystore(1, noc, ByteSpan{}));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageAfterAdd);

        // Validate iterator sees the pending data
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 1001);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.ShouldAdvertiseIdentity());
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }

        // Commit, should see Node ID 1001, and 1 less cert in the storage
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(), numStorageAfterAdd - 1);

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == fabricIndex);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 1001);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 44);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(fabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        {
            Crypto::P256PublicKey nocPubKey;
            NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), nocPubKey));

            Crypto::P256ECDSASignature sig;
            uint8_t message[] = { 'm', 's', 'g' };

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(fabricIndex, ByteSpan{ message }, sig));
            NL_TEST_ASSERT_SUCCESS(inSuite, nocPubKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
        }

        // Validate iterator sees the updated fabric
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 1001);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }
    }
}

void TestAddRootCertFailSafe(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabric11CertAuthority;

    chip::TestPersistentStorageDelegate storage;

    NL_TEST_ASSERT(inSuite, fabric11CertAuthority.Init().IsSuccess());

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    // Add a root cert, see that pending works, and that revert works
    {
        ByteSpan rcac = fabric11CertAuthority.GetRcac();

        uint8_t rcacBuf[Credentials::kMaxCHIPCertLength];
        {
            // No pending root cert yet.
            MutableByteSpan fetchedSpan{ rcacBuf };
            NL_TEST_ASSERT(inSuite, fabricTable.FetchPendingNonFabricAssociatedRootCert(fetchedSpan) == CHIP_ERROR_NOT_FOUND);
        }

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        {
            // Now have a pending root cert.
            MutableByteSpan fetchedSpan{ rcacBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchPendingNonFabricAssociatedRootCert(fetchedSpan));
            NL_TEST_ASSERT(inSuite, fetchedSpan.data_equal(rcac));
        }

        // Revert
        fabricTable.RevertPendingFabricData();

        {
            // No pending root cert anymore.
            MutableByteSpan fetchedSpan{ rcacBuf };
            NL_TEST_ASSERT(inSuite, fabricTable.FetchPendingNonFabricAssociatedRootCert(fetchedSpan) == CHIP_ERROR_NOT_FOUND);
        }
    }
}

void TestSequenceErrors(nlTestSuite * inSuite, void * inContext)
{
    // TODO: Write test
}

void TestFabricLabelChange(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority;

    chip::TestPersistentStorageDelegate storage;
    NL_TEST_ASSERT(inSuite, fabricCertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    // First scope: add FabricID 1111, node ID 55
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabricCertAuthority.GetRcac();
        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);
        }
    }
    size_t numStorageKeysAfterFirstAdd = storage.GetNumKeys();
    NL_TEST_ASSERT(inSuite, numStorageKeysAfterFirstAdd == 7); // Metadata, index, 3 certs, 1 opkey, last known good time

    // Second scope: set FabricLabel to "acme fabric", make sure it cannot be reverted
    {
        // Fabric label starts unset from prior scope
        CharSpan fabricLabel = "placeholder"_span;

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.GetFabricLabel(1, fabricLabel));
        NL_TEST_ASSERT(inSuite, fabricLabel.size() == 0);

        // Set a valid name
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SetFabricLabel(1, "acme fabric"_span));
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.GetFabricLabel(1, fabricLabel));
        NL_TEST_ASSERT(inSuite, fabricLabel.data_equal("acme fabric"_span) == true);

        // Revert pending fabric data. Should not revert name since nothing pending.
        fabricTable.RevertPendingFabricData();

        fabricLabel = "placeholder"_span;
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.GetFabricLabel(1, fabricLabel));
        NL_TEST_ASSERT(inSuite, fabricLabel.data_equal("acme fabric"_span) == true);

        // Verify we fail to set too large a label (> kFabricLabelMaxLengthInBytes)
        CharSpan fabricLabelTooBig = "012345678901234567890123456789123456"_span;
        NL_TEST_ASSERT(inSuite, fabricLabelTooBig.size() > chip::kFabricLabelMaxLengthInBytes);

        NL_TEST_ASSERT(inSuite, fabricTable.SetFabricLabel(1, fabricLabelTooBig) == CHIP_ERROR_INVALID_ARGUMENT);

        fabricLabel = "placeholder"_span;
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.GetFabricLabel(1, fabricLabel));
        NL_TEST_ASSERT(inSuite, fabricLabel.data_equal("acme fabric"_span) == true);
    }

    // Third scope: set fabric label after an update, it sticks, but then goes back after revert
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 66; // Update node ID from 55 to 66

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AllocatePendingOperationalKey(chip::MakeOptional(static_cast<FabricIndex>(1)), csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.UpdatePendingFabricWithOperationalKeystore(1, noc, icac));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        // Validate contents prior to change/revert
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);

        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 66);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);

            CharSpan fabricLabel = fabricInfo->GetFabricLabel();
            NL_TEST_ASSERT(inSuite, fabricLabel.data_equal("acme fabric"_span) == true);
        }

        // Update fabric label
        CharSpan fabricLabel = "placeholder"_span;
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SetFabricLabel(1, "roboto fabric"_span));

        fabricLabel = "placeholder"_span;
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.GetFabricLabel(1, fabricLabel));
        NL_TEST_ASSERT(inSuite, fabricLabel.data_equal("roboto fabric"_span) == true);

        // Revert pending fabric data. Should revert name to "acme fabric"
        fabricTable.RevertPendingFabricData();

        fabricLabel = "placeholder"_span;
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.GetFabricLabel(1, fabricLabel));
        NL_TEST_ASSERT(inSuite, fabricLabel.data_equal("acme fabric"_span) == true);
    }
}

void TestCompressedFabricId(nlTestSuite * inSuite, void * inContext)
{
    // TODO: Write test
}

void TestFabricLookup(nlTestSuite * inSuite, void * inContext)
{
    // Initialize a fabric table.
    chip::TestPersistentStorageDelegate testStorage;
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();
    NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit = */ true) == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite,
                   LoadTestFabric_Node02_01(inSuite, fabricTable, /* doCommit = */ true, FabricTable::AdvertiseIdentity::No) ==
                       CHIP_NO_ERROR);

    // Attempt lookup of the Root01 fabric.
    {
        Crypto::P256PublicKey key;
        NL_TEST_ASSERT(inSuite, key.Length() >= TestCerts::sTestCert_Root01_PublicKey.size());
        if (key.Length() < TestCerts::sTestCert_Root01_PublicKey.size())
        {
            return;
        }
        memcpy(key.Bytes(), TestCerts::sTestCert_Root01_PublicKey.data(), TestCerts::sTestCert_Root01_PublicKey.size());
        auto fabricInfo = fabricTable.FindFabric(key, 0xFAB000000000001D);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo == nullptr)
        {
            return;
        }
        NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
        NL_TEST_ASSERT(inSuite, fabricInfo->ShouldAdvertiseIdentity());
    }

    // Attempt lookup of the Root02 fabric.
    {
        Crypto::P256PublicKey key;
        NL_TEST_ASSERT(inSuite, key.Length() >= TestCerts::sTestCert_Root02_PublicKey.size());
        if (key.Length() < TestCerts::sTestCert_Root02_PublicKey.size())
        {
            return;
        }
        memcpy(key.Bytes(), TestCerts::sTestCert_Root02_PublicKey.data(), TestCerts::sTestCert_Root02_PublicKey.size());
        auto fabricInfo = fabricTable.FindFabric(key, 0xFAB000000000001D);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo == nullptr)
        {
            return;
        }
        NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
        NL_TEST_ASSERT(inSuite, !fabricInfo->ShouldAdvertiseIdentity());
    }

    // Attempt lookup of FabricIndex 0 --> should always fail.
    {
        NL_TEST_ASSERT(inSuite, fabricTable.FindFabricWithIndex(0) == nullptr);
    }
}

void TestFetchCATs(nlTestSuite * inSuite, void * inContext)
{
    // Initialize a fabric table.
    chip::TestPersistentStorageDelegate testStorage;
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();
    NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit = */ true) == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, LoadTestFabric_Node02_01(inSuite, fabricTable, /* doCommit = */ true) == CHIP_NO_ERROR);

    // Attempt Fetching fabric index 1 CATs and verify contents.
    {
        CATValues cats;
        NL_TEST_ASSERT(inSuite, fabricTable.FetchCATs(1, cats) == CHIP_NO_ERROR);
        // Test fabric NOCs don't contain any CATs.
        NL_TEST_ASSERT(inSuite, cats == kUndefinedCATs);
    }

    // Attempt Fetching fabric index 2 CATs and verify contents.
    {
        CATValues cats;
        NL_TEST_ASSERT(inSuite, fabricTable.FetchCATs(2, cats) == CHIP_NO_ERROR);
        // Test fabric NOCs don't contain any CATs.
        NL_TEST_ASSERT(inSuite, cats == kUndefinedCATs);
    }

    // TODO(#20335): Add test cases for NOCs that actually embed CATs
}

// Validate that adding the same fabric twice fails (same root, same FabricId)
void TestAddNocRootCollision(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority;

    chip::TestPersistentStorageDelegate storage;
    NL_TEST_ASSERT(inSuite, fabricCertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    // First scope: add FabricID 1111, node ID 55
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabricCertAuthority.GetRcac();
        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex,
                                                                                      FabricTable::AdvertiseIdentity::No));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, !fabricInfo->ShouldAdvertiseIdentity());

            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }
    }
    size_t numStorageKeysAfterFirstAdd = storage.GetNumKeys();
    NL_TEST_ASSERT(inSuite, numStorageKeysAfterFirstAdd == 7); // Metadata, index, 3 certs, 1 opkey, last known good time

    // Second scope: add FabricID 1111, node ID 55 *again* --> Collision of Root/FabricID with existing
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabricCertAuthority.GetRcac();
        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT(inSuite,
                       fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex) ==
                           CHIP_ERROR_FABRIC_EXISTS);
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        CHIP_ERROR err = fabricTable.CommitPendingFabricData();
        printf("err = %" CHIP_ERROR_FORMAT "\n", err.Format());
        NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INCORRECT_STATE);

        // Validate contents of Fabric index 1 still valid
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(1, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }
    }

    // Ensure no new persisted keys after failed colliding add
    NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageKeysAfterFirstAdd);

    // Third scope: add FabricID 2222, node ID 55 --> Not colliding, should work. The failing commit above]
    // should have been enough of a revert that this scope succeeds without any additional revert.
    {
        FabricId fabricId = 2222;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabricCertAuthority.GetRcac();
        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 2);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->ShouldAdvertiseIdentity());

            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 2222);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }
    }
    size_t numStorageKeysAfterSecondAdd = storage.GetNumKeys();

    NL_TEST_ASSERT(inSuite, numStorageKeysAfterSecondAdd == (numStorageKeysAfterFirstAdd + 5)); // Metadata, 3 certs, 1 opkey
}

void TestInvalidChaining(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority;
    Credentials::TestOnlyLocalCertificateAuthority differentCertAuthority;

    chip::TestPersistentStorageDelegate storage;
    NL_TEST_ASSERT(inSuite, fabricCertAuthority.Init().IsSuccess());
    NL_TEST_ASSERT(inSuite, differentCertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    // Try to add fabric with either the NOC not chaining properly, or ICAC not chaining properly, fail,
    // then succeed with proper chaining
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        // Generate same cert chain from two different roots
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               differentCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());

        ByteSpan rcac = fabricCertAuthority.GetRcac();
        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        ByteSpan otherIcac = differentCertAuthority.GetIcac();
        ByteSpan otherNoc  = differentCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));

        // Add with NOC not chaining to ICAC: fail
        {
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            CHIP_ERROR err = fabricTable.AddNewPendingFabricWithOperationalKeystore(otherNoc, icac, kVendorId, &newFabricIndex);
            NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        }

        // Add with ICAC not chaining to root: fail
        {
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            CHIP_ERROR err = fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, otherIcac, kVendorId, &newFabricIndex);
            NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        }

        // Add with NOC and ICAC chaining together, but not to root: fail
        {
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            CHIP_ERROR err =
                fabricTable.AddNewPendingFabricWithOperationalKeystore(otherNoc, otherIcac, kVendorId, &newFabricIndex);
            NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        }

        // Revert state, start tests without ICAC
        fabricTable.RevertPendingFabricData();

        // Generate same cert chain from two different roots

        csrSpan = MutableByteSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        NL_TEST_ASSERT_SUCCESS(
            inSuite, differentCertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());

        rcac = fabricCertAuthority.GetRcac();
        noc  = fabricCertAuthority.GetNoc();

        otherNoc = differentCertAuthority.GetNoc();

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));

        // Add with NOC not chaining to RCAC: fail
        {
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            CHIP_ERROR err =
                fabricTable.AddNewPendingFabricWithOperationalKeystore(otherNoc, ByteSpan{}, kVendorId, &newFabricIndex);
            NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        }

        // Add properly now
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, ByteSpan{}, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);
        }
    }
}

void TestEphemeralKeys(nlTestSuite * inSuite, void * inContext)
{
    // Initialize a fabric table with operational keystore
    {
        chip::TestPersistentStorageDelegate storage;

        // Initialize a FabricTable
        ScopedFabricTable fabricTableHolder;
        NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
        FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

        Crypto::P256ECDSASignature sig;
        uint8_t message[] = { 'm', 's', 'g' };

        Crypto::P256Keypair * ephemeralKeypair = fabricTable.AllocateEphemeralKeypairForCASE();
        NL_TEST_ASSERT(inSuite, ephemeralKeypair != nullptr);
        NL_TEST_ASSERT_SUCCESS(inSuite, ephemeralKeypair->Initialize(Crypto::ECPKeyTarget::ECDSA));

        NL_TEST_ASSERT_SUCCESS(inSuite, ephemeralKeypair->ECDSA_sign_msg(message, sizeof(message), sig));
        NL_TEST_ASSERT_SUCCESS(inSuite, ephemeralKeypair->Pubkey().ECDSA_validate_msg_signature(message, sizeof(message), sig));

        fabricTable.ReleaseEphemeralKeypair(ephemeralKeypair);
    }

    // Use a fabric table without an operational keystore: should still work
    {
        chip::TestPersistentStorageDelegate storage;

        chip::Credentials::PersistentStorageOpCertStore opCertStore;
        NL_TEST_ASSERT_SUCCESS(inSuite, opCertStore.Init(&storage));

        FabricTable fabricTable;
        FabricTable::InitParams initParams;
        initParams.storage     = &storage;
        initParams.opCertStore = &opCertStore;

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.Init(initParams));

        Crypto::P256ECDSASignature sig;
        uint8_t message[] = { 'm', 's', 'g' };

        Crypto::P256Keypair * ephemeralKeypair = fabricTable.AllocateEphemeralKeypairForCASE();
        NL_TEST_ASSERT(inSuite, ephemeralKeypair != nullptr);
        NL_TEST_ASSERT_SUCCESS(inSuite, ephemeralKeypair->Initialize(Crypto::ECPKeyTarget::ECDSA));

        NL_TEST_ASSERT_SUCCESS(inSuite, ephemeralKeypair->ECDSA_sign_msg(message, sizeof(message), sig));
        NL_TEST_ASSERT_SUCCESS(inSuite, ephemeralKeypair->Pubkey().ECDSA_validate_msg_signature(message, sizeof(message), sig));

        fabricTable.ReleaseEphemeralKeypair(ephemeralKeypair);

        fabricTable.Shutdown();
        opCertStore.Finish();
    }
}

void TestCommitMarker(nlTestSuite * inSuite, void * inContext)
{
    Crypto::P256PublicKey fIdx1PublicKey;
    Crypto::P256PublicKey fIdx2PublicKey;

    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority;

    chip::TestPersistentStorageDelegate storage;

    // Log verbosity on this test helps debug significantly
    storage.SetLoggingLevel(chip::TestPersistentStorageDelegate::LoggingLevel::kLogMutationAndReads);

    NL_TEST_ASSERT(inSuite, fabricCertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    size_t numStorageKeysAfterFirstAdd = 0;

    // First scope: add 2 fabrics with same root:
    //   - FabricID 1111, Node ID 55
    //   - FabricID 2222, Node ID 66
    //      - Abort commit on second fabric
    {
        // Initialize a fabric table
        ScopedFabricTable fabricTableHolder;
        NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
        FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

        NL_TEST_ASSERT(inSuite, fabricTable.GetDeletedFabricFromCommitMarker() == kUndefinedFabricIndex);
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

        // Add Fabric 1111 Node Id 55
        {
            FabricId fabricId = 1111;
            NodeId nodeId     = 55;

            uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
            MutableByteSpan csrSpan{ csrBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

            NL_TEST_ASSERT_SUCCESS(
                inSuite, fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
            ByteSpan rcac = fabricCertAuthority.GetRcac();
            ByteSpan icac = fabricCertAuthority.GetIcac();
            ByteSpan noc  = fabricCertAuthority.GetNoc();

            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
            NL_TEST_ASSERT(inSuite, newFabricIndex == 1);

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

            // Validate contents
            const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
            NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
            if (fabricInfo != nullptr)
            {
                Credentials::ChipCertificateSet certificates;
                NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
                NL_TEST_ASSERT_SUCCESS(inSuite,
                                       certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
                Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

                Crypto::P256PublicKey rootPublicKeyOfFabric;
                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
                NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
            }

            // Validate that fabric has the correct operational key by verifying a signature
            {
                Crypto::P256ECDSASignature sig;
                uint8_t message[] = { 'm', 's', 'g' };

                NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), fIdx1PublicKey));

                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(newFabricIndex, ByteSpan{ message }, sig));
                NL_TEST_ASSERT_SUCCESS(inSuite, fIdx1PublicKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
            }
        }
        numStorageKeysAfterFirstAdd = storage.GetNumKeys();

        NL_TEST_ASSERT(inSuite, numStorageKeysAfterFirstAdd == 7); // Metadata, index, 3 certs, 1 opkey, last known good time

        // The following test requires test methods not available on all builds.
        // TODO: Debug why some CI jobs don't set it properly.
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST

        // Add Fabric 2222 Node Id 66, no ICAC *** AND ABORT COMMIT ***
        {
            FabricId fabricId = 2222;
            NodeId nodeId     = 66;

            uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
            MutableByteSpan csrSpan{ csrBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

            NL_TEST_ASSERT_SUCCESS(
                inSuite, fabricCertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
            ByteSpan rcac = fabricCertAuthority.GetRcac();
            ByteSpan noc  = fabricCertAuthority.GetNoc();

            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT_SUCCESS(
                inSuite, fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, ByteSpan{}, kVendorId, &newFabricIndex));
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
            NL_TEST_ASSERT(inSuite, newFabricIndex == 2);

            // Validate contents of pending
            const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
            NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
            if (fabricInfo != nullptr)
            {
                Credentials::ChipCertificateSet certificates;
                NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
                NL_TEST_ASSERT_SUCCESS(inSuite,
                                       certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
                Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 66);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 2222);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

                Crypto::P256PublicKey rootPublicKeyOfFabric;
                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
                NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
            }

            // Make sure no additional storage yet
            NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageKeysAfterFirstAdd);

            // --> FORCE AN ERROR ON COMMIT that will BYPASS commit clean-up (similar to reboot during commit)
            fabricTable.SetForceAbortCommitForTest(true);
            NL_TEST_ASSERT(inSuite, fabricTable.CommitPendingFabricData() == CHIP_ERROR_INTERNAL);

            // Check that there are more keys now, partially committed: at least a Commit Marker (+1)
            // and some more keys from the aborted process.
            NL_TEST_ASSERT(inSuite, storage.GetNumKeys() > (numStorageKeysAfterFirstAdd + 1));
        }
#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST
    }

#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
    {
        storage.DumpKeys();

        // Initialize a FabricTable again. Make sure it succeeds in initing.
        ScopedFabricTable fabricTableHolder;

        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() > (numStorageKeysAfterFirstAdd + 1));

        NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
        FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

        // Make sure that after init, the fabricTable has only 1 fabric
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        // Make sure it caught the last partially committed fabric
        NL_TEST_ASSERT(inSuite, fabricTable.GetDeletedFabricFromCommitMarker() == 2);

        // Second read must return kUndefinedFabricIndex
        NL_TEST_ASSERT(inSuite, fabricTable.GetDeletedFabricFromCommitMarker() == kUndefinedFabricIndex);

        {
            // Here we would do other clean-ups (e.g. see Server.cpp that uses the above) and then
            // clear the commit marker after.
            fabricTable.ClearCommitMarker();
        }

        // Make sure that all other pending storage got deleted
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageKeysAfterFirstAdd);

        // Verify we can only see 1 fabric with the iterator
        {
            size_t numFabricsIterated = 0;
            bool saw1                 = false;
            bool saw2                 = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 55);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 1111);
                    saw1 = true;
                }
                if (iterFabricInfo.GetFabricIndex() == 2)
                {
                    saw2 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
            NL_TEST_ASSERT(inSuite, saw2 == false);
        }
    }
#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST
}

// Test Suite

/**
 *  Test Suite that lists all the test functions.
 */
// clang-format off
static const nlTest sTests[] =
{
    NL_TEST_DEF("Last Known Good Time Init", TestLastKnownGoodTimeInit),
    NL_TEST_DEF("Update Last Known Good Time", TestUpdateLastKnownGoodTime),
    NL_TEST_DEF("Set Last Known Good Time", TestSetLastKnownGoodTime),
    NL_TEST_DEF("Test basic AddNOC flow", TestBasicAddNocUpdateNocFlow),
    NL_TEST_DEF("Test adding multiple fabrics that chain to same root, different fabric ID", TestAddMultipleSameRootDifferentFabricId),
    NL_TEST_DEF("Test adding multiple fabrics that chain to different roots, same fabric ID", TestAddMultipleSameFabricIdDifferentRoot),
    NL_TEST_DEF("Validate fabrics are loaded from persistence at FabricTable::init", TestPersistence),
    NL_TEST_DEF("Test fail-safe handling during AddNOC", TestAddNocFailSafe),
    NL_TEST_DEF("Test fail-safe handling during UpdateNoc", TestUpdateNocFailSafe),
    NL_TEST_DEF("Test fail-safe handling for root cert", TestAddRootCertFailSafe),
    NL_TEST_DEF("Test interlock sequencing errors", TestSequenceErrors),
    NL_TEST_DEF("Test fabric label changes", TestFabricLabelChange),
    NL_TEST_DEF("Test compressed fabric ID is properly generated", TestCompressedFabricId),
    NL_TEST_DEF("Test fabric lookup by <root public key, fabric ID>", TestFabricLookup),
    NL_TEST_DEF("Test Fetching CATs", TestFetchCATs),
    NL_TEST_DEF("Test AddNOC root collision", TestAddNocRootCollision),
    NL_TEST_DEF("Test invalid chaining in AddNOC and UpdateNOC", TestInvalidChaining),
    NL_TEST_DEF("Test ephemeral keys allocation", TestEphemeralKeys),
    NL_TEST_DEF("Test proper detection of Commit Marker on init", TestCommitMarker),
    NL_TEST_DEF("Test colliding fabrics in the fabric table", TestCollidingFabrics),

    NL_TEST_SENTINEL()
};

// clang-format on

int TestFabricTable_Setup(void * inContext);
int TestFabricTable_Teardown(void * inContext);

// clang-format off
static nlTestSuite sSuite =
{
    "Test-CHIP-FabricTable",
    &sTests[0],
    TestFabricTable_Setup,
    TestFabricTable_Teardown,
};
// clang-format on

/**
 *  Set up the test suite.
 */
int TestFabricTable_Setup(void * inContext)
{
    DeviceLayer::SetConfigurationMgr(&DeviceLayer::ConfigurationManagerImpl::GetDefaultInstance());
    return chip::Platform::MemoryInit() == CHIP_NO_ERROR ? SUCCESS : FAILURE;
}

/**
 *  Tear down the test suite.
 */
int TestFabricTable_Teardown(void * inContext)
{
    chip::Platform::MemoryShutdown();
    return SUCCESS;
}

} // namespace

/**
 *  Main
 */
int TestFabricTable()
{
    // Run test suit against one context
    nlTestRunner(&sSuite, nullptr);

    return (nlTestRunnerStats(&sSuite));
}

CHIP_REGISTER_TEST_SUITE(TestFabricTable)
