blob: 045ef77be69d9fe37e54f9384ad4a3b94033112f [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.
*/
/**
* @file
* This file implements unit tests for AttributePersistenceProvider
*
*/
#include <app-common/zap-generated/cluster-objects.h>
#include <app/DefaultAttributePersistenceProvider.h>
#include <lib/support/TestPersistentStorageDelegate.h>
#include <lib/support/UnitTestRegistration.h>
#include <nlunit-test.h>
using namespace chip;
using namespace chip::app;
using namespace chip::TLV;
const ConcreteAttributePath TestConcretePath = ConcreteAttributePath(1, 1, 1);
namespace {
/**
* Set up the test suite.
*/
int Test_Setup(void * inContext)
{
CHIP_ERROR error = chip::Platform::MemoryInit();
VerifyOrReturnError(error == CHIP_NO_ERROR, FAILURE);
return SUCCESS;
}
/**
* Tear down the test suite.
*/
int Test_Teardown(void * inContext)
{
chip::Platform::MemoryShutdown();
return SUCCESS;
}
/**
* Tests the storage and retrival of data from the KVS as ByteSpan
*/
void TestStorageAndRetrivalByteSpans(nlTestSuite * inSuite, void * inContext)
{
TestPersistentStorageDelegate storageDelegate;
DefaultAttributePersistenceProvider persistenceProvider;
// Init
ChipError err = persistenceProvider.Init(&storageDelegate);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
// Store ByteSpan of size 1
uint8_t valueArray[1] = { 0x42 };
ByteSpan value(valueArray);
err = persistenceProvider.WriteValue(TestConcretePath, value);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
uint8_t getArray[1];
MutableByteSpan valueReadBack(getArray);
err = persistenceProvider.ReadValue(TestConcretePath, 0x20, sizeof(getArray), valueReadBack);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, std::equal(valueReadBack.begin(), valueReadBack.end(), value.begin(), value.end()));
// Finishing
persistenceProvider.Shutdown();
}
/**
* Helper to test the storage and retrival of various types from persistent storage.
* @tparam T The type of the value to store and retrieve
* @param testValue The test value to store and retrieve
*/
template <typename T>
void testHelperStorageAndRetrivalScalarValues(nlTestSuite * inSuite, DefaultAttributePersistenceProvider & persistenceProvider,
T testValue)
{
CHIP_ERROR err = persistenceProvider.WriteScalarValue(TestConcretePath, testValue);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
T valueReadBack = 0;
err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, valueReadBack == testValue);
}
/**
* Helper to test the storage and retrival of various nullable types from persistent storage.
* @tparam T The type of the value to store and retrieve
* @param testValue The test value to store and retrieve
*/
template <typename T>
void testHelperStorageAndRetrivalScalarValues(nlTestSuite * inSuite, DefaultAttributePersistenceProvider & persistenceProvider,
DataModel::Nullable<T> testValue)
{
CHIP_ERROR err = persistenceProvider.WriteScalarValue(TestConcretePath, testValue);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
DataModel::Nullable<T> valueReadBack(0);
err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, valueReadBack == testValue);
}
/**
* Tests the storage and retrival of data from the KVS of types bool, uint8_t, uint16_t, uint32_t, uint64_t.
*/
void TestStorageAndRetrivalScalarValues(nlTestSuite * inSuite, void * inContext)
{
TestPersistentStorageDelegate storageDelegate;
DefaultAttributePersistenceProvider persistenceProvider;
// Init
CHIP_ERROR err = persistenceProvider.Init(&storageDelegate);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
// Test bool
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, bool(true));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, bool(false));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, bool(true));
// Test uint8_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint8_t(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint8_t(42));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint8_t(0xff));
// Test uint16_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint16_t(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint16_t(0x0101));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint16_t(0xffff));
// Test uint32_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint32_t(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint32_t(0x01ffff));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint32_t(0xffffffff));
// Test uint64_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint64_t(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint64_t(0x0100000001));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint64_t(0xffffffffffffffff));
// Finishing
persistenceProvider.Shutdown();
}
/**
* Tests the storage and retrival of data from the KVS of types int8_t, int16_t, int32_t, int64_t.
*/
void TestStorageAndRetrivalSignedScalarValues(nlTestSuite * inSuite, void * inContext)
{
TestPersistentStorageDelegate storageDelegate;
DefaultAttributePersistenceProvider persistenceProvider;
// Init
CHIP_ERROR err = persistenceProvider.Init(&storageDelegate);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
// Test int8_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int8_t(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int8_t(42));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int8_t(-127));
// Test int16_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int16_t(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int16_t(0x7fff));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int16_t(0x8000));
// Test int32_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int32_t(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int32_t(0x7fffffff));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int32_t(0x80000000));
// Test int64_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int64_t(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int64_t(0x7fffffffffffffff));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int64_t(0x8000000000000000));
// Finishing
persistenceProvider.Shutdown();
}
void TestGetNullFunctions(nlTestSuite * inSuite, void * inContext)
{
NL_TEST_ASSERT(inSuite, AttributePersistenceProvider::GetNullValueForNullableType<bool>() == uint8_t(0xff));
NL_TEST_ASSERT(inSuite, AttributePersistenceProvider::GetNullValueForNullableType<uint8_t>() == uint8_t(0xff));
NL_TEST_ASSERT(inSuite, AttributePersistenceProvider::GetNullValueForNullableType<uint16_t>() == uint16_t(0xffff));
NL_TEST_ASSERT(inSuite, AttributePersistenceProvider::GetNullValueForNullableType<uint32_t>() == uint32_t(0xffffffff));
NL_TEST_ASSERT(inSuite, AttributePersistenceProvider::GetNullValueForNullableType<uint64_t>() == uint64_t(0xffffffffffffffff));
NL_TEST_ASSERT(inSuite, AttributePersistenceProvider::GetNullValueForNullableType<int8_t>() == int8_t(0x80));
NL_TEST_ASSERT(inSuite, AttributePersistenceProvider::GetNullValueForNullableType<int16_t>() == int16_t(0x8000));
NL_TEST_ASSERT(inSuite, AttributePersistenceProvider::GetNullValueForNullableType<int32_t>() == int32_t(0x80000000));
NL_TEST_ASSERT(inSuite, AttributePersistenceProvider::GetNullValueForNullableType<int64_t>() == int64_t(0x8000000000000000));
}
/**
* Tests the storage and retrival of data from the KVS of DataModel::Nullable types bool, uint8_t, uint16_t, uint32_t, uint64_t.
*/
void TestStorageAndRetrivalNullableScalarValues(nlTestSuite * inSuite, void * inContext)
{
TestPersistentStorageDelegate storageDelegate;
DefaultAttributePersistenceProvider persistenceProvider;
// Init
CHIP_ERROR err = persistenceProvider.Init(&storageDelegate);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
// Test bool
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<bool>(true));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<bool>(false));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<bool>(true));
auto nullValBool = DataModel::Nullable<bool>();
nullValBool.SetNull();
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullValBool);
// Test uint8_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint8_t>(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint8_t>(42));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint8_t>(0xfe));
auto nullVal8 = DataModel::Nullable<uint8_t>();
nullVal8.SetNull();
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal8);
// Test uint16_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint16_t>(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint16_t>(0x0101));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint16_t>(0xfffe));
auto nullVal16 = DataModel::Nullable<uint16_t>();
nullVal16.SetNull();
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal16);
// Test uint32_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint32_t>(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint32_t>(0x01ffff));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint32_t>(0xfffffffe));
auto nullVal32 = DataModel::Nullable<uint32_t>();
nullVal32.SetNull();
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal32);
// Test uint64_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint64_t>(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint64_t>(0x0100000001));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint64_t>(0xfffffffffffffffe));
auto nullVal64 = DataModel::Nullable<uint64_t>();
nullVal64.SetNull();
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal64);
// Finishing
persistenceProvider.Shutdown();
}
/**
* Tests the storage and retrival of data from the KVS of DataModel::Nullable types int8_t, int16_t, int32_t, int64_t.
*/
void TestStorageAndRetrivalSignedNullableScalarValues(nlTestSuite * inSuite, void * inContext)
{
TestPersistentStorageDelegate storageDelegate;
DefaultAttributePersistenceProvider persistenceProvider;
// Init
CHIP_ERROR err = persistenceProvider.Init(&storageDelegate);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
// Test int8_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int8_t>(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int8_t>(42));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int8_t>(-127));
auto nullVal8 = DataModel::Nullable<int8_t>();
nullVal8.SetNull();
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal8);
// Test int16_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int16_t>(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int16_t>(0x7fff));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int16_t>(-0x7fff));
auto nullVal16 = DataModel::Nullable<int16_t>();
nullVal16.SetNull();
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal16);
// Test int32_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int32_t>(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int32_t>(0x7fffffff));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int32_t>(-0x7fffffff));
auto nullVal32 = DataModel::Nullable<int32_t>();
nullVal32.SetNull();
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal32);
// Test int64_t
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int64_t>(0));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int64_t>(0x7fffffffffffffff));
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int64_t>(-0x7fffffffffffffff));
auto nullVal64 = DataModel::Nullable<int64_t>();
nullVal64.SetNull();
testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal64);
// Finishing
persistenceProvider.Shutdown();
}
/**
* Test that the correct error is given when trying to read a value with a buffer that's too small.
*/
void TestBufferTooSmallErrors(nlTestSuite * inSuite, void * inContext)
{
TestPersistentStorageDelegate storageDelegate;
DefaultAttributePersistenceProvider persistenceProvider;
// Init
CHIP_ERROR err = persistenceProvider.Init(&storageDelegate);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
// Store large data
uint8_t valueArray[9] = { 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42 };
ByteSpan value(valueArray);
err = persistenceProvider.WriteValue(TestConcretePath, value);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
// Confirm the daya is there
uint8_t getArray[9];
MutableByteSpan valueReadBack(getArray);
err = persistenceProvider.ReadValue(TestConcretePath, 0x20, sizeof(getArray), valueReadBack);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
NL_TEST_ASSERT(inSuite, std::equal(valueReadBack.begin(), valueReadBack.end(), value.begin(), value.end()));
// Fail to get data as ByteSpace of size 0
uint8_t getArray0[0];
MutableByteSpan valueReadBackByteSpan0(getArray0, 0);
err = persistenceProvider.ReadValue(TestConcretePath, 0x20, 1, valueReadBackByteSpan0);
NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
// Fail to get data as ByteSpace of size > 0 but < required
uint8_t getArray8[8];
MutableByteSpan valueReadBackByteSpan8(getArray8, sizeof(getArray8));
err = persistenceProvider.ReadValue(TestConcretePath, 0x20, 1, valueReadBackByteSpan8);
NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
// Fail to get value as uint8_t
uint8_t valueReadBack8;
err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack8);
NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
// Fail to get value as uint16_t
uint16_t valueReadBack16;
err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack16);
NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
// Fail to get value as uint32_t
uint32_t valueReadBack32;
err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack32);
NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
// Fail to get value as uint64_t
uint64_t valueReadBack64;
err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack64);
NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
// Finishing
persistenceProvider.Shutdown();
}
} // anonymous namespace
namespace {
const nlTest sTests[] = {
NL_TEST_DEF("Storage and retrival of ByteSpans", TestStorageAndRetrivalByteSpans),
NL_TEST_DEF("Storage and retrival of unsigned scalar values", TestStorageAndRetrivalScalarValues),
NL_TEST_DEF("Storage and retrival of signed scalar values", TestStorageAndRetrivalSignedScalarValues),
NL_TEST_DEF("Check GetNullValueForNullableType return values", TestGetNullFunctions),
NL_TEST_DEF("Storage and retrival of unsigned nullable scalar values", TestStorageAndRetrivalNullableScalarValues),
NL_TEST_DEF("Storage and retrival of signed nullable scalar values", TestStorageAndRetrivalSignedNullableScalarValues),
NL_TEST_DEF("Small buffer errors", TestBufferTooSmallErrors),
NL_TEST_SENTINEL()
};
}
int TestAttributePersistenceProvider()
{
nlTestSuite theSuite = { "AttributePersistenceProvider", &sTests[0], Test_Setup, Test_Teardown };
nlTestRunner(&theSuite, nullptr);
return (nlTestRunnerStats(&theSuite));
}
CHIP_REGISTER_TEST_SUITE(TestAttributePersistenceProvider)