1 // Copyright (C) 2018 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "external/puller_util.h"
16
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 #include <stdio.h>
20
21 #include <vector>
22
23 #include "../metrics/metrics_test_helper.h"
24 #include "FieldValue.h"
25 #include "stats_event.h"
26 #include "tests/statsd_test_util.h"
27
28 #ifdef __ANDROID__
29
30 namespace android {
31 namespace os {
32 namespace statsd {
33
34 using namespace testing;
35 using std::shared_ptr;
36 using std::vector;
37 /*
38 * Test merge isolated and host uid
39 */
40 namespace {
41 const int uidAtomTagId = 100;
42 const vector<int> additiveFields = {3};
43 const int nonUidAtomTagId = 200;
44 const int timestamp = 1234;
45 const int isolatedUid1 = 30;
46 const int isolatedUid2 = 40;
47 const int isolatedNonAdditiveData = 32;
48 const int isolatedAdditiveData = 31;
49 const int hostUid = 20;
50 const int hostNonAdditiveData = 22;
51 const int hostAdditiveData = 21;
52 const int attributionAtomTagId = 300;
53 const int hostUid2 = 2000;
54 const int isolatedUid3 = 3000;
55 const int isolatedUid4 = 4000;
56
makeMockUidMap()57 sp<MockUidMap> makeMockUidMap() {
58 return makeMockUidMapForHosts(
59 {{hostUid, {isolatedUid1, isolatedUid2}}, {hostUid2, {isolatedUid3, isolatedUid4}}});
60 }
61
62 } // anonymous namespace
63
TEST(PullerUtilTest,MergeNoDimension)64 TEST(PullerUtilTest, MergeNoDimension) {
65 vector<shared_ptr<LogEvent>> data = {
66 // 30->22->31
67 makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData,
68 isolatedAdditiveData),
69
70 // 20->22->21
71 makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData,
72 hostAdditiveData),
73 };
74
75 sp<MockUidMap> uidMap = makeMockUidMap();
76 mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
77
78 ASSERT_EQ(1, (int)data.size());
79 const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
80 ASSERT_EQ(3, actualFieldValues->size());
81 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
82 EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
83 EXPECT_EQ(isolatedAdditiveData + hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
84 }
85
TEST(PullerUtilTest,MergeWithDimension)86 TEST(PullerUtilTest, MergeWithDimension) {
87 vector<shared_ptr<LogEvent>> data = {
88 // 30->32->31
89 makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
90 isolatedAdditiveData),
91
92 // 20->32->21
93 makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
94 hostAdditiveData),
95
96 // 20->22->21
97 makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData,
98 hostAdditiveData),
99 };
100
101 sp<MockUidMap> uidMap = makeMockUidMap();
102 mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
103
104 ASSERT_EQ(2, (int)data.size());
105
106 const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
107 ASSERT_EQ(3, actualFieldValues->size());
108 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
109 EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
110 EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
111
112 actualFieldValues = &data[1]->getValues();
113 ASSERT_EQ(3, actualFieldValues->size());
114 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
115 EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
116 EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value);
117 }
118
TEST(PullerUtilTest,NoMergeHostUidOnly)119 TEST(PullerUtilTest, NoMergeHostUidOnly) {
120 vector<shared_ptr<LogEvent>> data = {
121 // 20->32->31
122 makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
123 isolatedAdditiveData),
124
125 // 20->22->21
126 makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData,
127 hostAdditiveData),
128 };
129
130 sp<MockUidMap> uidMap = makeMockUidMap();
131 mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
132
133 ASSERT_EQ(2, (int)data.size());
134
135 const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
136 ASSERT_EQ(3, actualFieldValues->size());
137 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
138 EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
139 EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
140
141 actualFieldValues = &data[1]->getValues();
142 ASSERT_EQ(3, actualFieldValues->size());
143 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
144 EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
145 EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value);
146 }
147
TEST(PullerUtilTest,IsolatedUidOnly)148 TEST(PullerUtilTest, IsolatedUidOnly) {
149 vector<shared_ptr<LogEvent>> data = {
150 // 30->32->31
151 makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
152 isolatedAdditiveData),
153
154 // 30->22->21
155 makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData,
156 hostAdditiveData),
157 };
158
159 sp<MockUidMap> uidMap = makeMockUidMap();
160 mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
161
162 ASSERT_EQ(2, (int)data.size());
163
164 // 20->32->31
165 const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
166 ASSERT_EQ(3, actualFieldValues->size());
167 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
168 EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
169 EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
170
171 // 20->22->21
172 actualFieldValues = &data[1]->getValues();
173 ASSERT_EQ(3, actualFieldValues->size());
174 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
175 EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
176 EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value);
177 }
178
TEST(PullerUtilTest,MultipleIsolatedUidToOneHostUid)179 TEST(PullerUtilTest, MultipleIsolatedUidToOneHostUid) {
180 vector<shared_ptr<LogEvent>> data = {
181 // 30->32->31
182 makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
183 isolatedAdditiveData),
184
185 // 40->32->21
186 makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid2, isolatedNonAdditiveData,
187 hostAdditiveData),
188
189 // 20->32->21
190 makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
191 hostAdditiveData),
192 };
193
194 sp<MockUidMap> uidMap = makeMockUidMap();
195 mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
196
197 ASSERT_EQ(1, (int)data.size());
198
199 const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
200 ASSERT_EQ(3, actualFieldValues->size());
201 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
202 EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
203 EXPECT_EQ(isolatedAdditiveData + hostAdditiveData + hostAdditiveData,
204 actualFieldValues->at(2).mValue.int_value);
205 }
206
TEST(PullerUtilTest,TwoIsolatedUidsOneAtom)207 TEST(PullerUtilTest, TwoIsolatedUidsOneAtom) {
208 vector<shared_ptr<LogEvent>> data = {
209 makeExtraUidsLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
210 isolatedAdditiveData, {isolatedUid3}),
211
212 makeExtraUidsLogEvent(uidAtomTagId, timestamp, isolatedUid2, isolatedNonAdditiveData,
213 hostAdditiveData, {isolatedUid4}),
214
215 makeExtraUidsLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
216 hostAdditiveData, {hostUid2}),
217 };
218
219 sp<MockUidMap> uidMap = makeMockUidMap();
220 mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
221
222 ASSERT_EQ(1, (int)data.size());
223
224 const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
225 ASSERT_EQ(4, actualFieldValues->size());
226 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
227 EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
228 EXPECT_EQ(isolatedAdditiveData + hostAdditiveData + hostAdditiveData,
229 actualFieldValues->at(2).mValue.int_value);
230 EXPECT_EQ(hostUid2, actualFieldValues->at(3).mValue.int_value);
231 }
232
TEST(PullerUtilTest,NoNeedToMerge)233 TEST(PullerUtilTest, NoNeedToMerge) {
234 vector<shared_ptr<LogEvent>> data = {
235 // 32->31
236 CreateTwoValueLogEvent(nonUidAtomTagId, timestamp, isolatedNonAdditiveData,
237 isolatedAdditiveData),
238
239 // 22->21
240 CreateTwoValueLogEvent(nonUidAtomTagId, timestamp, hostNonAdditiveData,
241 hostAdditiveData),
242
243 };
244
245 sp<MockUidMap> uidMap = makeMockUidMap();
246 mapAndMergeIsolatedUidsToHostUid(data, uidMap, nonUidAtomTagId, {} /*no additive fields*/);
247
248 ASSERT_EQ(2, (int)data.size());
249
250 const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
251 ASSERT_EQ(2, actualFieldValues->size());
252 EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(0).mValue.int_value);
253 EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(1).mValue.int_value);
254
255 actualFieldValues = &data[1]->getValues();
256 ASSERT_EQ(2, actualFieldValues->size());
257 EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(0).mValue.int_value);
258 EXPECT_EQ(hostAdditiveData, actualFieldValues->at(1).mValue.int_value);
259 }
260
TEST(PullerUtilTest,MergeNoDimensionAttributionChain)261 TEST(PullerUtilTest, MergeNoDimensionAttributionChain) {
262 vector<shared_ptr<LogEvent>> data = {
263 // 30->tag1->400->tag2->22->31
264 makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
265 {"tag1", "tag2"}, hostNonAdditiveData, isolatedAdditiveData),
266
267 // 20->tag1->400->tag2->22->21
268 makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
269 {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
270 };
271
272 sp<MockUidMap> uidMap = makeMockUidMap();
273 mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
274
275 ASSERT_EQ(1, (int)data.size());
276 const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
277 ASSERT_EQ(6, actualFieldValues->size());
278 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
279 EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
280 EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
281 EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
282 EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
283 EXPECT_EQ(isolatedAdditiveData + hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
284 }
285
TEST(PullerUtilTest,MergeWithDimensionAttributionChain)286 TEST(PullerUtilTest, MergeWithDimensionAttributionChain) {
287 vector<shared_ptr<LogEvent>> data = {
288 // 200->tag1->30->tag2->32->31
289 makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, isolatedUid1},
290 {"tag1", "tag2"}, isolatedNonAdditiveData,
291 isolatedAdditiveData),
292
293 // 200->tag1->20->tag2->32->21
294 makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, hostUid},
295 {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData),
296
297 // 200->tag1->20->tag2->22->21
298 makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, hostUid},
299 {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
300 };
301
302 sp<MockUidMap> uidMap = makeMockUidMap();
303 mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
304
305 ASSERT_EQ(2, (int)data.size());
306
307 const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
308 ASSERT_EQ(6, actualFieldValues->size());
309 EXPECT_EQ(200, actualFieldValues->at(0).mValue.int_value);
310 EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
311 EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value);
312 EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
313 EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
314 EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
315
316 actualFieldValues = &data[1]->getValues();
317 ASSERT_EQ(6, actualFieldValues->size());
318 EXPECT_EQ(200, actualFieldValues->at(0).mValue.int_value);
319 EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
320 EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value);
321 EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
322 EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
323 EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value);
324 }
325
TEST(PullerUtilTest,NoMergeHostUidOnlyAttributionChain)326 TEST(PullerUtilTest, NoMergeHostUidOnlyAttributionChain) {
327 vector<shared_ptr<LogEvent>> data = {
328 // 20->tag1->400->tag2->32->31
329 makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
330 {"tag1", "tag2"}, isolatedNonAdditiveData,
331 isolatedAdditiveData),
332
333 // 20->tag1->400->tag2->22->21
334 makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
335 {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
336 };
337
338 sp<MockUidMap> uidMap = makeMockUidMap();
339 mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
340
341 ASSERT_EQ(2, (int)data.size());
342
343 const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
344 ASSERT_EQ(6, actualFieldValues->size());
345 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
346 EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
347 EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
348 EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
349 EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
350 EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
351
352 actualFieldValues = &data[1]->getValues();
353 ASSERT_EQ(6, actualFieldValues->size());
354 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
355 EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
356 EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
357 EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
358 EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
359 EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value);
360 }
361
TEST(PullerUtilTest,IsolatedUidOnlyAttributionChain)362 TEST(PullerUtilTest, IsolatedUidOnlyAttributionChain) {
363 vector<shared_ptr<LogEvent>> data = {
364 // 30->tag1->400->tag2->32->31
365 makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
366 {"tag1", "tag2"}, isolatedNonAdditiveData,
367 isolatedAdditiveData),
368
369 // 30->tag1->400->tag2->22->21
370 makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
371 {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
372 };
373
374 sp<MockUidMap> uidMap = makeMockUidMap();
375 mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
376
377 ASSERT_EQ(2, (int)data.size());
378
379 // 20->tag1->400->tag2->32->31
380 const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
381 ASSERT_EQ(6, actualFieldValues->size());
382 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
383 EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
384 EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
385 EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
386 EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
387 EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
388
389 // 20->tag1->400->tag2->22->21
390 actualFieldValues = &data[1]->getValues();
391 ASSERT_EQ(6, actualFieldValues->size());
392 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
393 EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
394 EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
395 EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
396 EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
397 EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value);
398 }
399
TEST(PullerUtilTest,MultipleIsolatedUidToOneHostUidAttributionChain)400 TEST(PullerUtilTest, MultipleIsolatedUidToOneHostUidAttributionChain) {
401 vector<shared_ptr<LogEvent>> data = {
402 // 30->tag1->400->tag2->32->31
403 makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
404 {"tag1", "tag2"}, isolatedNonAdditiveData,
405 isolatedAdditiveData),
406
407 // 31->tag1->400->tag2->32->21
408 makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid2, 400},
409 {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData),
410
411 // 20->tag1->400->tag2->32->21
412 makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
413 {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData),
414 };
415
416 sp<MockUidMap> uidMap = makeMockUidMap();
417 mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
418
419 ASSERT_EQ(1, (int)data.size());
420
421 const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
422 ASSERT_EQ(6, actualFieldValues->size());
423 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
424 EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
425 EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
426 EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
427 EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
428 EXPECT_EQ(isolatedAdditiveData + hostAdditiveData + hostAdditiveData,
429 actualFieldValues->at(5).mValue.int_value);
430 }
431
432 // Test that repeated fields are treated as non-additive fields even when marked as additive.
TEST(PullerUtilTest,RepeatedAdditiveField)433 TEST(PullerUtilTest, RepeatedAdditiveField) {
434 vector<int> int32Array1 = {3, 6};
435 vector<int> int32Array2 = {6, 9};
436
437 vector<shared_ptr<LogEvent>> data = {
438 // 30->22->{3,6}
439 makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData,
440 int32Array1),
441
442 // 30->22->{6,9}
443 makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData,
444 int32Array2),
445
446 // 20->22->{3,6}
447 makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData, int32Array1),
448 };
449
450 sp<MockUidMap> uidMap = makeMockUidMap();
451 mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
452
453 ASSERT_EQ(2, (int)data.size());
454 // Events 1 and 3 are merged - non-additive fields, including the repeated additive field, are
455 // equal.
456 const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
457 ASSERT_EQ(4, actualFieldValues->size());
458 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
459 EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
460 EXPECT_EQ(3, actualFieldValues->at(2).mValue.int_value);
461 EXPECT_EQ(6, actualFieldValues->at(3).mValue.int_value);
462
463 // Event 2 isn't merged - repeated additive field is not equal.
464 actualFieldValues = &data[1]->getValues();
465 ASSERT_EQ(4, actualFieldValues->size());
466 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
467 EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
468 EXPECT_EQ(6, actualFieldValues->at(2).mValue.int_value);
469 EXPECT_EQ(9, actualFieldValues->at(3).mValue.int_value);
470 }
471
472 // Test that repeated uid events are sorted and merged correctly.
TEST(PullerUtilTest,RepeatedUidField)473 TEST(PullerUtilTest, RepeatedUidField) {
474 vector<int> uidArray1 = {isolatedUid1, hostUid};
475 vector<int> uidArray2 = {isolatedUid1, isolatedUid3};
476 vector<int> uidArray3 = {isolatedUid1, hostUid, isolatedUid2};
477
478 vector<shared_ptr<LogEvent>> data = {
479 // {30, 20}->22->21
480 makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray1, hostNonAdditiveData,
481 hostAdditiveData),
482
483 // {30, 3000}->22->21 (different uid, not merged)
484 makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray2, hostNonAdditiveData,
485 hostAdditiveData),
486
487 // {30, 20}->22->31 (different additive field, merged)
488 makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray1, hostNonAdditiveData,
489 isolatedAdditiveData),
490
491 // {30, 20}->32->21 (different non-additive field, not merged)
492 makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray1, isolatedNonAdditiveData,
493 hostAdditiveData),
494
495 // {30, 20, 40}->22->21 (different repeated uid length, not merged)
496 makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray3, hostNonAdditiveData,
497 hostAdditiveData),
498
499 // {30, 20}->22->21 (same as first event, merged)
500 makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray1, hostNonAdditiveData,
501 hostAdditiveData),
502 };
503
504 sp<MockUidMap> uidMap = makeMockUidMap();
505 mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
506
507 ASSERT_EQ(4, (int)data.size());
508 // Events 1 and 3 and 6 are merged.
509 const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
510 ASSERT_EQ(4, actualFieldValues->size());
511 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
512 EXPECT_EQ(hostUid, actualFieldValues->at(1).mValue.int_value);
513 EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(2).mValue.int_value);
514 EXPECT_EQ(hostAdditiveData + isolatedAdditiveData + hostAdditiveData,
515 actualFieldValues->at(3).mValue.int_value);
516
517 // Event 4 isn't merged - different non-additive data.
518 actualFieldValues = &data[1]->getValues();
519 ASSERT_EQ(4, actualFieldValues->size());
520 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
521 EXPECT_EQ(hostUid, actualFieldValues->at(1).mValue.int_value);
522 EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(2).mValue.int_value);
523 EXPECT_EQ(hostAdditiveData, actualFieldValues->at(3).mValue.int_value);
524
525 // Event 2 isn't merged - different uid.
526 actualFieldValues = &data[2]->getValues();
527 ASSERT_EQ(4, actualFieldValues->size());
528 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
529 EXPECT_EQ(hostUid2, actualFieldValues->at(1).mValue.int_value);
530 EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(2).mValue.int_value);
531 EXPECT_EQ(hostAdditiveData, actualFieldValues->at(3).mValue.int_value);
532
533 // Event 5 isn't merged - different repeated uid length.
534 actualFieldValues = &data[3]->getValues();
535 ASSERT_EQ(5, actualFieldValues->size());
536 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
537 EXPECT_EQ(hostUid, actualFieldValues->at(1).mValue.int_value);
538 EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value);
539 EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(3).mValue.int_value);
540 EXPECT_EQ(hostAdditiveData, actualFieldValues->at(4).mValue.int_value);
541 }
542
543 // Test that repeated uid events with multiple repeated non-additive fields are sorted and merged
544 // correctly.
TEST(PullerUtilTest,MultipleRepeatedFields)545 TEST(PullerUtilTest, MultipleRepeatedFields) {
546 vector<int> uidArray1 = {isolatedUid1, hostUid};
547 vector<int> uidArray2 = {isolatedUid1, isolatedUid3};
548 vector<int> uidArray3 = {isolatedUid1, hostUid, isolatedUid2};
549
550 vector<int> nonAdditiveArray1 = {1, 2, 3};
551 vector<int> nonAdditiveArray2 = {1, 5, 3};
552 vector<int> nonAdditiveArray3 = {1, 2};
553
554 const vector<int> secondAdditiveField = {2};
555
556 vector<shared_ptr<LogEvent>> data = {
557 // TODO: Once b/224880904 is fixed, can use different additive data without
558 // having the sort order messed up.
559
560 // Event 1 {30, 20}->21->{1, 2, 3} (merged with event 4)
561 makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray1, hostAdditiveData,
562 nonAdditiveArray1),
563
564 // Event 2 {30, 3000}->21->{1, 2, 3} (different uid, not merged)
565 makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray2, hostAdditiveData,
566 nonAdditiveArray1),
567
568 // Event 3 {30, 20, 40}->21->{1, 2} (different repeated fields with total length equal
569 // to event 1, merged with event 6)
570 makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray3, hostAdditiveData,
571 nonAdditiveArray3),
572
573 // Event 4 {30, 20}->21->{1, 2, 3} (merged with event 1)
574 // TODO: once sorting bug is fixed, can change this additive field
575 makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray1, hostAdditiveData,
576 nonAdditiveArray1),
577
578 // Event 5 {30, 20}->21->{1, 5, 3} (different repeated field, not merged)
579 makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray1, hostAdditiveData,
580 nonAdditiveArray2),
581
582 // Event 6 {30, 20, 40}->22->{1, 2} (different repeated fields with total length equal
583 // to event 1, merged with event 3)
584 makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray3, isolatedAdditiveData,
585 nonAdditiveArray3),
586 };
587
588 // Expected event ordering after the sort:
589 // Event 3 {30, 20, 40}->21->{1, 2} (total size equal to event 1, merged with event 6)
590 // Event 6 {30, 20, 40}->22->{1, 2} (total size equal to event 1, merged with event 3)
591 // Event 1 {30, 20}->21->{1, 2, 3}
592 // Event 4 {30, 20}->21->{1, 2, 3} (merged with event 1)
593 // Event 5 {30, 20}->21->{1, 5, 3} (different repeated field, not merged)
594 // Event 2 {30, 3000}->21->{1, 2, 3} (different uid, not merged)
595
596 sp<MockUidMap> uidMap = makeMockUidMap();
597 mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, secondAdditiveField);
598
599 ASSERT_EQ(4, (int)data.size());
600
601 // Events 3 and 6 are merged. Not merged with event 1 because different repeated uids and
602 // fields, though length is same.
603 const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
604 ASSERT_EQ(6, actualFieldValues->size());
605 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
606 EXPECT_EQ(hostUid, actualFieldValues->at(1).mValue.int_value);
607 EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value);
608 EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(3).mValue.int_value);
609 EXPECT_EQ(1, actualFieldValues->at(4).mValue.int_value);
610 EXPECT_EQ(2, actualFieldValues->at(5).mValue.int_value);
611
612 // Events 1 and 4 are merged.
613 actualFieldValues = &data[1]->getValues();
614 ASSERT_EQ(6, actualFieldValues->size());
615 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
616 EXPECT_EQ(hostUid, actualFieldValues->at(1).mValue.int_value);
617 EXPECT_EQ(hostAdditiveData + hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
618 EXPECT_EQ(1, actualFieldValues->at(3).mValue.int_value);
619 EXPECT_EQ(2, actualFieldValues->at(4).mValue.int_value);
620 EXPECT_EQ(3, actualFieldValues->at(5).mValue.int_value);
621
622 // Event 5 isn't merged - different repeated field.
623 actualFieldValues = &data[2]->getValues();
624 ASSERT_EQ(6, actualFieldValues->size());
625 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
626 EXPECT_EQ(hostUid, actualFieldValues->at(1).mValue.int_value);
627 EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
628 EXPECT_EQ(1, actualFieldValues->at(3).mValue.int_value);
629 EXPECT_EQ(5, actualFieldValues->at(4).mValue.int_value);
630 EXPECT_EQ(3, actualFieldValues->at(5).mValue.int_value);
631
632 // Event 2 isn't merged - different uid.
633 actualFieldValues = &data[3]->getValues();
634 ASSERT_EQ(6, actualFieldValues->size());
635 EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
636 EXPECT_EQ(hostUid2, actualFieldValues->at(1).mValue.int_value);
637 EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
638 EXPECT_EQ(1, actualFieldValues->at(3).mValue.int_value);
639 EXPECT_EQ(2, actualFieldValues->at(4).mValue.int_value);
640 EXPECT_EQ(3, actualFieldValues->at(5).mValue.int_value);
641 }
642
643 } // namespace statsd
644 } // namespace os
645 } // namespace android
646 #else
647 GTEST_LOG_(INFO) << "This test does nothing.\n";
648 #endif
649