1 /*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "chre/util/fragmentation_manager.h"
18 #include <stdio.h>
19 #include <type_traits>
20 #include "chre/util/memory.h"
21 #include "gtest/gtest.h"
22
23 namespace chre::test {
24
TEST(FragmentationTest,CanRetrieveByteDataTest)25 TEST(FragmentationTest, CanRetrieveByteDataTest) {
26 constexpr size_t dataSize = 9;
27 constexpr size_t fragmentSize = 3;
28 uint8_t testData[dataSize];
29 Optional<Fragment<uint8_t>> fragment;
30 FragmentationManager<uint8_t, fragmentSize> testManager;
31
32 for (size_t i = 0; i < dataSize; i++) {
33 testData[i] = i;
34 }
35 testManager.init(testData, dataSize);
36 for (size_t iteration = 0; iteration < dataSize / fragmentSize; ++iteration) {
37 std::cout << iteration << std::endl;
38 fragment = testManager.getNextFragment();
39 EXPECT_TRUE(fragment.has_value());
40 EXPECT_EQ(fragment.value().size, fragmentSize);
41 for (size_t j = 0; j < fragmentSize; j++) {
42 EXPECT_EQ(fragment.value().data[j], j + iteration * fragmentSize);
43 }
44 }
45
46 fragment = testManager.getNextFragment();
47 EXPECT_FALSE(fragment.has_value());
48
49 testManager.deinit();
50 }
51
TEST(FragmentationTest,CanRetrieveLongDataTest)52 TEST(FragmentationTest, CanRetrieveLongDataTest) {
53 constexpr size_t dataSize = 10;
54 constexpr size_t fragmentSize = 3;
55 uint32_t testData[dataSize];
56 Optional<Fragment<uint32_t>> fragment;
57 FragmentationManager<uint32_t, fragmentSize> testManager;
58
59 for (size_t i = 0; i < dataSize; i++) {
60 testData[i] = i;
61 }
62 testManager.init(testData, dataSize);
63 for (size_t iteration = 0; iteration < dataSize / fragmentSize; ++iteration) {
64 fragment = testManager.getNextFragment();
65 EXPECT_TRUE(fragment.has_value());
66 EXPECT_EQ(fragment.value().size, fragmentSize);
67 for (size_t j = 0; j < fragmentSize; j++) {
68 EXPECT_EQ(fragment.value().data[j], j + iteration * fragmentSize);
69 }
70 }
71
72 // Special case for the last element.
73 fragment = testManager.getNextFragment();
74 EXPECT_TRUE(fragment.has_value());
75 EXPECT_EQ(fragment.value().size, 1);
76 EXPECT_EQ(fragment.value().data[0], testData[dataSize - 1]);
77
78 fragment = testManager.getNextFragment();
79 EXPECT_FALSE(fragment.has_value());
80
81 testManager.deinit();
82 }
83
TEST(FragmentationTest,FailWhenInitializingWithNullptr)84 TEST(FragmentationTest, FailWhenInitializingWithNullptr) {
85 constexpr size_t dataSize = 10;
86 constexpr size_t fragmentSize = 3;
87 FragmentationManager<uint64_t, fragmentSize> testManager;
88 EXPECT_FALSE(testManager.init(nullptr, dataSize));
89 }
90
TEST(FragmentationTest,CanRetrieveLongComplexDataTest)91 TEST(FragmentationTest, CanRetrieveLongComplexDataTest) {
92 struct Foo {
93 uint8_t byteData;
94 uint32_t longData;
95 uint64_t doubleData;
96 };
97
98 constexpr size_t dataSize = 10;
99 constexpr size_t fragmentSize = 3;
100 Foo testData[dataSize];
101 Optional<Fragment<Foo>> fragment;
102 FragmentationManager<Foo, fragmentSize> testManager;
103
104 for (size_t i = 0; i < dataSize; i++) {
105 testData[i].byteData = i;
106 testData[i].longData = static_cast<uint64_t>(i) << 16 | i;
107 testData[i].doubleData = static_cast<uint64_t>(i) << 32 | i;
108 }
109
110 EXPECT_TRUE(testManager.init(testData, dataSize));
111 for (size_t iteration = 0; iteration < dataSize / fragmentSize; ++iteration) {
112 fragment = testManager.getNextFragment();
113 EXPECT_TRUE(fragment.has_value());
114 EXPECT_EQ(fragment.value().size, fragmentSize);
115 for (size_t j = 0; j < fragmentSize; j++) {
116 uint8_t arrayIndex = j + iteration * fragmentSize;
117 EXPECT_EQ(
118 memcmp(&fragment.value().data[j], &testData[arrayIndex], sizeof(Foo)),
119 0);
120 }
121 EXPECT_EQ(fragment.value().data, &testData[iteration * fragmentSize]);
122 }
123
124 // Special case for the last element.
125 fragment = testManager.getNextFragment();
126 EXPECT_TRUE(fragment.has_value());
127 EXPECT_EQ(fragment.value().size, 1);
128 EXPECT_EQ(
129 memcmp(&fragment.value().data[0], &testData[dataSize - 1], sizeof(Foo)),
130 0);
131
132 fragment = testManager.getNextFragment();
133 EXPECT_FALSE(fragment.has_value());
134
135 testManager.deinit();
136 }
137
TEST(FragmentationTest,CanReuseAfterDeinitInitTest)138 TEST(FragmentationTest, CanReuseAfterDeinitInitTest) {
139 constexpr size_t dataSize = 10;
140 constexpr size_t fragmentSize = 3;
141 uint32_t testData[dataSize];
142 for (size_t i = 0; i < dataSize; i++) {
143 testData[i] = i;
144 }
145
146 constexpr size_t realDataSize = 13;
147 uint32_t realTestData[realDataSize];
148 for (size_t i = 0; i < realDataSize; i++) {
149 realTestData[i] = UINT32_MAX - i;
150 }
151
152 Optional<Fragment<uint32_t>> fragment;
153 FragmentationManager<uint32_t, fragmentSize> testManager;
154
155 testManager.init(testData, dataSize);
156 for (size_t iteration = 0; iteration < dataSize / fragmentSize; ++iteration) {
157 testManager.getNextFragment();
158 }
159 testManager.deinit();
160
161 testManager.init(realTestData, realDataSize);
162 for (size_t iteration = 0; iteration < realDataSize / fragmentSize;
163 ++iteration) {
164 fragment = testManager.getNextFragment();
165 EXPECT_TRUE(fragment.has_value());
166 EXPECT_EQ(fragment.value().size, fragmentSize);
167 for (size_t j = 0; j < fragmentSize; j++) {
168 EXPECT_EQ(fragment.value().data[j],
169 realTestData[iteration * fragmentSize + j]);
170 }
171 }
172
173 // Special case for the last element.
174 fragment = testManager.getNextFragment();
175 EXPECT_TRUE(fragment.has_value());
176 EXPECT_EQ(fragment.value().size, 1);
177 EXPECT_EQ(fragment.value().data[0], realTestData[realDataSize - 1]);
178
179 fragment = testManager.getNextFragment();
180 EXPECT_FALSE(fragment.has_value());
181
182 testManager.deinit();
183 }
184
185 } // namespace chre::test
186