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 "annotations.h"
26 #include "stats_event.h"
27 #include "tests/statsd_test_util.h"
28 
29 #ifdef __ANDROID__
30 
31 namespace android {
32 namespace os {
33 namespace statsd {
34 
35 using namespace testing;
36 using std::shared_ptr;
37 using std::vector;
38 /*
39  * Test merge isolated and host uid
40  */
41 namespace {
42 const int uidAtomTagId = 100;
43 const vector<int> additiveFields = {3};
44 const int nonUidAtomTagId = 200;
45 const int timestamp = 1234;
46 const int isolatedUid1 = 30;
47 const int isolatedUid2 = 40;
48 const int isolatedNonAdditiveData = 32;
49 const int isolatedAdditiveData = 31;
50 const int hostUid = 20;
51 const int hostNonAdditiveData = 22;
52 const int hostAdditiveData = 21;
53 const int attributionAtomTagId = 300;
54 
makeMockUidMap()55 sp<MockUidMap> makeMockUidMap() {
56     return makeMockUidMapForOneHost(hostUid, {isolatedUid1, isolatedUid2});
57 }
58 
59 }  // anonymous namespace
60 
TEST(PullerUtilTest,MergeNoDimension)61 TEST(PullerUtilTest, MergeNoDimension) {
62     vector<shared_ptr<LogEvent>> data = {
63             // 30->22->31
64             makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData,
65                             isolatedAdditiveData),
66 
67             // 20->22->21
68             makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData,
69                             hostAdditiveData),
70     };
71 
72     sp<MockUidMap> uidMap = makeMockUidMap();
73     mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
74 
75     ASSERT_EQ(1, (int)data.size());
76     const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
77     ASSERT_EQ(3, actualFieldValues->size());
78     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
79     EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
80     EXPECT_EQ(isolatedAdditiveData + hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
81 }
82 
TEST(PullerUtilTest,MergeWithDimension)83 TEST(PullerUtilTest, MergeWithDimension) {
84     vector<shared_ptr<LogEvent>> data = {
85             // 30->32->31
86             makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
87                             isolatedAdditiveData),
88 
89             // 20->32->21
90             makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
91                             hostAdditiveData),
92 
93             // 20->22->21
94             makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData,
95                             hostAdditiveData),
96     };
97 
98     sp<MockUidMap> uidMap = makeMockUidMap();
99     mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
100 
101     ASSERT_EQ(2, (int)data.size());
102 
103     const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
104     ASSERT_EQ(3, actualFieldValues->size());
105     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
106     EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
107     EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
108 
109     actualFieldValues = &data[1]->getValues();
110     ASSERT_EQ(3, actualFieldValues->size());
111     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
112     EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
113     EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value);
114 }
115 
TEST(PullerUtilTest,NoMergeHostUidOnly)116 TEST(PullerUtilTest, NoMergeHostUidOnly) {
117     vector<shared_ptr<LogEvent>> data = {
118             // 20->32->31
119             makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
120                             isolatedAdditiveData),
121 
122             // 20->22->21
123             makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData,
124                             hostAdditiveData),
125     };
126 
127     sp<MockUidMap> uidMap = makeMockUidMap();
128     mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
129 
130     ASSERT_EQ(2, (int)data.size());
131 
132     const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
133     ASSERT_EQ(3, actualFieldValues->size());
134     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
135     EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
136     EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
137 
138     actualFieldValues = &data[1]->getValues();
139     ASSERT_EQ(3, actualFieldValues->size());
140     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
141     EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
142     EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value);
143 }
144 
TEST(PullerUtilTest,IsolatedUidOnly)145 TEST(PullerUtilTest, IsolatedUidOnly) {
146     vector<shared_ptr<LogEvent>> data = {
147             // 30->32->31
148             makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
149                             isolatedAdditiveData),
150 
151             // 30->22->21
152             makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData,
153                             hostAdditiveData),
154     };
155 
156     sp<MockUidMap> uidMap = makeMockUidMap();
157     mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
158 
159     ASSERT_EQ(2, (int)data.size());
160 
161     // 20->32->31
162     const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
163     ASSERT_EQ(3, actualFieldValues->size());
164     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
165     EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
166     EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
167 
168     // 20->22->21
169     actualFieldValues = &data[1]->getValues();
170     ASSERT_EQ(3, actualFieldValues->size());
171     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
172     EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
173     EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value);
174 }
175 
TEST(PullerUtilTest,MultipleIsolatedUidToOneHostUid)176 TEST(PullerUtilTest, MultipleIsolatedUidToOneHostUid) {
177     vector<shared_ptr<LogEvent>> data = {
178             // 30->32->31
179             makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
180                             isolatedAdditiveData),
181 
182             // 31->32->21
183             makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid2, isolatedNonAdditiveData,
184                             hostAdditiveData),
185 
186             // 20->32->21
187             makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
188                             hostAdditiveData),
189     };
190 
191     sp<MockUidMap> uidMap = makeMockUidMap();
192     mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
193 
194     ASSERT_EQ(1, (int)data.size());
195 
196     const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
197     ASSERT_EQ(3, actualFieldValues->size());
198     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
199     EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
200     EXPECT_EQ(isolatedAdditiveData + hostAdditiveData + hostAdditiveData,
201               actualFieldValues->at(2).mValue.int_value);
202 }
203 
TEST(PullerUtilTest,NoNeedToMerge)204 TEST(PullerUtilTest, NoNeedToMerge) {
205     vector<shared_ptr<LogEvent>> data = {
206             // 32->31
207             CreateTwoValueLogEvent(nonUidAtomTagId, timestamp, isolatedNonAdditiveData,
208                                    isolatedAdditiveData),
209 
210             // 22->21
211             CreateTwoValueLogEvent(nonUidAtomTagId, timestamp, hostNonAdditiveData,
212                                    hostAdditiveData),
213 
214     };
215 
216     sp<MockUidMap> uidMap = makeMockUidMap();
217     mapAndMergeIsolatedUidsToHostUid(data, uidMap, nonUidAtomTagId, {} /*no additive fields*/);
218 
219     ASSERT_EQ(2, (int)data.size());
220 
221     const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
222     ASSERT_EQ(2, actualFieldValues->size());
223     EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(0).mValue.int_value);
224     EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(1).mValue.int_value);
225 
226     actualFieldValues = &data[1]->getValues();
227     ASSERT_EQ(2, actualFieldValues->size());
228     EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(0).mValue.int_value);
229     EXPECT_EQ(hostAdditiveData, actualFieldValues->at(1).mValue.int_value);
230 }
231 
TEST(PullerUtilTest,MergeNoDimensionAttributionChain)232 TEST(PullerUtilTest, MergeNoDimensionAttributionChain) {
233     vector<shared_ptr<LogEvent>> data = {
234             // 30->tag1->400->tag2->22->31
235             makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
236                                     {"tag1", "tag2"}, hostNonAdditiveData, isolatedAdditiveData),
237 
238             // 20->tag1->400->tag2->22->21
239             makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
240                                     {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
241     };
242 
243     sp<MockUidMap> uidMap = makeMockUidMap();
244     mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
245 
246     ASSERT_EQ(1, (int)data.size());
247     const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
248     ASSERT_EQ(6, actualFieldValues->size());
249     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
250     EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
251     EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
252     EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
253     EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
254     EXPECT_EQ(isolatedAdditiveData + hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
255 }
256 
TEST(PullerUtilTest,MergeWithDimensionAttributionChain)257 TEST(PullerUtilTest, MergeWithDimensionAttributionChain) {
258     vector<shared_ptr<LogEvent>> data = {
259             // 200->tag1->30->tag2->32->31
260             makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, isolatedUid1},
261                                     {"tag1", "tag2"}, isolatedNonAdditiveData,
262                                     isolatedAdditiveData),
263 
264             // 200->tag1->20->tag2->32->21
265             makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, hostUid},
266                                     {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData),
267 
268             // 200->tag1->20->tag2->22->21
269             makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, hostUid},
270                                     {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
271     };
272 
273     sp<MockUidMap> uidMap = makeMockUidMap();
274     mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
275 
276     ASSERT_EQ(2, (int)data.size());
277 
278     const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
279     ASSERT_EQ(6, actualFieldValues->size());
280     EXPECT_EQ(200, actualFieldValues->at(0).mValue.int_value);
281     EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
282     EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value);
283     EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
284     EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
285     EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
286 
287     actualFieldValues = &data[1]->getValues();
288     ASSERT_EQ(6, actualFieldValues->size());
289     EXPECT_EQ(200, actualFieldValues->at(0).mValue.int_value);
290     EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
291     EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value);
292     EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
293     EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
294     EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value);
295 }
296 
TEST(PullerUtilTest,NoMergeHostUidOnlyAttributionChain)297 TEST(PullerUtilTest, NoMergeHostUidOnlyAttributionChain) {
298     vector<shared_ptr<LogEvent>> data = {
299             // 20->tag1->400->tag2->32->31
300             makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
301                                     {"tag1", "tag2"}, isolatedNonAdditiveData,
302                                     isolatedAdditiveData),
303 
304             // 20->tag1->400->tag2->22->21
305             makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
306                                     {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
307     };
308 
309     sp<MockUidMap> uidMap = makeMockUidMap();
310     mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
311 
312     ASSERT_EQ(2, (int)data.size());
313 
314     const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
315     ASSERT_EQ(6, actualFieldValues->size());
316     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
317     EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
318     EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
319     EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
320     EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
321     EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
322 
323     actualFieldValues = &data[1]->getValues();
324     ASSERT_EQ(6, actualFieldValues->size());
325     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
326     EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
327     EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
328     EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
329     EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
330     EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value);
331 }
332 
TEST(PullerUtilTest,IsolatedUidOnlyAttributionChain)333 TEST(PullerUtilTest, IsolatedUidOnlyAttributionChain) {
334     vector<shared_ptr<LogEvent>> data = {
335             // 30->tag1->400->tag2->32->31
336             makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
337                                     {"tag1", "tag2"}, isolatedNonAdditiveData,
338                                     isolatedAdditiveData),
339 
340             // 30->tag1->400->tag2->22->21
341             makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
342                                     {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
343     };
344 
345     sp<MockUidMap> uidMap = makeMockUidMap();
346     mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
347 
348     ASSERT_EQ(2, (int)data.size());
349 
350     // 20->tag1->400->tag2->32->31
351     const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
352     ASSERT_EQ(6, actualFieldValues->size());
353     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
354     EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
355     EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
356     EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
357     EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
358     EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
359 
360     // 20->tag1->400->tag2->22->21
361     actualFieldValues = &data[1]->getValues();
362     ASSERT_EQ(6, actualFieldValues->size());
363     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
364     EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
365     EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
366     EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
367     EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
368     EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value);
369 }
370 
TEST(PullerUtilTest,MultipleIsolatedUidToOneHostUidAttributionChain)371 TEST(PullerUtilTest, MultipleIsolatedUidToOneHostUidAttributionChain) {
372     vector<shared_ptr<LogEvent>> data = {
373             // 30->tag1->400->tag2->32->31
374             makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
375                                     {"tag1", "tag2"}, isolatedNonAdditiveData,
376                                     isolatedAdditiveData),
377 
378             // 31->tag1->400->tag2->32->21
379             makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid2, 400},
380                                     {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData),
381 
382             // 20->tag1->400->tag2->32->21
383             makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
384                                     {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData),
385     };
386 
387     sp<MockUidMap> uidMap = makeMockUidMap();
388     mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
389 
390     ASSERT_EQ(1, (int)data.size());
391 
392     const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
393     ASSERT_EQ(6, actualFieldValues->size());
394     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
395     EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
396     EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
397     EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
398     EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
399     EXPECT_EQ(isolatedAdditiveData + hostAdditiveData + hostAdditiveData,
400               actualFieldValues->at(5).mValue.int_value);
401 }
402 
403 }  // namespace statsd
404 }  // namespace os
405 }  // namespace android
406 #else
407 GTEST_LOG_(INFO) << "This test does nothing.\n";
408 #endif
409