• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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