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