blob: 1d693104d4aa0026efc62863b6d60055d10cdd34 [file] [log] [blame]
/*
*
* Copyright (c) 2021 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "access/AccessControl.h"
#include "access/examples/ExampleAccessControlDelegate.h"
#include <lib/core/CHIPCore.h>
#include <lib/support/UnitTestRegistration.h>
#include <nlunit-test.h>
namespace {
using namespace chip;
using namespace chip::Access;
using Entry = AccessControl::Entry;
using EntryIterator = AccessControl::EntryIterator;
using Target = Entry::Target;
AccessControl accessControl(Examples::GetAccessControlDelegate());
constexpr ClusterId kOnOffCluster = 0x0006;
constexpr ClusterId kLevelControlCluster = 0x0008;
constexpr ClusterId kAccessControlCluster = 0x001F;
constexpr ClusterId kColorControlCluster = 0x0300;
constexpr DeviceTypeId kColorLightDeviceType = 0x0102;
constexpr NodeId kPaseVerifier0 = 0xFFFFFFFB0000'0000;
constexpr NodeId kPaseVerifier1 = 0xFFFFFFFB0000'0001;
constexpr NodeId kPaseVerifier3 = 0xFFFFFFFB0000'0003;
constexpr NodeId kPaseVerifier5 = 0xFFFFFFFB0000'0005;
constexpr NodeId kGroup2 = 0xFFFFFFFFFFFF'0002;
constexpr NodeId kGroup4 = 0xFFFFFFFFFFFF'0004;
constexpr NodeId kGroup6 = 0xFFFFFFFFFFFF'0006;
constexpr NodeId kGroup8 = 0xFFFFFFFFFFFF'0008;
constexpr AuthMode authModes[] = { AuthMode::kPase, AuthMode::kCase, AuthMode::kGroup };
constexpr FabricIndex fabricIndexes[] = { 1, 2, 3 };
constexpr Privilege privileges[] = { Privilege::kView, Privilege::kProxyView, Privilege::kOperate, Privilege::kManage,
Privilege::kAdminister };
constexpr NodeId subjects[][3] = { {
kPaseVerifier0,
kPaseVerifier3,
kPaseVerifier5,
},
{
0x0123456789ABCDEF, // CASE node
0xFFFFFFFD'00000001, // CAT1
0xFFFFFFFC'00000002, // CAT2
},
{
kGroup4,
kGroup6,
kGroup8,
} };
constexpr Target targets[] = {
{ .flags = Target::kCluster, .cluster = kOnOffCluster },
{ .flags = Target::kEndpoint, .endpoint = 3 },
{ .flags = Target::kDeviceType, .deviceType = kColorLightDeviceType },
};
bool operator==(const Target & a, const Target & b)
{
if (a.flags != b.flags)
return false;
if ((a.flags & Target::kCluster) && a.cluster != b.cluster)
return false;
if ((a.flags & Target::kEndpoint) && a.endpoint != b.endpoint)
return false;
if ((a.flags & Target::kDeviceType) && a.deviceType != b.deviceType)
return false;
return true;
}
bool operator!=(const Target & a, const Target & b)
{
return !(a == b);
}
struct EntryData
{
static constexpr int kMaxSubjects = 3;
static constexpr int kMaxTargets = 3;
FabricIndex fabricIndex = kUndefinedFabricIndex;
Privilege privilege = Privilege::kView;
AuthMode authMode = AuthMode::kNone;
NodeId subjects[kMaxSubjects] = { 0 };
Target targets[kMaxTargets] = { { 0 } };
void Clear() { memset(this, 0, sizeof(*this)); }
bool IsEmpty() const { return authMode == AuthMode::kNone; }
size_t GetSubjectCount() const
{
size_t count = 0;
for (auto & subject : subjects)
{
if (subject == kUndefinedNodeId)
{
break;
}
count++;
}
return count;
}
void AddSubject(size_t * index, NodeId subject)
{
size_t count = GetSubjectCount();
if (count < kMaxSubjects)
{
subjects[count] = subject;
if (index)
{
*index = count;
}
}
}
void RemoveSubject(size_t index)
{
size_t count = GetSubjectCount();
if (index < count)
{
while (++index < kMaxSubjects)
{
subjects[index - 1] = subjects[index];
}
subjects[kMaxSubjects - 1] = { 0 };
}
}
size_t GetTargetCount() const
{
size_t count = 0;
for (auto & target : targets)
{
if (target.flags == 0)
{
break;
}
count++;
}
return count;
}
void AddTarget(size_t * index, const Target & target)
{
size_t count = GetTargetCount();
if (count < kMaxTargets)
{
targets[count] = target;
if (index)
{
*index = count;
}
}
}
void RemoveTarget(size_t index)
{
size_t count = GetTargetCount();
if (index < count)
{
while (++index < kMaxTargets)
{
targets[index - 1] = targets[index];
}
targets[kMaxTargets - 1] = { 0 };
}
}
};
CHIP_ERROR CompareEntry(const Entry & entry, const EntryData & entryData)
{
AuthMode authMode = AuthMode::kNone;
ReturnErrorOnFailure(entry.GetAuthMode(authMode));
ReturnErrorCodeIf(authMode != entryData.authMode, CHIP_ERROR_INCORRECT_STATE);
FabricIndex fabricIndex = kUndefinedFabricIndex;
ReturnErrorOnFailure(entry.GetFabricIndex(fabricIndex));
ReturnErrorCodeIf(fabricIndex != entryData.fabricIndex, CHIP_ERROR_INCORRECT_STATE);
Privilege privilege = Privilege::kView;
ReturnErrorOnFailure(entry.GetPrivilege(privilege));
ReturnErrorCodeIf(privilege != entryData.privilege, CHIP_ERROR_INCORRECT_STATE);
size_t subjectCount = 0;
ReturnErrorOnFailure(entry.GetSubjectCount(subjectCount));
ReturnErrorCodeIf(subjectCount != entryData.GetSubjectCount(), CHIP_ERROR_INCORRECT_STATE);
for (size_t i = 0; i < subjectCount; ++i)
{
NodeId subject = kUndefinedNodeId;
ReturnErrorOnFailure(entry.GetSubject(i, subject));
ReturnErrorCodeIf(subject != entryData.subjects[i], CHIP_ERROR_INCORRECT_STATE);
}
size_t targetCount = 0;
ReturnErrorOnFailure(entry.GetTargetCount(targetCount));
ReturnErrorCodeIf(targetCount != entryData.GetTargetCount(), CHIP_ERROR_INCORRECT_STATE);
for (size_t i = 0; i < targetCount; ++i)
{
Target target;
ReturnErrorOnFailure(entry.GetTarget(i, target));
ReturnErrorCodeIf(target != entryData.targets[i], CHIP_ERROR_INCORRECT_STATE);
}
return CHIP_NO_ERROR;
}
CHIP_ERROR LoadEntry(Entry & entry, const EntryData & entryData)
{
ReturnErrorOnFailure(entry.SetAuthMode(entryData.authMode));
ReturnErrorOnFailure(entry.SetFabricIndex(entryData.fabricIndex));
ReturnErrorOnFailure(entry.SetPrivilege(entryData.privilege));
for (size_t i = 0; i < entryData.GetSubjectCount(); ++i)
{
ReturnErrorOnFailure(entry.AddSubject(nullptr, entryData.subjects[i]));
}
for (size_t i = 0; i < entryData.GetTargetCount(); ++i)
{
ReturnErrorOnFailure(entry.AddTarget(nullptr, entryData.targets[i]));
}
return CHIP_NO_ERROR;
}
CHIP_ERROR ClearAccessControl(AccessControl & ac)
{
CHIP_ERROR err;
do
{
err = accessControl.DeleteEntry(0);
} while (err == CHIP_NO_ERROR);
return CHIP_NO_ERROR;
}
CHIP_ERROR CompareAccessControl(AccessControl & ac, const EntryData * entryData, size_t count)
{
Entry entry;
for (size_t i = 0; i < count; ++i, ++entryData)
{
ReturnErrorOnFailure(ac.ReadEntry(i, entry));
ReturnErrorOnFailure(CompareEntry(entry, *entryData));
}
ReturnErrorCodeIf(ac.ReadEntry(count, entry) == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE);
return CHIP_NO_ERROR;
}
CHIP_ERROR LoadAccessControl(AccessControl & ac, const EntryData * entryData, size_t count)
{
Entry entry;
for (size_t i = 0; i < count; ++i, ++entryData)
{
ReturnErrorOnFailure(ac.PrepareEntry(entry));
ReturnErrorOnFailure(LoadEntry(entry, *entryData));
ReturnErrorOnFailure(ac.CreateEntry(nullptr, entry));
}
return CHIP_NO_ERROR;
}
constexpr EntryData entryData1[] = {
{
.fabricIndex = 1,
.privilege = Privilege::kAdminister,
.authMode = AuthMode::kCase,
.subjects = { 0x1111111111111111 },
},
{
.fabricIndex = 1,
.privilege = Privilege::kView,
.authMode = AuthMode::kCase,
},
{
.fabricIndex = 2,
.privilege = Privilege::kAdminister,
.authMode = AuthMode::kCase,
.subjects = { 0x2222222222222222 },
},
{
.fabricIndex = 1,
.privilege = Privilege::kOperate,
.authMode = AuthMode::kCase,
.targets = { { .flags = Target::kCluster, .cluster = kOnOffCluster } },
},
{
.fabricIndex = 2,
.privilege = Privilege::kManage,
.authMode = AuthMode::kPase,
.subjects = { kPaseVerifier1 },
.targets = { { .flags = Target::kCluster | Target::kEndpoint, .cluster = kOnOffCluster, .endpoint = 2 } },
},
{
.fabricIndex = 2,
.privilege = Privilege::kProxyView,
.authMode = AuthMode::kGroup,
.subjects = { kGroup2 },
.targets = { { .flags = Target::kCluster | Target::kEndpoint, .cluster = kLevelControlCluster, .endpoint = 1 },
{ .flags = Target::kCluster, .cluster = kOnOffCluster },
{ .flags = Target::kEndpoint, .endpoint = 2 } },
},
};
struct CheckData
{
SubjectDescriptor subjectDescriptor;
RequestPath requestPath;
Privilege privilege;
bool allow;
};
constexpr CheckData checkData1[] =
{
// Checks for entry 0
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kCase, .subjects = { 0x1111111111111111 }, },
.requestPath = { .cluster = kAccessControlCluster, .endpoint = 0 },
.privilege = Privilege::kAdminister,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kCase, .subjects = { 0x1111111111111111 }, },
.requestPath = { .cluster = 1, .endpoint = 2 },
.privilege = Privilege::kManage,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kCase, .subjects = { 0x1111111111111111 }, },
.requestPath = { .cluster = 3, .endpoint = 4 },
.privilege = Privilege::kOperate,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kCase, .subjects = { 0x1111111111111111 }, },
.requestPath = { .cluster = 5, .endpoint = 6 },
.privilege = Privilege::kView,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kCase, .subjects = { 0x1111111111111111 }, },
.requestPath = { .cluster = 7, .endpoint = 8 },
.privilege = Privilege::kProxyView,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kCase, .subjects = { 0x1111111111111111 }, },
.requestPath = { .cluster = 1, .endpoint = 2 },
.privilege = Privilege::kAdminister,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kPase, .subjects = { 0x1111111111111111 }, },
.requestPath = { .cluster = 1, .endpoint = 2 },
.privilege = Privilege::kAdminister,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kGroup, .subjects = { 0x1111111111111111 }, },
.requestPath = { .cluster = 1, .endpoint = 2 },
.privilege = Privilege::kAdminister,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kCase, .subjects = { 0x2222222222222222 }, },
.requestPath = { .cluster = 1, .endpoint = 2 },
.privilege = Privilege::kAdminister,
.allow = false
},
// Checks for entry 1
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kCase, .subjects = { 0x1234567812345678 }, },
.requestPath = { .cluster = 11, .endpoint = 13 },
.privilege = Privilege::kView,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kCase, .subjects = { 0x1234567812345678 }, },
.requestPath = { .cluster = 11, .endpoint = 13 },
.privilege = Privilege::kOperate,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kCase, .subjects = { 0x1234567812345678 }, },
.requestPath = { .cluster = 11, .endpoint = 13 },
.privilege = Privilege::kView,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kPase, .subjects = { 0x1234567812345678 }, },
.requestPath = { .cluster = 11, .endpoint = 13 },
.privilege = Privilege::kView,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kGroup, .subjects = { 0x1234567812345678 }, },
.requestPath = { .cluster = 11, .endpoint = 13 },
.privilege = Privilege::kView,
.allow = false
},
// Checks for entry 2
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kCase, .subjects = { 0x2222222222222222 }, },
.requestPath = { .cluster = kAccessControlCluster, .endpoint = 0 },
.privilege = Privilege::kAdminister,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kCase, .subjects = { 0x2222222222222222 }, },
.requestPath = { .cluster = 1, .endpoint = 2 },
.privilege = Privilege::kManage,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kCase, .subjects = { 0x2222222222222222 }, },
.requestPath = { .cluster = 3, .endpoint = 4 },
.privilege = Privilege::kOperate,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kCase, .subjects = { 0x2222222222222222 }, },
.requestPath = { .cluster = 5, .endpoint = 6 },
.privilege = Privilege::kView,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kCase, .subjects = { 0x2222222222222222 }, },
.requestPath = { .cluster = 7, .endpoint = 8 },
.privilege = Privilege::kProxyView,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kCase, .subjects = { 0x2222222222222222 }, },
.requestPath = { .cluster = 1, .endpoint = 2 },
.privilege = Privilege::kAdminister,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kPase, .subjects = { 0x2222222222222222 }, },
.requestPath = { .cluster = 1, .endpoint = 2 },
.privilege = Privilege::kAdminister,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kGroup, .subjects = { 0x2222222222222222 }, },
.requestPath = { .cluster = 1, .endpoint = 2 },
.privilege = Privilege::kAdminister,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kCase, .subjects = { 0x1111111111111111 }, },
.requestPath = { .cluster = 1, .endpoint = 2 },
.privilege = Privilege::kAdminister,
.allow = false
},
// Checks for entry 3
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kCase, .subjects = { 0x1234567812345678 }, },
.requestPath = { .cluster = kOnOffCluster, .endpoint = 11 },
.privilege = Privilege::kOperate,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kCase, .subjects = { 0x1122334455667788 }, },
.requestPath = { .cluster = kOnOffCluster, .endpoint = 13 },
.privilege = Privilege::kOperate,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kCase, .subjects = { 0x1234567812345678 }, },
.requestPath = { .cluster = kOnOffCluster, .endpoint = 11 },
.privilege = Privilege::kOperate,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kPase, .subjects = { 0x1234567812345678 }, },
.requestPath = { .cluster = kOnOffCluster, .endpoint = 11 },
.privilege = Privilege::kOperate,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kCase, .subjects = { 0x1234567812345678 }, },
.requestPath = { .cluster = 123, .endpoint = 11 },
.privilege = Privilege::kOperate,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kCase, .subjects = { 0x1234567812345678 }, },
.requestPath = { .cluster = kOnOffCluster, .endpoint = 11 },
.privilege = Privilege::kManage,
.allow = false
},
// Checks for entry 4
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kPase, .subjects = { kPaseVerifier1 }, },
.requestPath = { .cluster = kOnOffCluster, .endpoint = 2 },
.privilege = Privilege::kManage,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kPase, .subjects = { kPaseVerifier1 }, },
.requestPath = { .cluster = kOnOffCluster, .endpoint = 2 },
.privilege = Privilege::kManage,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kCase, .subjects = { kPaseVerifier1 }, },
.requestPath = { .cluster = kOnOffCluster, .endpoint = 2 },
.privilege = Privilege::kManage,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kGroup, .subjects = { kPaseVerifier1 }, },
.requestPath = { .cluster = kOnOffCluster, .endpoint = 2 },
.privilege = Privilege::kManage,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kPase, .subjects = { kPaseVerifier0 }, },
.requestPath = { .cluster = kOnOffCluster, .endpoint = 2 },
.privilege = Privilege::kManage,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kPase, .subjects = { kPaseVerifier3 }, },
.requestPath = { .cluster = kOnOffCluster, .endpoint = 2 },
.privilege = Privilege::kManage,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kPase, .subjects = { kPaseVerifier1 }, },
.requestPath = { .cluster = kLevelControlCluster, .endpoint = 2 },
.privilege = Privilege::kManage,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kPase, .subjects = { kPaseVerifier1 }, },
.requestPath = { .cluster = kOnOffCluster, .endpoint = 1 },
.privilege = Privilege::kManage,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kPase, .subjects = { kPaseVerifier1 }, },
.requestPath = { .cluster = kOnOffCluster, .endpoint = 2 },
.privilege = Privilege::kAdminister,
.allow = false
},
// Checks for entry 5
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kGroup, .subjects = { kGroup2 }, },
.requestPath = { .cluster = kLevelControlCluster, .endpoint = 1 },
.privilege = Privilege::kProxyView,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kGroup, .subjects = { kGroup2 }, },
.requestPath = { .cluster = kOnOffCluster, .endpoint = 3 },
.privilege = Privilege::kProxyView,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kGroup, .subjects = { kGroup2 }, },
.requestPath = { .cluster = kColorControlCluster, .endpoint = 2 },
.privilege = Privilege::kProxyView,
.allow = true
},
{
.subjectDescriptor = { .fabricIndex = 1, .authMode = AuthMode::kGroup, .subjects = { kGroup2 }, },
.requestPath = { .cluster = kLevelControlCluster, .endpoint = 1 },
.privilege = Privilege::kProxyView,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kPase, .subjects = { kGroup2 }, },
.requestPath = { .cluster = kLevelControlCluster, .endpoint = 1 },
.privilege = Privilege::kProxyView,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kCase, .subjects = { kGroup2 }, },
.requestPath = { .cluster = kLevelControlCluster, .endpoint = 1 },
.privilege = Privilege::kProxyView,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kGroup, .subjects = { kGroup4 }, },
.requestPath = { .cluster = kLevelControlCluster, .endpoint = 1 },
.privilege = Privilege::kProxyView,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kGroup, .subjects = { kGroup2 }, },
.requestPath = { .cluster = kColorControlCluster, .endpoint = 1 },
.privilege = Privilege::kProxyView,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kGroup, .subjects = { kGroup2 }, },
.requestPath = { .cluster = kColorControlCluster, .endpoint = 1 },
.privilege = Privilege::kProxyView,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kGroup, .subjects = { kGroup2 }, },
.requestPath = { .cluster = kLevelControlCluster, .endpoint = 3 },
.privilege = Privilege::kProxyView,
.allow = false
},
{
.subjectDescriptor = { .fabricIndex = 2, .authMode = AuthMode::kGroup, .subjects = { kGroup2 }, },
.requestPath = { .cluster = kLevelControlCluster, .endpoint = 1 },
.privilege = Privilege::kOperate,
.allow = false
},
};
void MetaTest(nlTestSuite * inSuite, void * inContext)
{
NL_TEST_ASSERT(inSuite, LoadAccessControl(accessControl, entryData1, ArraySize(entryData1)) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, CompareAccessControl(accessControl, entryData1, ArraySize(entryData1)) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, accessControl.DeleteEntry(3) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, CompareAccessControl(accessControl, entryData1, ArraySize(entryData1)) != CHIP_NO_ERROR);
}
void TestCheck(nlTestSuite * inSuite, void * inContext)
{
LoadAccessControl(accessControl, entryData1, ArraySize(entryData1));
for (const auto & checkData : checkData1)
{
CHIP_ERROR expectedResult = checkData.allow ? CHIP_NO_ERROR : CHIP_ERROR_ACCESS_DENIED;
NL_TEST_ASSERT(inSuite,
accessControl.Check(checkData.subjectDescriptor, checkData.requestPath, checkData.privilege) ==
expectedResult);
}
}
void TestCreateReadEntry(nlTestSuite * inSuite, void * inContext)
{
for (size_t i = 0; i < ArraySize(entryData1); ++i)
{
NL_TEST_ASSERT(inSuite, LoadAccessControl(accessControl, entryData1 + i, 1) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, CompareAccessControl(accessControl, entryData1, i + 1) == CHIP_NO_ERROR);
}
}
void TestDeleteEntry(nlTestSuite * inSuite, void * inContext)
{
EntryData data[ArraySize(entryData1)];
for (size_t pos = 0; pos < ArraySize(data); ++pos)
{
for (size_t count = ArraySize(data) - pos; count > 0; --count)
{
memcpy(data, entryData1, sizeof(data));
NL_TEST_ASSERT(inSuite, ClearAccessControl(accessControl) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, LoadAccessControl(accessControl, data, ArraySize(data)) == CHIP_NO_ERROR);
memmove(&data[pos], &data[pos + count], (ArraySize(data) - count - pos) * sizeof(data[0]));
for (size_t i = 0; i < count; ++i)
{
NL_TEST_ASSERT(inSuite, accessControl.DeleteEntry(pos) == CHIP_NO_ERROR);
}
NL_TEST_ASSERT(inSuite, LoadAccessControl(accessControl, data, ArraySize(data) - count) == CHIP_NO_ERROR);
}
}
}
void TestFabricFilteredCreateEntry(nlTestSuite * inSuite, void * inContext)
{
for (auto & fabricIndex : fabricIndexes)
{
for (size_t count = 0; count < ArraySize(entryData1); ++count)
{
NL_TEST_ASSERT(inSuite, ClearAccessControl(accessControl) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, LoadAccessControl(accessControl, entryData1, count) == CHIP_NO_ERROR);
constexpr size_t expectedIndexes[][ArraySize(entryData1)] = {
{ 0, 1, 2, 2, 3, 3 },
{ 0, 0, 0, 1, 1, 2 },
{ 0, 0, 0, 0, 0, 0 },
};
const size_t expectedIndex = expectedIndexes[&fabricIndex - fabricIndexes][count];
Entry entry;
NL_TEST_ASSERT(inSuite, accessControl.PrepareEntry(entry) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.SetFabricIndex(fabricIndex) == CHIP_NO_ERROR);
size_t outIndex = 999;
FabricIndex outFabricIndex = 123;
NL_TEST_ASSERT(inSuite, accessControl.CreateEntry(&outIndex, entry, &outFabricIndex) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, outIndex == expectedIndex);
NL_TEST_ASSERT(inSuite, outFabricIndex == fabricIndex);
}
}
}
void TestFabricFilteredReadEntry(nlTestSuite * inSuite, void * inContext)
{
NL_TEST_ASSERT(inSuite, LoadAccessControl(accessControl, entryData1, ArraySize(entryData1)) == CHIP_NO_ERROR);
for (auto & fabricIndex : fabricIndexes)
{
constexpr size_t indexes[] = { 0, 1, 2, 3 };
for (auto & index : indexes)
{
constexpr size_t illegalIndex = ArraySize(entryData1);
constexpr size_t expectedIndexes[][ArraySize(indexes)] = {
{ 0, 1, 3, illegalIndex },
{ 2, 4, 5, illegalIndex },
{ illegalIndex, illegalIndex, illegalIndex, illegalIndex },
};
const size_t expectedIndex = expectedIndexes[&fabricIndex - fabricIndexes][&index - indexes];
Entry entry;
CHIP_ERROR err = accessControl.ReadEntry(index, entry, &fabricIndex);
if (expectedIndex != illegalIndex)
{
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, CompareEntry(entry, entryData1[expectedIndex]) == CHIP_NO_ERROR);
}
else
{
NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
}
}
}
}
void TestIterator(nlTestSuite * inSuite, void * inContext)
{
LoadAccessControl(accessControl, entryData1, ArraySize(entryData1));
FabricIndex fabricIndex;
EntryIterator iterator;
Entry entry;
size_t count;
NL_TEST_ASSERT(inSuite, accessControl.Entries(iterator) == CHIP_NO_ERROR);
count = 0;
while (iterator.Next(entry) == CHIP_NO_ERROR)
{
NL_TEST_ASSERT(inSuite, CompareEntry(entry, entryData1[count]) == CHIP_NO_ERROR);
count++;
}
NL_TEST_ASSERT(inSuite, count == ArraySize(entryData1));
fabricIndex = kUndefinedFabricIndex;
NL_TEST_ASSERT(inSuite, accessControl.Entries(iterator, &fabricIndex) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, iterator.Next(entry) != CHIP_NO_ERROR);
fabricIndex = 1;
NL_TEST_ASSERT(inSuite, accessControl.Entries(iterator, &fabricIndex) == CHIP_NO_ERROR);
size_t fabric1[] = { 0, 1, 3 };
count = 0;
while (iterator.Next(entry) == CHIP_NO_ERROR)
{
NL_TEST_ASSERT(inSuite, CompareEntry(entry, entryData1[fabric1[count]]) == CHIP_NO_ERROR);
count++;
}
NL_TEST_ASSERT(inSuite, count == ArraySize(fabric1));
fabricIndex = 2;
NL_TEST_ASSERT(inSuite, accessControl.Entries(iterator, &fabricIndex) == CHIP_NO_ERROR);
size_t fabric2[] = { 2, 4, 5 };
count = 0;
while (iterator.Next(entry) == CHIP_NO_ERROR)
{
NL_TEST_ASSERT(inSuite, CompareEntry(entry, entryData1[fabric2[count]]) == CHIP_NO_ERROR);
count++;
}
NL_TEST_ASSERT(inSuite, count == ArraySize(fabric1));
}
void TestPrepareEntry(nlTestSuite * inSuite, void * inContext)
{
Entry entry;
for (auto authMode : authModes)
{
for (auto fabricIndex : fabricIndexes)
{
for (auto privilege : privileges)
{
NL_TEST_ASSERT(inSuite, accessControl.PrepareEntry(entry) == CHIP_NO_ERROR);
size_t subjectCount;
size_t targetCount;
NL_TEST_ASSERT(inSuite, entry.GetSubjectCount(subjectCount) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.GetTargetCount(targetCount) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, subjectCount == 0);
NL_TEST_ASSERT(inSuite, targetCount == 0);
NL_TEST_ASSERT(inSuite, entry.SetAuthMode(authMode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.SetFabricIndex(fabricIndex) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.SetPrivilege(privilege) == CHIP_NO_ERROR);
int subjectIndex;
switch (authMode)
{
default:
case AuthMode::kPase:
subjectIndex = 0;
break;
case AuthMode::kCase:
subjectIndex = 1;
break;
case AuthMode::kGroup:
subjectIndex = 2;
break;
}
for (auto subject : subjects[subjectIndex])
{
NL_TEST_ASSERT(inSuite, entry.AddSubject(nullptr, subject) == CHIP_NO_ERROR);
}
for (auto & target : targets)
{
NL_TEST_ASSERT(inSuite, entry.AddTarget(nullptr, target) == CHIP_NO_ERROR);
}
AuthMode a;
FabricIndex f;
Privilege p;
NL_TEST_ASSERT(inSuite, entry.GetAuthMode(a) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.GetFabricIndex(f) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.GetPrivilege(p) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, a == authMode);
NL_TEST_ASSERT(inSuite, f == fabricIndex);
NL_TEST_ASSERT(inSuite, p == privilege);
NL_TEST_ASSERT(inSuite, entry.GetSubjectCount(subjectCount) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.GetTargetCount(targetCount) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, subjectCount == 3);
NL_TEST_ASSERT(inSuite, targetCount == 3);
for (size_t i = 0; i < ArraySize(subjects[subjectIndex]); ++i)
{
NodeId n;
NL_TEST_ASSERT(inSuite, entry.GetSubject(i, n) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, n == subjects[subjectIndex][i]);
}
for (size_t i = 0; i < ArraySize(targets); ++i)
{
Target t;
NL_TEST_ASSERT(inSuite, entry.GetTarget(i, t) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, t == targets[i]);
}
}
}
}
}
void TestSubjectsTargets(nlTestSuite * inSuite, void * inContext)
{
Entry entry;
NL_TEST_ASSERT(inSuite, accessControl.PrepareEntry(entry) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.SetFabricIndex(1) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.SetPrivilege(Privilege::kAdminister) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.SetAuthMode(AuthMode::kCase) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.AddTarget(nullptr, { Target::kCluster, 1, 0, 0 }) == CHIP_NO_ERROR);
size_t index = 999;
NL_TEST_ASSERT(inSuite, accessControl.CreateEntry(&index, entry) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, int(index) == 0);
NL_TEST_ASSERT(inSuite, entry.SetFabricIndex(2) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.SetPrivilege(Privilege::kManage) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.SetAuthMode(AuthMode::kPase) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.AddSubject(nullptr, 0x0000000011111111) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.AddTarget(nullptr, { Target::kEndpoint, 0, 2, 0 }) == CHIP_NO_ERROR);
index = 999;
NL_TEST_ASSERT(inSuite, accessControl.CreateEntry(&index, entry) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, int(index) == 1);
NL_TEST_ASSERT(inSuite, entry.SetFabricIndex(3) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.SetPrivilege(Privilege::kOperate) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.SetAuthMode(AuthMode::kGroup) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.AddSubject(nullptr, 0x0000000022222222) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.AddTarget(nullptr, { Target::kDeviceType, 0, 0, 3 }) == CHIP_NO_ERROR);
index = 999;
NL_TEST_ASSERT(inSuite, accessControl.CreateEntry(&index, entry) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, int(index) == 2);
FabricIndex fabricIndex;
Privilege privilege;
AuthMode authMode;
size_t count;
NodeId subject;
Target target;
NL_TEST_ASSERT(inSuite, accessControl.ReadEntry(0, entry) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.GetFabricIndex(fabricIndex) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, fabricIndex == 1);
NL_TEST_ASSERT(inSuite, entry.GetPrivilege(privilege) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, privilege == Privilege::kAdminister);
NL_TEST_ASSERT(inSuite, entry.GetAuthMode(authMode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, authMode == AuthMode::kCase);
NL_TEST_ASSERT(inSuite, entry.GetSubjectCount(count) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, count == 0);
NL_TEST_ASSERT(inSuite, entry.GetTargetCount(count) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, count == 1);
NL_TEST_ASSERT(inSuite, entry.GetTarget(0, target) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, target.flags == Target::kCluster && target.cluster == 1);
NL_TEST_ASSERT(inSuite, accessControl.ReadEntry(1, entry) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.GetFabricIndex(fabricIndex) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, fabricIndex == 2);
NL_TEST_ASSERT(inSuite, entry.GetPrivilege(privilege) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, privilege == Privilege::kManage);
NL_TEST_ASSERT(inSuite, entry.GetAuthMode(authMode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, authMode == AuthMode::kPase);
NL_TEST_ASSERT(inSuite, entry.GetSubjectCount(count) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, count == 1);
NL_TEST_ASSERT(inSuite, entry.GetSubject(0, subject) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, subject == 0x0000000011111111);
NL_TEST_ASSERT(inSuite, entry.GetTargetCount(count) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, count == 2);
NL_TEST_ASSERT(inSuite, entry.GetTarget(0, target) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, target.flags == Target::kCluster && target.cluster == 1);
NL_TEST_ASSERT(inSuite, entry.GetTarget(1, target) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, target.flags == Target::kEndpoint && target.endpoint == 2);
NL_TEST_ASSERT(inSuite, accessControl.ReadEntry(2, entry) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.GetFabricIndex(fabricIndex) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, fabricIndex == 3);
NL_TEST_ASSERT(inSuite, entry.GetPrivilege(privilege) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, privilege == Privilege::kOperate);
NL_TEST_ASSERT(inSuite, entry.GetAuthMode(authMode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, authMode == AuthMode::kGroup);
NL_TEST_ASSERT(inSuite, entry.GetSubjectCount(count) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, count == 2);
NL_TEST_ASSERT(inSuite, entry.GetSubject(0, subject) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, subject == 0x0000000011111111);
NL_TEST_ASSERT(inSuite, entry.GetSubject(1, subject) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, subject == 0x0000000022222222);
NL_TEST_ASSERT(inSuite, entry.GetTargetCount(count) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, count == 3);
NL_TEST_ASSERT(inSuite, entry.GetTarget(0, target) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, target.flags == Target::kCluster && target.cluster == 1);
NL_TEST_ASSERT(inSuite, entry.GetTarget(1, target) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, target.flags == Target::kEndpoint && target.endpoint == 2);
NL_TEST_ASSERT(inSuite, entry.GetTarget(2, target) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, target.flags == Target::kDeviceType && target.deviceType == 3);
NL_TEST_ASSERT(inSuite, accessControl.PrepareEntry(entry) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.SetFabricIndex(11) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.SetPrivilege(Privilege::kProxyView) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.SetAuthMode(AuthMode::kCase) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.AddSubject(nullptr, 0x11111111AAAAAAAA) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.AddSubject(nullptr, 0x22222222BBBBBBBB) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.AddSubject(nullptr, 0x33333333CCCCCCCC) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.AddTarget(nullptr, { Target::kCluster | Target::kEndpoint, 11, 22, 0 }) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.AddTarget(nullptr, { Target::kCluster | Target::kDeviceType, 33, 0, 44 }) == CHIP_NO_ERROR);
NL_TEST_ASSERT(
inSuite, entry.AddTarget(nullptr, { Target::kCluster | Target::kDeviceType, 0xAAAA5555, 0, 0xBBBB6666 }) == CHIP_NO_ERROR);
index = 999;
NL_TEST_ASSERT(inSuite, accessControl.CreateEntry(&index, entry) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, int(index) == 3);
NL_TEST_ASSERT(inSuite, accessControl.ReadEntry(3, entry) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.GetFabricIndex(fabricIndex) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, fabricIndex == 11);
NL_TEST_ASSERT(inSuite, entry.GetPrivilege(privilege) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, privilege == Privilege::kProxyView);
NL_TEST_ASSERT(inSuite, entry.GetAuthMode(authMode) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, authMode == AuthMode::kCase);
NL_TEST_ASSERT(inSuite, entry.GetSubjectCount(count) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, count == 3);
NL_TEST_ASSERT(inSuite, entry.GetSubject(0, subject) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, subject == 0x11111111AAAAAAAA);
NL_TEST_ASSERT(inSuite, entry.GetSubject(1, subject) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, subject == 0x22222222BBBBBBBB);
NL_TEST_ASSERT(inSuite, entry.GetSubject(2, subject) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, subject == 0x33333333CCCCCCCC);
NL_TEST_ASSERT(inSuite, entry.GetTargetCount(count) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, count == 3);
NL_TEST_ASSERT(inSuite, entry.GetTarget(0, target) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite,
target.flags == (Target::kCluster | Target::kEndpoint) && target.cluster == 11 && target.endpoint == 22);
NL_TEST_ASSERT(inSuite, entry.GetTarget(1, target) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite,
target.flags == (Target::kCluster | Target::kDeviceType) && target.cluster == 33 && target.deviceType == 44);
NL_TEST_ASSERT(inSuite, entry.GetTarget(2, target) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite,
target.flags == (Target::kCluster | Target::kDeviceType) && target.cluster == 0xAAAA5555 &&
target.deviceType == 0xBBBB6666);
NL_TEST_ASSERT(inSuite, entry.RemoveSubject(1) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.GetSubjectCount(count) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, count == 2);
NL_TEST_ASSERT(inSuite, entry.GetSubject(0, subject) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, subject == 0x11111111AAAAAAAA);
NL_TEST_ASSERT(inSuite, entry.GetSubject(1, subject) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, subject == 0x33333333CCCCCCCC);
NL_TEST_ASSERT(inSuite, entry.GetSubject(2, subject) != CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.RemoveTarget(1) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, entry.GetTargetCount(count) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, count == 2);
NL_TEST_ASSERT(inSuite, entry.GetTarget(0, target) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite,
target.flags == (Target::kCluster | Target::kEndpoint) && target.cluster == 11 && target.endpoint == 22);
NL_TEST_ASSERT(inSuite, entry.GetTarget(1, target) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite,
target.flags == (Target::kCluster | Target::kDeviceType) && target.cluster == 0xAAAA5555 &&
target.deviceType == 0xBBBB6666);
NL_TEST_ASSERT(inSuite, entry.GetTarget(2, target) != CHIP_NO_ERROR);
}
void TestUpdateEntry(nlTestSuite * inSuite, void * inContext)
{
EntryData data[6];
memcpy(data, entryData1, sizeof(data));
NL_TEST_ASSERT(inSuite, LoadAccessControl(accessControl, data, 6) == CHIP_NO_ERROR);
EntryData updateData;
for (size_t i = 0; i < 6; ++i)
{
updateData.authMode = authModes[i % 3];
updateData.fabricIndex = fabricIndexes[i % 3];
updateData.privilege = privileges[i % 3];
if (i < 3)
{
updateData.AddSubject(nullptr, subjects[i][i]);
}
else
{
updateData.AddTarget(nullptr, targets[i - 3]);
}
data[i] = updateData;
{
Entry entry;
NL_TEST_ASSERT(inSuite, accessControl.PrepareEntry(entry) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, LoadEntry(entry, updateData) == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, accessControl.UpdateEntry(i, entry) == CHIP_NO_ERROR);
}
NL_TEST_ASSERT(inSuite, CompareAccessControl(accessControl, data, 6) == CHIP_NO_ERROR);
}
}
int Setup(void * inContext)
{
SetAccessControl(accessControl);
GetAccessControl().Init();
return SUCCESS;
}
int Teardown(void * inContext)
{
GetAccessControl().Finish();
return SUCCESS;
}
int Initialize(void * inContext)
{
return ClearAccessControl(accessControl) == CHIP_NO_ERROR ? SUCCESS : FAILURE;
}
int Terminate(void * inContext)
{
return SUCCESS;
}
} // namespace
int TestAccessControl()
{
// clang-format off
constexpr nlTest tests[] = {
NL_TEST_DEF("MetaTest", MetaTest),
NL_TEST_DEF("TestPrepareEntry", TestPrepareEntry),
NL_TEST_DEF("TestCreateReadEntry", TestCreateReadEntry),
NL_TEST_DEF("TestUpdateEntry", TestUpdateEntry),
NL_TEST_DEF("TestDeleteEntry", TestDeleteEntry),
NL_TEST_DEF("TestSubjectsTargets", TestSubjectsTargets),
NL_TEST_DEF("TestIterator", TestIterator),
NL_TEST_DEF("TestFabricFilteredReadEntry", TestFabricFilteredReadEntry),
NL_TEST_DEF("TestFabricFilteredCreateEntry", TestFabricFilteredCreateEntry),
NL_TEST_DEF("TestCheck", TestCheck),
NL_TEST_SENTINEL()
};
// clang-format on
nlTestSuite suite = {
.name = "AccessControl",
.tests = tests,
.setup = Setup,
.tear_down = Teardown,
.initialize = Initialize,
.terminate = Terminate,
};
nlTestRunner(&suite, nullptr);
return nlTestRunnerStats(&suite);
}
CHIP_REGISTER_TEST_SUITE(TestAccessControl);