blob: 09ca114b2847503bbca5f43db9dbd4a55691ab76 [file] [log] [blame]
Andy Hungc89c8dc2019-10-16 17:48:21 -07001/*
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#define LOG_TAG "mediametrics_tests"
18#include <utils/Log.h>
19
20#include "MediaAnalyticsService.h"
21
22#include <stdio.h>
23
24#include <gtest/gtest.h>
25#include <media/MediaAnalyticsItem.h>
26
27using namespace android;
28
29TEST(mediametrics_tests, instantiate) {
30 sp mediaMetrics = new MediaAnalyticsService();
31 status_t status;
32
Andy Hungc89c8dc2019-10-16 17:48:21 -070033 // random keys ignored when empty
Andy Hunga87e69c2019-10-18 10:07:40 -070034 std::unique_ptr<MediaAnalyticsItem> random_key(MediaAnalyticsItem::create("random_key"));
35 status = mediaMetrics->submit(random_key.get());
36 ASSERT_EQ(PERMISSION_DENIED, status);
Andy Hungc89c8dc2019-10-16 17:48:21 -070037
38 // random keys ignored with data
Andy Hungc89c8dc2019-10-16 17:48:21 -070039 random_key->setInt32("foo", 10);
Andy Hunga87e69c2019-10-18 10:07:40 -070040 status = mediaMetrics->submit(random_key.get());
41 ASSERT_EQ(PERMISSION_DENIED, status);
Andy Hungc89c8dc2019-10-16 17:48:21 -070042
43 // known keys ignored if empty
Andy Hunga87e69c2019-10-18 10:07:40 -070044 std::unique_ptr<MediaAnalyticsItem> audiotrack_key(MediaAnalyticsItem::create("audiotrack"));
45 status = mediaMetrics->submit(audiotrack_key.get());
46 ASSERT_EQ(BAD_VALUE, status);
Andy Hungc89c8dc2019-10-16 17:48:21 -070047
Andy Hunga87e69c2019-10-18 10:07:40 -070048 // known keys not ignored if not empty
49 audiotrack_key->addInt32("foo", 10);
50 status = mediaMetrics->submit(audiotrack_key.get());
51 ASSERT_EQ(NO_ERROR, status);
Andy Hungc89c8dc2019-10-16 17:48:21 -070052
Andy Hungaeef7882019-10-18 15:18:14 -070053
54 /*
55 // fluent style that goes directly to mediametrics
56 ASSERT_EQ(true, MediaAnalyticsItem("audiorecord")
57 .setInt32("value", 2)
58 .addInt32("bar", 1)
59 .addInt32("value", 3)
60 .selfrecord());
61 */
62
Andy Hungc89c8dc2019-10-16 17:48:21 -070063 mediaMetrics->dump(fileno(stdout), {} /* args */);
64}
Andy Hungaeef7882019-10-18 15:18:14 -070065
66TEST(mediametrics_tests, item_manipulation) {
67 MediaAnalyticsItem item("audiorecord");
68
69 item.setInt32("value", 2).addInt32("bar", 3).addInt32("value", 4);
70
71 int32_t i32;
72 ASSERT_TRUE(item.getInt32("value", &i32));
73 ASSERT_EQ(6, i32);
74
75 ASSERT_TRUE(item.getInt32("bar", &i32));
76 ASSERT_EQ(3, i32);
77
78 item.setInt64("big", INT64_MAX).setInt64("smaller", INT64_MAX - 1).addInt64("smaller", -2);
79
80 int64_t i64;
81 ASSERT_TRUE(item.getInt64("big", &i64));
82 ASSERT_EQ(INT64_MAX, i64);
83
84 ASSERT_TRUE(item.getInt64("smaller", &i64));
85 ASSERT_EQ(INT64_MAX - 3, i64);
86
87 item.setDouble("precise", 10.5).setDouble("small", 0.125).addDouble("precise", 0.25);
88
89 double d;
90 ASSERT_TRUE(item.getDouble("precise", &d));
91 ASSERT_EQ(10.75, d);
92
93 ASSERT_TRUE(item.getDouble("small", &d));
94 ASSERT_EQ(0.125, d);
95
96 char *s;
97 item.setCString("name", "Frank").setCString("mother", "June").setCString("mother", "July");
98 ASSERT_TRUE(item.getCString("name", &s));
99 ASSERT_EQ(0, strcmp(s, "Frank"));
100 free(s);
101
102 ASSERT_TRUE(item.getCString("mother", &s));
103 ASSERT_EQ(0, strcmp(s, "July")); // "July" overwrites "June"
104 free(s);
105
106 item.setRate("burgersPerHour", 5, 2);
107 int64_t b, h;
108 ASSERT_TRUE(item.getRate("burgersPerHour", &b, &h, &d));
109 ASSERT_EQ(5, b);
110 ASSERT_EQ(2, h);
111 ASSERT_EQ(2.5, d);
112
113 item.addRate("burgersPerHour", 4, 2);
114 ASSERT_TRUE(item.getRate("burgersPerHour", &b, &h, &d));
115 ASSERT_EQ(9, b);
116 ASSERT_EQ(4, h);
117 ASSERT_EQ(2.25, d);
118
119 printf("item: %s\n", item.toString().c_str());
120 fflush(stdout);
121
122 sp mediaMetrics = new MediaAnalyticsService();
123 status_t status = mediaMetrics->submit(&item);
124 ASSERT_EQ(NO_ERROR, status);
125 mediaMetrics->dump(fileno(stdout), {} /* args */);
126}
127
128TEST(mediametrics_tests, superbig_item) {
129 MediaAnalyticsItem item("TheBigOne");
130 constexpr size_t count = 10000;
131
132 for (size_t i = 0; i < count; ++i) {
133 item.setInt32(std::to_string(i).c_str(), i);
134 }
135 for (size_t i = 0; i < count; ++i) {
136 int32_t i32;
137 ASSERT_TRUE(item.getInt32(std::to_string(i).c_str(), &i32));
138 ASSERT_EQ((int32_t)i, i32);
139 }
140}
141
142TEST(mediametrics_tests, superbig_item_removal) {
143 MediaAnalyticsItem item("TheOddBigOne");
144 constexpr size_t count = 10000;
145
146 for (size_t i = 0; i < count; ++i) {
147 item.setInt32(std::to_string(i).c_str(), i);
148 }
149 for (size_t i = 0; i < count; i += 2) {
150 item.filter(std::to_string(i).c_str()); // filter out all the evens.
151 }
152 for (size_t i = 0; i < count; ++i) {
153 int32_t i32;
154 if (i & 1) { // check to see that only the odds are left.
155 ASSERT_TRUE(item.getInt32(std::to_string(i).c_str(), &i32));
156 ASSERT_EQ((int32_t)i, i32);
157 } else {
158 ASSERT_FALSE(item.getInt32(std::to_string(i).c_str(), &i32));
159 }
160 }
161}
162
Andy Hung3253f2d2019-10-21 14:50:07 -0700163TEST(mediametrics_tests, superbig_item_removal2) {
164 MediaAnalyticsItem item("TheOne");
165 constexpr size_t count = 10000;
166
167 for (size_t i = 0; i < count; ++i) {
168 item.setInt32(std::to_string(i).c_str(), i);
169 }
170 static const char *attrs[] = { "1", };
171 item.filterNot(1, attrs);
172
173 for (size_t i = 0; i < count; ++i) {
174 int32_t i32;
175 if (i == 1) { // check to see that there is only one
176 ASSERT_TRUE(item.getInt32(std::to_string(i).c_str(), &i32));
177 ASSERT_EQ((int32_t)i, i32);
178 } else {
179 ASSERT_FALSE(item.getInt32(std::to_string(i).c_str(), &i32));
180 }
181 }
182}
183
Andy Hungaeef7882019-10-18 15:18:14 -0700184TEST(mediametrics_tests, item_transmutation) {
185 MediaAnalyticsItem item("Alchemist's Stone");
186
187 item.setInt64("convert", 123);
188 int64_t i64;
189 ASSERT_TRUE(item.getInt64("convert", &i64));
190 ASSERT_EQ(123, i64);
191
192 item.addInt32("convert", 2); // changes type of 'convert' from i64 to i32 (and re-init).
193 ASSERT_FALSE(item.getInt64("convert", &i64)); // should be false, no value in i64.
194
195 int32_t i32;
196 ASSERT_TRUE(item.getInt32("convert", &i32)); // check it is i32 and 2 (123 is discarded).
197 ASSERT_EQ(2, i32);
198}
Andy Hung3253f2d2019-10-21 14:50:07 -0700199
200TEST(mediametrics_tests, item_binderization) {
201 MediaAnalyticsItem item;
202 item.setInt32("i32", 1)
203 .setInt64("i64", 2)
204 .setDouble("double", 3.1)
205 .setCString("string", "abc")
206 .setRate("rate", 11, 12);
207
208 Parcel p;
209 item.writeToParcel(&p);
210
211 p.setDataPosition(0); // rewind for reading
212 MediaAnalyticsItem item2;
213 item2.readFromParcel(p);
214
215 ASSERT_EQ(item, item2);
216}
217
218TEST(mediametrics_tests, item_byteserialization) {
219 MediaAnalyticsItem item;
220 item.setInt32("i32", 1)
221 .setInt64("i64", 2)
222 .setDouble("double", 3.1)
223 .setCString("string", "abc")
224 .setRate("rate", 11, 12);
225
226 char *data;
227 size_t length;
228 ASSERT_EQ(0, item.writeToByteString(&data, &length));
229 ASSERT_GT(length, (size_t)0);
230
231 MediaAnalyticsItem item2;
232 item2.readFromByteString(data, length);
233
234 printf("item: %s\n", item.toString().c_str());
235 printf("item2: %s\n", item2.toString().c_str());
236 ASSERT_EQ(item, item2);
237
238 free(data);
239}
240
241TEST(mediametrics_tests, item_iteration) {
242 MediaAnalyticsItem item;
243 item.setInt32("i32", 1)
244 .setInt64("i64", 2)
245 .setDouble("double", 3.125)
246 .setCString("string", "abc")
247 .setRate("rate", 11, 12);
248
249 int mask = 0;
250 for (auto &prop : item) {
251 const char *name = prop.getName();
252 if (!strcmp(name, "i32")) {
253 int32_t i32;
254 ASSERT_TRUE(prop.get(&i32));
255 ASSERT_EQ(1, i32);
256 mask |= 1;
257 } else if (!strcmp(name, "i64")) {
258 int64_t i64;
259 ASSERT_TRUE(prop.get(&i64));
260 ASSERT_EQ(2, i64);
261 mask |= 2;
262 } else if (!strcmp(name, "double")) {
263 double d;
264 ASSERT_TRUE(prop.get(&d));
265 ASSERT_EQ(3.125, d);
266 mask |= 4;
267 } else if (!strcmp(name, "string")) {
268 const char *s;
269 ASSERT_TRUE(prop.get(&s));
270 ASSERT_EQ(0, strcmp(s, "abc"));
271 mask |= 8;
272 } else if (!strcmp(name, "rate")) {
273 std::pair<int64_t, int64_t> r;
274 ASSERT_TRUE(prop.get(&r));
275 ASSERT_EQ(11, r.first);
276 ASSERT_EQ(12, r.second);
277 mask |= 16;
278 } else {
279 FAIL();
280 }
281 }
282 ASSERT_EQ(31, mask);
283}