blob: 04d349f286667a735d5f7c54f1a29c31bdf61f64 [file] [log] [blame] [edit]
/*
* Copyright (C) 2024 The Android Open Source Project
*
* 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 "chre/util/fragmentation_manager.h"
#include <stdio.h>
#include <type_traits>
#include "chre/util/memory.h"
#include "gtest/gtest.h"
namespace chre::test {
TEST(FragmentationTest, CanRetrieveByteDataTest) {
constexpr size_t dataSize = 9;
constexpr size_t fragmentSize = 3;
uint8_t testData[dataSize];
Optional<Fragment<uint8_t>> fragment;
FragmentationManager<uint8_t, fragmentSize> testManager;
for (size_t i = 0; i < dataSize; i++) {
testData[i] = i;
}
testManager.init(testData, dataSize);
for (size_t iteration = 0; iteration < dataSize / fragmentSize; ++iteration) {
std::cout << iteration << std::endl;
fragment = testManager.getNextFragment();
EXPECT_TRUE(fragment.has_value());
EXPECT_EQ(fragment.value().size, fragmentSize);
for (size_t j = 0; j < fragmentSize; j++) {
EXPECT_EQ(fragment.value().data[j], j + iteration * fragmentSize);
}
}
fragment = testManager.getNextFragment();
EXPECT_FALSE(fragment.has_value());
testManager.deinit();
}
TEST(FragmentationTest, CanRetrieveLongDataTest) {
constexpr size_t dataSize = 10;
constexpr size_t fragmentSize = 3;
uint32_t testData[dataSize];
Optional<Fragment<uint32_t>> fragment;
FragmentationManager<uint32_t, fragmentSize> testManager;
for (size_t i = 0; i < dataSize; i++) {
testData[i] = i;
}
testManager.init(testData, dataSize);
for (size_t iteration = 0; iteration < dataSize / fragmentSize; ++iteration) {
fragment = testManager.getNextFragment();
EXPECT_TRUE(fragment.has_value());
EXPECT_EQ(fragment.value().size, fragmentSize);
for (size_t j = 0; j < fragmentSize; j++) {
EXPECT_EQ(fragment.value().data[j], j + iteration * fragmentSize);
}
}
// Special case for the last element.
fragment = testManager.getNextFragment();
EXPECT_TRUE(fragment.has_value());
EXPECT_EQ(fragment.value().size, 1);
EXPECT_EQ(fragment.value().data[0], testData[dataSize - 1]);
fragment = testManager.getNextFragment();
EXPECT_FALSE(fragment.has_value());
testManager.deinit();
}
TEST(FragmentationTest, FailWhenInitializingWithNullptr) {
constexpr size_t dataSize = 10;
constexpr size_t fragmentSize = 3;
FragmentationManager<uint64_t, fragmentSize> testManager;
EXPECT_FALSE(testManager.init(nullptr, dataSize));
}
TEST(FragmentationTest, CanRetrieveLongComplexDataTest) {
struct Foo {
uint8_t byteData;
uint32_t longData;
uint64_t doubleData;
};
constexpr size_t dataSize = 10;
constexpr size_t fragmentSize = 3;
Foo testData[dataSize];
Optional<Fragment<Foo>> fragment;
FragmentationManager<Foo, fragmentSize> testManager;
for (size_t i = 0; i < dataSize; i++) {
testData[i].byteData = i;
testData[i].longData = static_cast<uint64_t>(i) << 16 | i;
testData[i].doubleData = static_cast<uint64_t>(i) << 32 | i;
}
EXPECT_TRUE(testManager.init(testData, dataSize));
for (size_t iteration = 0; iteration < dataSize / fragmentSize; ++iteration) {
fragment = testManager.getNextFragment();
EXPECT_TRUE(fragment.has_value());
EXPECT_EQ(fragment.value().size, fragmentSize);
for (size_t j = 0; j < fragmentSize; j++) {
uint8_t arrayIndex = j + iteration * fragmentSize;
EXPECT_EQ(
memcmp(&fragment.value().data[j], &testData[arrayIndex], sizeof(Foo)),
0);
}
EXPECT_EQ(fragment.value().data, &testData[iteration * fragmentSize]);
}
// Special case for the last element.
fragment = testManager.getNextFragment();
EXPECT_TRUE(fragment.has_value());
EXPECT_EQ(fragment.value().size, 1);
EXPECT_EQ(
memcmp(&fragment.value().data[0], &testData[dataSize - 1], sizeof(Foo)),
0);
fragment = testManager.getNextFragment();
EXPECT_FALSE(fragment.has_value());
testManager.deinit();
}
TEST(FragmentationTest, CanReuseAfterDeinitInitTest) {
constexpr size_t dataSize = 10;
constexpr size_t fragmentSize = 3;
uint32_t testData[dataSize];
for (size_t i = 0; i < dataSize; i++) {
testData[i] = i;
}
constexpr size_t realDataSize = 13;
uint32_t realTestData[realDataSize];
for (size_t i = 0; i < realDataSize; i++) {
realTestData[i] = UINT32_MAX - i;
}
Optional<Fragment<uint32_t>> fragment;
FragmentationManager<uint32_t, fragmentSize> testManager;
testManager.init(testData, dataSize);
for (size_t iteration = 0; iteration < dataSize / fragmentSize; ++iteration) {
testManager.getNextFragment();
}
testManager.deinit();
testManager.init(realTestData, realDataSize);
for (size_t iteration = 0; iteration < realDataSize / fragmentSize;
++iteration) {
fragment = testManager.getNextFragment();
EXPECT_TRUE(fragment.has_value());
EXPECT_EQ(fragment.value().size, fragmentSize);
for (size_t j = 0; j < fragmentSize; j++) {
EXPECT_EQ(fragment.value().data[j],
realTestData[iteration * fragmentSize + j]);
}
}
// Special case for the last element.
fragment = testManager.getNextFragment();
EXPECT_TRUE(fragment.has_value());
EXPECT_EQ(fragment.value().size, 1);
EXPECT_EQ(fragment.value().data[0], realTestData[realDataSize - 1]);
fragment = testManager.getNextFragment();
EXPECT_FALSE(fragment.has_value());
testManager.deinit();
}
} // namespace chre::test