/* * * Copyright (c) 2023 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 #include #include #include #include using namespace chip; namespace TestEFS { enum class TagTestEFS : uint8_t { kEFS = 1, kTestArray, }; static constexpr size_t kPersistentSceneBufferMax = 256; // Test Cluster ID constexpr chip::ClusterId kOnOffClusterId = 0x0006; constexpr chip::ClusterId kLevelControlClusterId = 0x0008; constexpr chip::ClusterId kColorControlClusterId = 0x0300; constexpr uint8_t kOnOffSize = 1; constexpr uint8_t kLevelControlSize = 3; constexpr uint8_t kColorControlSize = 14; static uint8_t onOffBuffer[scenes::kMaxFieldBytesPerCluster] = "0"; static uint8_t levelControlBuffer[scenes::kMaxFieldBytesPerCluster] = "123"; static uint8_t colorControlBuffer[scenes::kMaxFieldBytesPerCluster] = "abcdefghijklmn"; static const scenes::ExtensionFieldSet EFS1(kOnOffClusterId, onOffBuffer, kOnOffSize); static const scenes::ExtensionFieldSet EFS2(kLevelControlClusterId, levelControlBuffer, kLevelControlSize); static const scenes::ExtensionFieldSet EFS3(kColorControlClusterId, colorControlBuffer, kColorControlSize); static scenes::ExtensionFieldSetsImpl sEFSets; class TestExtensionFieldSets : public ::testing::Test { public: static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } }; TEST_F(TestExtensionFieldSets, TestInsertExtensionFieldSet) { scenes::ExtensionFieldSetsImpl * EFS = &sEFSets; scenes::ExtensionFieldSetsImpl testEFS1; scenes::ExtensionFieldSetsImpl testEFS2; scenes::ExtensionFieldSetsImpl testEFS3; scenes::ExtensionFieldSetsImpl tempTestEFS; scenes::ExtensionFieldSet tempEFS; uint8_t empty_buffer[scenes::kMaxFieldBytesPerCluster] = { 0 }; uint8_t double_size_buffer[scenes::kMaxFieldBytesPerCluster + 1]; ByteSpan bufferSpan(double_size_buffer); memset(double_size_buffer, static_cast(1), sizeof(double_size_buffer)); EXPECT_TRUE(EFS->IsEmpty()); // Test creators of single ExtensionFieldSet EXPECT_EQ(EFS1.mID, kOnOffClusterId); EXPECT_EQ(EFS1.mUsedBytes, kOnOffSize); EXPECT_EQ(memcmp(onOffBuffer, EFS1.mBytesBuffer, EFS1.mUsedBytes), 0); EXPECT_EQ(EFS2.mID, kLevelControlClusterId); EXPECT_EQ(EFS2.mUsedBytes, kLevelControlSize); EXPECT_EQ(memcmp(levelControlBuffer, EFS2.mBytesBuffer, EFS2.mUsedBytes), 0); EXPECT_EQ(EFS3.mID, kColorControlClusterId); EXPECT_EQ(EFS3.mUsedBytes, kColorControlSize); EXPECT_EQ(memcmp(colorControlBuffer, EFS3.mBytesBuffer, EFS3.mUsedBytes), 0); // operator tests single EFS tempEFS = EFS1; EXPECT_EQ(tempEFS, EFS1); tempEFS = EFS2; EXPECT_EQ(tempEFS, EFS2); tempEFS = EFS3; EXPECT_EQ(tempEFS, EFS3); // Test clear EFS tempEFS.Clear(); EXPECT_TRUE(tempEFS.IsEmpty()); EXPECT_EQ(tempEFS.mID, kInvalidClusterId); EXPECT_EQ(tempEFS.mUsedBytes, 0); EXPECT_EQ(memcmp(empty_buffer, tempEFS.mBytesBuffer, sizeof(tempEFS.mBytesBuffer)), 0); // Test creation of EFS from Array and ByteSpan that are to big tempEFS = scenes::ExtensionFieldSet(kOnOffClusterId, double_size_buffer, sizeof(double_size_buffer)); EXPECT_EQ(tempEFS.mID, kOnOffClusterId); // Confirm EFS empty EXPECT_EQ(tempEFS.mUsedBytes, 0); EXPECT_EQ(memcmp(empty_buffer, tempEFS.mBytesBuffer, sizeof(empty_buffer)), 0); tempEFS = scenes::ExtensionFieldSet(kLevelControlClusterId, bufferSpan); EXPECT_EQ(tempEFS.mID, kLevelControlClusterId); // Confirm EFS empty EXPECT_EQ(tempEFS.mUsedBytes, 0); EXPECT_EQ(memcmp(empty_buffer, tempEFS.mBytesBuffer, sizeof(empty_buffer)), 0); // Test creation of EFS from truncating an Array tempEFS = scenes::ExtensionFieldSet(kColorControlClusterId, double_size_buffer, sizeof(tempEFS.mBytesBuffer)); EXPECT_EQ(tempEFS.mID, kColorControlClusterId); // Confirm EFS was written EXPECT_EQ(tempEFS.mUsedBytes, static_cast(sizeof(tempEFS.mBytesBuffer))); EXPECT_EQ(memcmp(double_size_buffer, tempEFS.mBytesBuffer, sizeof(tempEFS.mBytesBuffer)), 0); tempEFS.Clear(); EXPECT_TRUE(tempEFS.IsEmpty()); // Test insertion of uninitialized EFS EXPECT_EQ(CHIP_ERROR_INVALID_ARGUMENT, EFS->InsertFieldSet(tempEFS)); EXPECT_EQ(0, EFS->GetFieldSetCount()); // Test insertion of empty EFS tempEFS.mID = kOnOffClusterId; EXPECT_EQ(CHIP_ERROR_INVALID_ARGUMENT, EFS->InsertFieldSet(tempEFS)); EXPECT_EQ(0, EFS->GetFieldSetCount()); // test operators on multiple EFS struct EXPECT_EQ(CHIP_NO_ERROR, testEFS1.InsertFieldSet(EFS1)); EXPECT_EQ(CHIP_NO_ERROR, testEFS1.InsertFieldSet(EFS2)); EXPECT_EQ(CHIP_NO_ERROR, testEFS1.InsertFieldSet(EFS3)); EXPECT_EQ(CHIP_NO_ERROR, testEFS2.InsertFieldSet(EFS3)); EXPECT_EQ(CHIP_NO_ERROR, testEFS3.InsertFieldSet(EFS1)); EXPECT_EQ(CHIP_NO_ERROR, testEFS3.InsertFieldSet(EFS2)); tempTestEFS = testEFS1; EXPECT_EQ(tempTestEFS, testEFS1); EXPECT_FALSE(tempTestEFS == testEFS2); EXPECT_FALSE(tempTestEFS == testEFS3); tempTestEFS = testEFS2; EXPECT_EQ(tempTestEFS, testEFS2); EXPECT_FALSE(tempTestEFS == testEFS1); EXPECT_FALSE(tempTestEFS == testEFS3); tempTestEFS = testEFS3; EXPECT_EQ(tempTestEFS, testEFS3); EXPECT_FALSE(tempTestEFS == testEFS1); EXPECT_FALSE(tempTestEFS == testEFS2); // test clear multipler efs struct tempTestEFS.Clear(); EXPECT_TRUE(tempTestEFS.IsEmpty()); EXPECT_EQ(0, tempTestEFS.GetFieldSetCount()); // Test insert EXPECT_EQ(CHIP_NO_ERROR, EFS->InsertFieldSet(EFS1)); EXPECT_EQ(1, EFS->GetFieldSetCount()); EXPECT_EQ(CHIP_NO_ERROR, EFS->InsertFieldSet(EFS2)); EXPECT_EQ(2, EFS->GetFieldSetCount()); EXPECT_EQ(CHIP_NO_ERROR, EFS->InsertFieldSet(EFS3)); EXPECT_EQ(3, EFS->GetFieldSetCount()); // Test get EXPECT_EQ(CHIP_NO_ERROR, EFS->GetFieldSetAtPosition(tempEFS, 0)); EXPECT_EQ(tempEFS, EFS1); EXPECT_EQ(CHIP_NO_ERROR, EFS->GetFieldSetAtPosition(tempEFS, 1)); EXPECT_EQ(tempEFS, EFS2); EXPECT_EQ(CHIP_NO_ERROR, EFS->GetFieldSetAtPosition(tempEFS, 2)); EXPECT_EQ(tempEFS, EFS3); } TEST_F(TestExtensionFieldSets, TestSerializeDerializeExtensionFieldSet) { scenes::ExtensionFieldSetsImpl * EFS = &sEFSets; scenes::ExtensionFieldSetsImpl testSceneEFS; scenes::ExtensionFieldSet tempEFS; uint8_t EFS1Buffer[scenes::kMaxFieldBytesPerCluster] = { 0 }; uint8_t EFS2Buffer[scenes::kMaxFieldBytesPerCluster] = { 0 }; uint8_t EFS3Buffer[scenes::kMaxFieldBytesPerCluster] = { 0 }; uint8_t sceneEFSBuffer[kPersistentSceneBufferMax] = { 0 }; uint32_t EFS1_serialized_length = 0; uint32_t EFS2_serialized_length = 0; uint32_t EFS3_serialized_length = 0; uint32_t sceneEFS_serialized_length = 0; TLV::TLVReader reader; TLV::TLVWriter writer; TLV::TLVType outer; TLV::TLVType outerRead; // Individual Field Sets serialize / deserialize writer.Init(EFS1Buffer); EXPECT_EQ(CHIP_NO_ERROR, EFS1.Serialize(writer)); EFS1_serialized_length = writer.GetLengthWritten(); EXPECT_LE(EFS1_serialized_length, scenes::kMaxFieldBytesPerCluster); writer.Init(EFS2Buffer); EXPECT_EQ(CHIP_NO_ERROR, EFS2.Serialize(writer)); EFS2_serialized_length = writer.GetLengthWritten(); EXPECT_LE(EFS2_serialized_length, scenes::kMaxFieldBytesPerCluster); writer.Init(EFS3Buffer); EXPECT_EQ(CHIP_NO_ERROR, EFS3.Serialize(writer)); EFS3_serialized_length = writer.GetLengthWritten(); EXPECT_LE(EFS3_serialized_length, scenes::kMaxFieldBytesPerCluster); reader.Init(EFS1Buffer); reader.Next(TLV::AnonymousTag()); EXPECT_EQ(CHIP_NO_ERROR, tempEFS.Deserialize(reader)); EXPECT_EQ(EFS1, tempEFS); reader.Init(EFS2Buffer); reader.Next(TLV::AnonymousTag()); EXPECT_EQ(CHIP_NO_ERROR, tempEFS.Deserialize(reader)); EXPECT_EQ(EFS2, tempEFS); reader.Init(EFS3Buffer); reader.Next(TLV::AnonymousTag()); EXPECT_EQ(CHIP_NO_ERROR, tempEFS.Deserialize(reader)); EXPECT_EQ(EFS3, tempEFS); // All ExtensionFieldSets serialize / deserialize writer.Init(sceneEFSBuffer); writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outer); EXPECT_EQ(CHIP_NO_ERROR, EFS->Serialize(writer)); writer.EndContainer(outer); sceneEFS_serialized_length = writer.GetLengthWritten(); EXPECT_LE(sceneEFS_serialized_length, kPersistentSceneBufferMax); reader.Init(sceneEFSBuffer); EXPECT_EQ(CHIP_NO_ERROR, reader.Next()); EXPECT_EQ(CHIP_NO_ERROR, reader.EnterContainer(outerRead)); EXPECT_EQ(CHIP_NO_ERROR, testSceneEFS.Deserialize(reader)); EXPECT_EQ(CHIP_NO_ERROR, reader.ExitContainer(outerRead)); EXPECT_EQ(*EFS, testSceneEFS); } TEST_F(TestExtensionFieldSets, TestRemoveExtensionFieldSet) { scenes::ExtensionFieldSetsImpl * EFS = &sEFSets; scenes::ExtensionFieldSet tempEFS; // Order in EFS at this point: [EFS1, EFS2, EFS3] // Removal at beginning EXPECT_EQ(CHIP_NO_ERROR, EFS->RemoveFieldAtPosition(0)); EXPECT_EQ(2, EFS->GetFieldSetCount()); EXPECT_EQ(CHIP_NO_ERROR, EFS->InsertFieldSet(EFS1)); EXPECT_EQ(3, EFS->GetFieldSetCount()); // Verify order EXPECT_EQ(CHIP_NO_ERROR, EFS->GetFieldSetAtPosition(tempEFS, 0)); EXPECT_EQ(tempEFS, EFS2); EXPECT_EQ(CHIP_NO_ERROR, EFS->GetFieldSetAtPosition(tempEFS, 1)); EXPECT_EQ(tempEFS, EFS3); EXPECT_EQ(CHIP_NO_ERROR, EFS->GetFieldSetAtPosition(tempEFS, 2)); EXPECT_EQ(tempEFS, EFS1); // Order in EFS at this point: [EFS2, EFS3, EFS1] // Removal at middle EXPECT_EQ(CHIP_NO_ERROR, EFS->RemoveFieldAtPosition(1)); EXPECT_EQ(2, EFS->GetFieldSetCount()); EXPECT_EQ(CHIP_NO_ERROR, EFS->InsertFieldSet(EFS3)); EXPECT_EQ(3, EFS->GetFieldSetCount()); // Verify order EXPECT_EQ(CHIP_NO_ERROR, EFS->GetFieldSetAtPosition(tempEFS, 0)); EXPECT_EQ(tempEFS, EFS2); EXPECT_EQ(CHIP_NO_ERROR, EFS->GetFieldSetAtPosition(tempEFS, 1)); EXPECT_EQ(tempEFS, EFS1); EXPECT_EQ(CHIP_NO_ERROR, EFS->GetFieldSetAtPosition(tempEFS, 2)); EXPECT_EQ(tempEFS, EFS3); // Order in EFS at this point: [EFS2, EFS1, EFS3] // Removal at end EXPECT_EQ(CHIP_NO_ERROR, EFS->RemoveFieldAtPosition(2)); EXPECT_EQ(2, EFS->GetFieldSetCount()); EXPECT_EQ(CHIP_NO_ERROR, EFS->InsertFieldSet(EFS3)); EXPECT_EQ(3, EFS->GetFieldSetCount()); // Verify order EXPECT_EQ(CHIP_NO_ERROR, EFS->GetFieldSetAtPosition(tempEFS, 0)); EXPECT_EQ(tempEFS, EFS2); EXPECT_EQ(CHIP_NO_ERROR, EFS->GetFieldSetAtPosition(tempEFS, 1)); EXPECT_EQ(tempEFS, EFS1); EXPECT_EQ(CHIP_NO_ERROR, EFS->GetFieldSetAtPosition(tempEFS, 2)); EXPECT_EQ(tempEFS, EFS3); // Emptying the table EFS->Clear(); EXPECT_TRUE(EFS->IsEmpty()); } } // namespace TestEFS