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