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