1 /*
2 * Copyright (C) 2019 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 // Unit Test for EcoData.
18
19 //#define LOG_NDEBUG 0
20 #define LOG_TAG "ECODataTest"
21
22 #include <android-base/unique_fd.h>
23 #include <binder/Parcel.h>
24 #include <binder/Parcelable.h>
25 #include <cutils/ashmem.h>
26 #include <gtest/gtest.h>
27 #include <math.h>
28 #include <stdlib.h>
29 #include <sys/mman.h>
30 #include <utils/Log.h>
31
32 #include "eco/ECOData.h"
33 #include "eco/ECODataKey.h"
34
35 namespace android {
36 namespace media {
37 namespace eco {
38
TEST(EcoDataTest,TestConstructor1)39 TEST(EcoDataTest, TestConstructor1) {
40 std::unique_ptr<ECOData> data = std::make_unique<ECOData>();
41 EXPECT_EQ(data->getDataType(), ECOData::DATA_TYPE_UNKNOWN);
42 EXPECT_EQ(data->getDataTimeUs(), -1);
43 }
44
TEST(EcoDataTest,TestConstructor2)45 TEST(EcoDataTest, TestConstructor2) {
46 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS);
47 EXPECT_EQ(data->getDataType(), ECOData::DATA_TYPE_STATS);
48 EXPECT_EQ(data->getDataTimeUs(), -1);
49 }
50
TEST(EcoDataTest,TestConstructor3)51 TEST(EcoDataTest, TestConstructor3) {
52 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
53 EXPECT_EQ(data->getDataType(), ECOData::DATA_TYPE_STATS);
54 EXPECT_EQ(data->getDataTimeUs(), 1000);
55 }
56
TEST(EcoDataTest,TestNormalSetAndFindString)57 TEST(EcoDataTest, TestNormalSetAndFindString) {
58 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
59
60 data->setString(ENCODER_TYPE, "avc");
61 std::string testValue;
62 EXPECT_TRUE(data->findString(ENCODER_TYPE, &testValue) == ECODataStatus::OK);
63 EXPECT_EQ(testValue, "avc");
64
65 // Override existing key.
66 data->setString(ENCODER_TYPE, "hevc");
67 EXPECT_EQ(data->findString(ENCODER_TYPE, &testValue), ECODataStatus::OK);
68 EXPECT_EQ(testValue, "hevc");
69 }
70
TEST(EcoDataTest,TestSetAndFindMultipleString)71 TEST(EcoDataTest, TestSetAndFindMultipleString) {
72 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
73
74 std::unordered_map<std::string, std::string> inputEntries = {
75 {"name1", "avc"}, {"name2", "avc2"}, {"name3", "avc3"}, {"name4", "avc4"},
76 {"name5", "avc5"}, {"name6", "avc6"}, {"name7", "avc7"}, {"name8", "avc8"},
77 {"name9", "avc9"}, {"name10", "avc10"}, {"name11", "avc11"}, {"name12", "avc12"}};
78 for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
79 data->setString(it->first, it->second);
80 }
81
82 // Checks if the string exist in the ECOData.
83 for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
84 std::string testValue;
85 EXPECT_TRUE(data->findString(it->first, &testValue) == ECODataStatus::OK);
86 EXPECT_EQ(testValue, it->second);
87 }
88 }
89
TEST(EcoDataTest,TestSetAndFindInvalidString)90 TEST(EcoDataTest, TestSetAndFindInvalidString) {
91 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
92
93 // Test read to null ptr and expect failure
94 EXPECT_TRUE(data->findString("encoder-name", nullptr) != ECODataStatus::OK);
95
96 // Test find non-existing key and expect failure.
97 std::string testValue;
98 EXPECT_TRUE(data->findString("encoder-name", &testValue) != ECODataStatus::OK);
99
100 // Test set empty key and expect failure
101 EXPECT_TRUE(data->setString("", "avc") != ECODataStatus::OK);
102
103 // Test read empty key and expect failure
104 EXPECT_TRUE(data->findString("", &testValue) != ECODataStatus::OK);
105 }
106
TEST(EcoDataTest,TestNormalSetAndFindInt32)107 TEST(EcoDataTest, TestNormalSetAndFindInt32) {
108 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
109
110 data->setInt32(ENCODER_TARGET_BITRATE_BPS, 2000000);
111 int32_t testValue;
112 EXPECT_TRUE(data->findInt32(ENCODER_TARGET_BITRATE_BPS, &testValue) == ECODataStatus::OK);
113 EXPECT_EQ(testValue, 2000000);
114
115 // Override existing key.
116 data->setInt32(ENCODER_TARGET_BITRATE_BPS, 2200000);
117 EXPECT_EQ(data->findInt32(ENCODER_TARGET_BITRATE_BPS, &testValue), ECODataStatus::OK);
118 EXPECT_EQ(testValue, 2200000);
119 }
120
TEST(EcoDataTest,TestSetAndFindMultipleInt32)121 TEST(EcoDataTest, TestSetAndFindMultipleInt32) {
122 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
123
124 std::unordered_map<std::string, int32_t> inputEntries = {
125 {"name1", 100}, {"name2", 200}, {"name3", 300}, {"name4", 400},
126 {"name5", 500}, {"name6", 600}, {"name7", 700}, {"name8", 800},
127 {"name9", 900}, {"name10", 10000}, {"name11", 110000}, {"name12", 120000}};
128 for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
129 data->setInt32(it->first, it->second);
130 }
131
132 // Checks if the string exist in the ECOData.
133 for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
134 int32_t testValue;
135 EXPECT_TRUE(data->findInt32(it->first, &testValue) == ECODataStatus::OK);
136 EXPECT_EQ(testValue, it->second);
137 }
138 }
139
TEST(EcoDataTest,TestSetAndFindInvalidInt32)140 TEST(EcoDataTest, TestSetAndFindInvalidInt32) {
141 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
142
143 // Test read to null ptr and expect failure
144 EXPECT_TRUE(data->findInt32("encoder-name", nullptr) != ECODataStatus::OK);
145
146 // Test find non-existing key and expect failure.
147 int32_t testValue;
148 EXPECT_TRUE(data->findInt32("encoder-name", &testValue) != ECODataStatus::OK);
149
150 // Test set empty key and expect failure
151 EXPECT_TRUE(data->setInt32("", 1000) != ECODataStatus::OK);
152
153 // Test read empty key and expect failure
154 EXPECT_TRUE(data->findInt32("", &testValue) != ECODataStatus::OK);
155 }
156
TEST(EcoDataTest,TestNormalSetAndFindInt64)157 TEST(EcoDataTest, TestNormalSetAndFindInt64) {
158 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
159
160 data->setInt64(ENCODER_TARGET_BITRATE_BPS, 2000000);
161 int64_t testValue;
162 EXPECT_TRUE(data->findInt64(ENCODER_TARGET_BITRATE_BPS, &testValue) == ECODataStatus::OK);
163 EXPECT_EQ(testValue, 2000000);
164
165 // Override existing key.
166 data->setInt64(ENCODER_TARGET_BITRATE_BPS, 2200000);
167 EXPECT_EQ(data->findInt64(ENCODER_TARGET_BITRATE_BPS, &testValue), ECODataStatus::OK);
168 EXPECT_EQ(testValue, 2200000);
169 }
170
TEST(EcoDataTest,TestNormalSetAndFindMultipleInt64)171 TEST(EcoDataTest, TestNormalSetAndFindMultipleInt64) {
172 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
173
174 std::unordered_map<std::string, int64_t> inputEntries = {
175 {"name1", 100}, {"name2", 200}, {"name3", 300}, {"name4", 400},
176 {"name5", 500}, {"name6", 600}, {"name7", 700}, {"name8", 800},
177 {"name9", 900}, {"name10", 10000}, {"name11", 110000}, {"name12", 120000}};
178 for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
179 data->setInt64(it->first, it->second);
180 }
181
182 // Checks if the string exist in the ECOData.
183 for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
184 int64_t testValue;
185 EXPECT_TRUE(data->findInt64(it->first, &testValue) == ECODataStatus::OK);
186 EXPECT_EQ(testValue, it->second);
187 }
188 }
189
TEST(EcoDataTest,TestSetAndFindInvalidInt64)190 TEST(EcoDataTest, TestSetAndFindInvalidInt64) {
191 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
192
193 // Test read to null ptr and expect failure
194 EXPECT_TRUE(data->findInt64("encoder-name", nullptr) != ECODataStatus::OK);
195
196 // Test find non-existing key and expect failure.
197 int64_t testValue;
198 EXPECT_TRUE(data->findInt64("encoder-name", &testValue) != ECODataStatus::OK);
199
200 // Test set empty key and expect failure
201 EXPECT_TRUE(data->setInt64("", 1000) != ECODataStatus::OK);
202
203 // Test read empty key and expect failure
204 EXPECT_TRUE(data->findInt64("", &testValue) != ECODataStatus::OK);
205 }
206
TEST(EcoDataTest,TestNormalSetAndFindFloat)207 TEST(EcoDataTest, TestNormalSetAndFindFloat) {
208 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
209
210 data->setFloat(ENCODER_TARGET_BITRATE_BPS, 2000000.0);
211 float testValue;
212 EXPECT_TRUE(data->findFloat(ENCODER_TARGET_BITRATE_BPS, &testValue) == ECODataStatus::OK);
213 EXPECT_FLOAT_EQ(testValue, 2000000.0);
214
215 // Override existing key.
216 data->setFloat(ENCODER_TARGET_BITRATE_BPS, 2200000.0);
217 EXPECT_TRUE(data->findFloat(ENCODER_TARGET_BITRATE_BPS, &testValue) == ECODataStatus::OK);
218 EXPECT_FLOAT_EQ(testValue, 2200000.0);
219 }
220
TEST(EcoDataTest,TestNormalSetAndFindMultipleFloat)221 TEST(EcoDataTest, TestNormalSetAndFindMultipleFloat) {
222 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
223
224 std::unordered_map<std::string, float> inputEntries = {
225 {"name1", 100.0}, {"name2", 200.0}, {"name3", 300.0}, {"name4", 400.0},
226 {"name5", 500.0}, {"name6", 600.0}, {"name7", 700.0}, {"name8", 800.0},
227 {"name9", 900.0}, {"name10", 10000.0}, {"name11", 110000.0}, {"name12", 120000.0}};
228 for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
229 data->setFloat(it->first, it->second);
230 }
231
232 // Checks if the string exist in the ECOData.
233 for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
234 float testValue;
235 EXPECT_TRUE(data->findFloat(it->first, &testValue) == ECODataStatus::OK);
236 EXPECT_FLOAT_EQ(testValue, it->second);
237 }
238 }
239
TEST(EcoDataTest,TestSetAndFindInvalidFloat)240 TEST(EcoDataTest, TestSetAndFindInvalidFloat) {
241 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
242
243 // Test read to null ptr and expect failure
244 EXPECT_TRUE(data->findFloat("encoder-name", nullptr) != ECODataStatus::OK);
245
246 // Test find non-existing key and expect failure.
247 float testValue;
248 EXPECT_TRUE(data->findFloat("encoder-name", &testValue) != ECODataStatus::OK);
249
250 // Test set empty key and expect failure
251 EXPECT_TRUE(data->setFloat("", 1000.0) != ECODataStatus::OK);
252
253 // Test read empty key and expect failure
254 EXPECT_TRUE(data->findFloat("", &testValue) != ECODataStatus::OK);
255 }
256
TEST(EcoDataTest,TestNormalSetAndFindMixedDataType)257 TEST(EcoDataTest, TestNormalSetAndFindMixedDataType) {
258 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
259
260 std::unordered_map<std::string, ECOData::ECODataValueType> inputEntries = {
261 {"name1", "google-encoder"}, {"name2", "avc"}, {"profile", 1}, {"level", 2},
262 {"framerate", 4.1}, {"kfi", 30}};
263 for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
264 data->set(it->first, it->second);
265 }
266
267 // Checks if the string exist in the ECOData.
268 for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
269 ECOData::ECODataValueType testValue;
270 EXPECT_TRUE(data->find(it->first, &testValue) == ECODataStatus::OK);
271 EXPECT_EQ(testValue, it->second);
272 }
273 }
274
TEST(EcoDataTest,TestSetAndFindInvalidDataType)275 TEST(EcoDataTest, TestSetAndFindInvalidDataType) {
276 std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
277
278 // Test read to null ptr and expect failure
279 EXPECT_TRUE(data->find("encoder-name", nullptr) != ECODataStatus::OK);
280
281 // Test find non-existing key and expect failure.
282 ECOData::ECODataValueType testValue;
283 EXPECT_TRUE(data->find("encoder-name2", &testValue) != ECODataStatus::OK);
284
285 // Test set empty key and expect failure
286 EXPECT_TRUE(data->set("", 1000) != ECODataStatus::OK);
287
288 // Test read empty key and expect failure
289 EXPECT_TRUE(data->find("", &testValue) != ECODataStatus::OK);
290 }
291
TEST(EcoDataTest,TestNormalWriteReadParcel)292 TEST(EcoDataTest, TestNormalWriteReadParcel) {
293 constexpr int32_t kDataType = ECOData::DATA_TYPE_STATS;
294 constexpr int64_t kDataTimeUs = 1000;
295
296 std::unique_ptr<ECOData> sourceData = std::make_unique<ECOData>(kDataType, kDataTimeUs);
297
298 std::unordered_map<std::string, ECOData::ECODataValueType> inputEntries = {
299 {"name1", "google-encoder"}, {"name2", "avc"}, {"profile", 1}, {"level", 2},
300 {"framerate", 4.1}, {"kfi", 30}};
301 for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
302 sourceData->set(it->first, it->second);
303 }
304
305 std::unique_ptr<Parcel> parcel = std::make_unique<Parcel>();
306 EXPECT_TRUE(sourceData->writeToParcel(parcel.get()) == NO_ERROR);
307
308 // Rewind the data position of the parcel for this test. Otherwise, the following read will not
309 // start from the beginning.
310 parcel->setDataPosition(0);
311
312 // Reads the parcel back into a new ECOData
313 std::unique_ptr<ECOData> dstData = std::make_unique<ECOData>();
314 EXPECT_TRUE(dstData->readFromParcel(parcel.get()) == NO_ERROR);
315
316 // Checks the data type, time and number of entries.
317 EXPECT_EQ(sourceData->getNumOfEntries(), dstData->getNumOfEntries());
318 EXPECT_EQ(dstData->getDataType(), kDataType);
319 EXPECT_EQ(dstData->getDataTimeUs(), kDataTimeUs);
320
321 for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
322 ECOData::ECODataValueType testValue;
323 EXPECT_TRUE(dstData->find(it->first, &testValue) == ECODataStatus::OK);
324 EXPECT_EQ(testValue, it->second);
325 }
326 }
327
TEST(EcoDataTest,TestWriteInvalidParcel)328 TEST(EcoDataTest, TestWriteInvalidParcel) {
329 constexpr int32_t kDataType = ECOData::DATA_TYPE_STATS;
330 constexpr int64_t kDataTimeUs = 1000;
331
332 std::unique_ptr<ECOData> sourceData = std::make_unique<ECOData>(kDataType, kDataTimeUs);
333
334 std::unique_ptr<Parcel> parcel = std::make_unique<Parcel>();
335 EXPECT_TRUE(sourceData->writeToParcel(nullptr) != NO_ERROR);
336 }
337
TEST(EcoDataTest,TestReadInvalidParcel)338 TEST(EcoDataTest, TestReadInvalidParcel) {
339 constexpr int32_t kDataType = ECOData::DATA_TYPE_STATS;
340 constexpr int64_t kDataTimeUs = 1000;
341
342 std::unique_ptr<ECOData> sourceData = std::make_unique<ECOData>(kDataType, kDataTimeUs);
343
344 std::unordered_map<std::string, ECOData::ECODataValueType> inputEntries = {
345 {"name1", "google-encoder"}, {"name2", "avc"}, {"profile", 1}, {"level", 2},
346 {"framerate", 4.1}, {"kfi", 30}};
347 for (auto it = inputEntries.begin(); it != inputEntries.end(); ++it) {
348 sourceData->set(it->first, it->second);
349 }
350
351 std::unique_ptr<Parcel> parcel = std::make_unique<Parcel>();
352 EXPECT_TRUE(sourceData->writeToParcel(parcel.get()) == NO_ERROR);
353
354 // Corrupt the parcel by write random data to the beginning.
355 parcel->setDataPosition(4);
356 parcel->writeCString("invalid-data");
357
358 parcel->setDataPosition(0);
359
360 // Reads the parcel back into a new ECOData
361 std::unique_ptr<ECOData> dstData = std::make_unique<ECOData>();
362 EXPECT_TRUE(dstData->readFromParcel(parcel.get()) != NO_ERROR);
363 }
364
365 } // namespace eco
366 } // namespace media
367 } // namespace android