1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include <gtest/gtest.h>
17
18 #include "src/stats_log.pb.h"
19 #include "src/statsd_config.pb.h"
20 #include "matchers/matcher_util.h"
21 #include "src/logd/LogEvent.h"
22 #include "stats_event.h"
23 #include "stats_log_util.h"
24 #include "stats_util.h"
25 #include "subscriber/SubscriberReporter.h"
26 #include "tests/statsd_test_util.h"
27
28 #ifdef __ANDROID__
29
30 using android::util::ProtoReader;
31
32 namespace android {
33 namespace os {
34 namespace statsd {
35
36 namespace {
37
makeLogEvent(LogEvent * logEvent,const int32_t atomId,const int64_t timestamp,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name)38 void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
39 const vector<int>& attributionUids, const vector<string>& attributionTags,
40 const string& name) {
41 AStatsEvent* statsEvent = AStatsEvent_obtain();
42 AStatsEvent_setAtomId(statsEvent, atomId);
43 AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
44
45 writeAttribution(statsEvent, attributionUids, attributionTags);
46 AStatsEvent_writeString(statsEvent, name.c_str());
47
48 parseStatsEventToLogEvent(statsEvent, logEvent);
49 }
50
makeLogEvent(LogEvent * logEvent,const int32_t atomId,const int64_t timestamp,const vector<int> & attributionUids,const vector<string> & attributionTags,const int32_t value)51 void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
52 const vector<int>& attributionUids, const vector<string>& attributionTags,
53 const int32_t value) {
54 AStatsEvent* statsEvent = AStatsEvent_obtain();
55 AStatsEvent_setAtomId(statsEvent, atomId);
56 AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
57
58 writeAttribution(statsEvent, attributionUids, attributionTags);
59 AStatsEvent_writeInt32(statsEvent, value);
60
61 parseStatsEventToLogEvent(statsEvent, logEvent);
62 }
63
makeRepeatedIntLogEvent(LogEvent * logEvent,const int32_t atomId,const vector<int> & intArray)64 void makeRepeatedIntLogEvent(LogEvent* logEvent, const int32_t atomId, const vector<int>& intArray)
65 __INTRODUCED_IN(__ANDROID_API_T__) {
66 AStatsEvent* statsEvent = AStatsEvent_obtain();
67 AStatsEvent_setAtomId(statsEvent, atomId);
68 AStatsEvent_writeInt32Array(statsEvent, intArray.data(), intArray.size());
69 parseStatsEventToLogEvent(statsEvent, logEvent);
70 }
71 } // anonymous namespace
72
TEST(AtomMatcherTest,TestFieldTranslation)73 TEST(AtomMatcherTest, TestFieldTranslation) {
74 FieldMatcher matcher1;
75 matcher1.set_field(10);
76 FieldMatcher* child = matcher1.add_child();
77 child->set_field(1);
78 child->set_position(Position::ANY);
79
80 child = child->add_child();
81 child->set_field(1);
82
83 vector<Matcher> output;
84 translateFieldMatcher(matcher1, &output);
85
86 ASSERT_EQ((size_t)1, output.size());
87
88 const auto& matcher12 = output[0];
89 EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
90 EXPECT_EQ((int32_t)0x02010001, matcher12.mMatcher.getField());
91 EXPECT_EQ((int32_t)0xff7f007f, matcher12.mMask);
92 }
93
TEST(AtomMatcherTest,TestFieldTranslation_ALL)94 TEST(AtomMatcherTest, TestFieldTranslation_ALL) {
95 FieldMatcher matcher1;
96 matcher1.set_field(10);
97 FieldMatcher* child = matcher1.add_child();
98 child->set_field(1);
99 child->set_position(Position::ALL);
100
101 child = child->add_child();
102 child->set_field(1);
103
104 vector<Matcher> output;
105 translateFieldMatcher(matcher1, &output);
106
107 ASSERT_EQ((size_t)1, output.size());
108
109 const auto& matcher12 = output[0];
110 EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
111 EXPECT_EQ((int32_t)0x02010001, matcher12.mMatcher.getField());
112 EXPECT_EQ((int32_t)0xff7f7f7f, matcher12.mMask);
113 }
114
TEST(AtomMatcherTest,TestFilter_ALL)115 TEST(AtomMatcherTest, TestFilter_ALL) {
116 FieldMatcher matcher1;
117 matcher1.set_field(10);
118 FieldMatcher* child = matcher1.add_child();
119 child->set_field(1);
120 child->set_position(Position::ALL);
121
122 child->add_child()->set_field(1);
123 child->add_child()->set_field(2);
124
125 child = matcher1.add_child();
126 child->set_field(2);
127
128 vector<Matcher> matchers;
129 translateFieldMatcher(matcher1, &matchers);
130
131 std::vector<int> attributionUids = {1111, 2222, 3333};
132 std::vector<string> attributionTags = {"location1", "location2", "location3"};
133
134 LogEvent event(/*uid=*/0, /*pid=*/0);
135 makeLogEvent(&event, 10 /*atomId*/, /*timestamp=*/1012345, attributionUids, attributionTags,
136 "some value");
137 HashableDimensionKey output;
138
139 filterValues(matchers, event.getValues(), &output);
140
141 ASSERT_EQ((size_t)7, output.getValues().size());
142 EXPECT_EQ((int32_t)0x02010101, output.getValues()[0].mField.getField());
143 EXPECT_EQ((int32_t)1111, output.getValues()[0].mValue.int_value);
144 EXPECT_EQ((int32_t)0x02010102, output.getValues()[1].mField.getField());
145 EXPECT_EQ("location1", output.getValues()[1].mValue.str_value);
146
147 EXPECT_EQ((int32_t)0x02010201, output.getValues()[2].mField.getField());
148 EXPECT_EQ((int32_t)2222, output.getValues()[2].mValue.int_value);
149 EXPECT_EQ((int32_t)0x02010202, output.getValues()[3].mField.getField());
150 EXPECT_EQ("location2", output.getValues()[3].mValue.str_value);
151
152 EXPECT_EQ((int32_t)0x02010301, output.getValues()[4].mField.getField());
153 EXPECT_EQ((int32_t)3333, output.getValues()[4].mValue.int_value);
154 EXPECT_EQ((int32_t)0x02010302, output.getValues()[5].mField.getField());
155 EXPECT_EQ("location3", output.getValues()[5].mValue.str_value);
156
157 EXPECT_EQ((int32_t)0x00020000, output.getValues()[6].mField.getField());
158 EXPECT_EQ("some value", output.getValues()[6].mValue.str_value);
159 }
160
TEST(AtomMatcherTest,TestFilter_FIRST)161 TEST(AtomMatcherTest, TestFilter_FIRST) {
162 FieldMatcher matcher1;
163 matcher1.set_field(10);
164 FieldMatcher* child = matcher1.add_child();
165 child->set_field(1);
166 child->set_position(Position::FIRST);
167
168 child->add_child()->set_field(1);
169 child->add_child()->set_field(2);
170
171 child = matcher1.add_child();
172 child->set_field(2);
173
174 vector<Matcher> matchers;
175 translateFieldMatcher(matcher1, &matchers);
176
177 std::vector<int> attributionUids = {1111, 2222, 3333};
178 std::vector<string> attributionTags = {"location1", "location2", "location3"};
179
180 LogEvent event(/*uid=*/0, /*pid=*/0);
181 makeLogEvent(&event, 10 /*atomId*/, 1012345, attributionUids, attributionTags, "some value");
182 HashableDimensionKey output;
183
184 filterValues(matchers, event.getValues(), &output);
185
186 ASSERT_EQ((size_t)3, output.getValues().size());
187 EXPECT_EQ((int32_t)0x02010101, output.getValues()[0].mField.getField());
188 EXPECT_EQ((int32_t)1111, output.getValues()[0].mValue.int_value);
189 EXPECT_EQ((int32_t)0x02010102, output.getValues()[1].mField.getField());
190 EXPECT_EQ("location1", output.getValues()[1].mValue.str_value);
191 EXPECT_EQ((int32_t)0x00020000, output.getValues()[2].mField.getField());
192 EXPECT_EQ("some value", output.getValues()[2].mValue.str_value);
193 };
194
TEST_GUARDED(AtomMatcherTest,TestFilterRepeated_FIRST,__ANDROID_API_T__)195 TEST_GUARDED(AtomMatcherTest, TestFilterRepeated_FIRST, __ANDROID_API_T__) {
196 FieldMatcher matcher;
197 matcher.set_field(123);
198 FieldMatcher* child = matcher.add_child();
199 child->set_field(1);
200 child->set_position(Position::FIRST);
201
202 vector<Matcher> matchers;
203 translateFieldMatcher(matcher, &matchers);
204
205 LogEvent event(/*uid=*/0, /*pid=*/0);
206 vector<int> intArray = {21, 9, 13};
207 makeRepeatedIntLogEvent(&event, 123, intArray);
208
209 HashableDimensionKey output;
210 EXPECT_TRUE(filterValues(matchers, event.getValues(), &output));
211
212 ASSERT_EQ((size_t)1, output.getValues().size());
213 EXPECT_EQ((int32_t)0x01010100, output.getValues()[0].mField.getField());
214 EXPECT_EQ((int32_t)21, output.getValues()[0].mValue.int_value);
215 }
216
TEST_GUARDED(AtomMatcherTest,TestFilterRepeated_LAST,__ANDROID_API_T__)217 TEST_GUARDED(AtomMatcherTest, TestFilterRepeated_LAST, __ANDROID_API_T__) {
218 FieldMatcher matcher;
219 matcher.set_field(123);
220 FieldMatcher* child = matcher.add_child();
221 child->set_field(1);
222 child->set_position(Position::LAST);
223
224 vector<Matcher> matchers;
225 translateFieldMatcher(matcher, &matchers);
226
227 LogEvent event(/*uid=*/0, /*pid=*/0);
228 vector<int> intArray = {21, 9, 13};
229 makeRepeatedIntLogEvent(&event, 123, intArray);
230
231 HashableDimensionKey output;
232 EXPECT_TRUE(filterValues(matchers, event.getValues(), &output));
233
234 ASSERT_EQ((size_t)1, output.getValues().size());
235 EXPECT_EQ((int32_t)0x01018000, output.getValues()[0].mField.getField());
236 EXPECT_EQ((int32_t)13, output.getValues()[0].mValue.int_value);
237 }
238
TEST_GUARDED(AtomMatcherTest,TestFilterRepeated_ALL,__ANDROID_API_T__)239 TEST_GUARDED(AtomMatcherTest, TestFilterRepeated_ALL, __ANDROID_API_T__) {
240 FieldMatcher matcher;
241 matcher.set_field(123);
242 FieldMatcher* child = matcher.add_child();
243 child->set_field(1);
244 child->set_position(Position::ALL);
245
246 vector<Matcher> matchers;
247 translateFieldMatcher(matcher, &matchers);
248
249 LogEvent event(/*uid=*/0, /*pid=*/0);
250 vector<int> intArray = {21, 9, 13};
251 makeRepeatedIntLogEvent(&event, 123, intArray);
252
253 HashableDimensionKey output;
254 EXPECT_TRUE(filterValues(matchers, event.getValues(), &output));
255
256 ASSERT_EQ((size_t)3, output.getValues().size());
257 EXPECT_EQ((int32_t)0x01010100, output.getValues()[0].mField.getField());
258 EXPECT_EQ((int32_t)21, output.getValues()[0].mValue.int_value);
259 EXPECT_EQ((int32_t)0x01010200, output.getValues()[1].mField.getField());
260 EXPECT_EQ((int32_t)9, output.getValues()[1].mValue.int_value);
261 EXPECT_EQ((int32_t)0x01010300, output.getValues()[2].mField.getField());
262 EXPECT_EQ((int32_t)13, output.getValues()[2].mValue.int_value);
263 }
264
TEST(AtomMatcherTest,TestFilterWithOneMatcher)265 TEST(AtomMatcherTest, TestFilterWithOneMatcher) {
266 FieldMatcher matcher;
267 matcher.set_field(10);
268 FieldMatcher* child = matcher.add_child();
269 child->set_field(2);
270
271 vector<Matcher> matchers;
272 translateFieldMatcher(matcher, &matchers);
273
274 std::vector<int> attributionUids = {1111, 2222, 3333};
275 std::vector<string> attributionTags = {"location1", "location2", "location3"};
276
277 LogEvent event(/*uid=*/0, /*pid=*/0);
278 makeLogEvent(&event, 10 /*atomId*/, /*timestamp=*/1012345, attributionUids, attributionTags,
279 "some value");
280 FieldValue value;
281
282 EXPECT_TRUE(filterValues(matchers[0], event.getValues(), &value));
283 EXPECT_EQ((int32_t)0x20000, value.mField.getField());
284 EXPECT_EQ("some value", value.mValue.str_value);
285 }
286
TEST(AtomMatcherTest,TestFilterWithOneMatcher_PositionFIRST)287 TEST(AtomMatcherTest, TestFilterWithOneMatcher_PositionFIRST) {
288 FieldMatcher matcher;
289 matcher.set_field(10);
290 FieldMatcher* child = matcher.add_child();
291 child->set_field(1);
292 child->set_position(Position::FIRST);
293 child->add_child()->set_field(1);
294
295 vector<Matcher> matchers;
296 translateFieldMatcher(matcher, &matchers);
297
298 std::vector<int> attributionUids = {1111, 2222, 3333};
299 std::vector<string> attributionTags = {"location1", "location2", "location3"};
300
301 LogEvent event(/*uid=*/0, /*pid=*/0);
302 makeLogEvent(&event, 10 /*atomId*/, /*timestamp=*/1012345, attributionUids, attributionTags,
303 "some value");
304 FieldValue value;
305
306 // Should only match the first field.
307 EXPECT_TRUE(filterValues(matchers[0], event.getValues(), &value));
308 EXPECT_EQ((int32_t)0x02010101, value.mField.getField());
309 EXPECT_EQ((int32_t)1111, value.mValue.int_value);
310 }
311
TEST(AtomMatcherTest,TestFilterWithOneMatcher_PositionLAST)312 TEST(AtomMatcherTest, TestFilterWithOneMatcher_PositionLAST) {
313 FieldMatcher matcher;
314 matcher.set_field(10);
315 FieldMatcher* child = matcher.add_child();
316 child->set_field(1);
317 child->set_position(Position::LAST);
318 child->add_child()->set_field(1);
319
320 vector<Matcher> matchers;
321 translateFieldMatcher(matcher, &matchers);
322
323 std::vector<int> attributionUids = {1111, 2222, 3333};
324 std::vector<string> attributionTags = {"location1", "location2", "location3"};
325
326 LogEvent event(/*uid=*/0, /*pid=*/0);
327 makeLogEvent(&event, 10 /*atomId*/, /*timestamp=*/1012345, attributionUids, attributionTags,
328 "some value");
329 FieldValue value;
330
331 // Should only match the last field.
332 EXPECT_TRUE(filterValues(matchers[0], event.getValues(), &value));
333 EXPECT_EQ((int32_t)0x02018301, value.mField.getField());
334 EXPECT_EQ((int32_t)3333, value.mValue.int_value);
335 }
336
TEST(AtomMatcherTest,TestFilterWithOneMatcher_PositionALL)337 TEST(AtomMatcherTest, TestFilterWithOneMatcher_PositionALL) {
338 FieldMatcher matcher;
339 matcher.set_field(10);
340 FieldMatcher* child = matcher.add_child();
341 child->set_field(1);
342 child->set_position(Position::ALL);
343 child->add_child()->set_field(1);
344
345 vector<Matcher> matchers;
346 translateFieldMatcher(matcher, &matchers);
347
348 std::vector<int> attributionUids = {1111, 2222, 3333};
349 std::vector<string> attributionTags = {"location1", "location2", "location3"};
350
351 LogEvent event(/*uid=*/0, /*pid=*/0);
352 makeLogEvent(&event, 10 /*atomId*/, 1012345, attributionUids, attributionTags, "some value");
353 FieldValue value;
354
355 // Can't filter with position ALL matcher.
356 EXPECT_FALSE(filterValues(matchers[0], event.getValues(), &value));
357 }
358
TEST(AtomMatcherTest,TestFilterWithOneMatcher_DifferentField)359 TEST(AtomMatcherTest, TestFilterWithOneMatcher_DifferentField) {
360 FieldMatcher matcher;
361 matcher.set_field(10);
362 FieldMatcher* child = matcher.add_child();
363 child->set_field(3);
364
365 vector<Matcher> matchers;
366 translateFieldMatcher(matcher, &matchers);
367
368 std::vector<int> attributionUids = {1111, 2222, 3333};
369 std::vector<string> attributionTags = {"location1", "location2", "location3"};
370
371 LogEvent event(/*uid=*/0, /*pid=*/0);
372 makeLogEvent(&event, 10 /*atomId*/, /*timestamp=*/1012345, attributionUids, attributionTags,
373 "some value");
374 FieldValue value;
375
376 // Shouldn't match any fields because matcher is looking for field 3.
377 EXPECT_FALSE(filterValues(matchers[0], event.getValues(), &value));
378 }
379
TEST(AtomMatcherTest,TestFilterWithOneMatcher_EmptyAttributionUids)380 TEST(AtomMatcherTest, TestFilterWithOneMatcher_EmptyAttributionUids) {
381 FieldMatcher matcher;
382 matcher.set_field(10);
383 FieldMatcher* child = matcher.add_child();
384 child->set_field(1);
385 child->set_position(Position::ALL);
386 child->add_child()->set_field(1);
387
388 vector<Matcher> matchers;
389 translateFieldMatcher(matcher, &matchers);
390
391 std::vector<string> attributionTags = {"location1", "location2", "location3"};
392
393 LogEvent event(/*uid=*/0, /*pid=*/0);
394 makeLogEvent(&event, 10 /*atomId*/, /*timestamp=*/1012345, {}, attributionTags, "some value");
395 FieldValue value;
396
397 // Shouldn't match any fields because field 1 is empty.
398 EXPECT_FALSE(filterValues(matchers[0], event.getValues(), &value));
399 }
400
TEST(AtomMatcherTest,TestSubDimension)401 TEST(AtomMatcherTest, TestSubDimension) {
402 HashableDimensionKey dim;
403
404 int pos1[] = {1, 1, 1};
405 int pos2[] = {1, 1, 2};
406 int pos3[] = {1, 1, 3};
407 int pos4[] = {2, 0, 0};
408 Field field1(10, pos1, 2);
409 Field field2(10, pos2, 2);
410
411 Field field3(10, pos3, 2);
412 Field field4(10, pos4, 0);
413
414 Value value1((int32_t)10025);
415 Value value2("tag");
416
417 Value value11((int32_t)10026);
418 Value value22("tag2");
419
420 dim.addValue(FieldValue(field1, value1));
421 dim.addValue(FieldValue(field2, value2));
422
423 HashableDimensionKey subDim1;
424 subDim1.addValue(FieldValue(field1, value1));
425
426 HashableDimensionKey subDim2;
427 subDim1.addValue(FieldValue(field2, value2));
428
429 EXPECT_TRUE(dim.contains(dim));
430 EXPECT_TRUE(dim.contains(subDim1));
431 EXPECT_TRUE(dim.contains(subDim2));
432
433 HashableDimensionKey subDim3;
434 subDim3.addValue(FieldValue(field1, value11));
435 EXPECT_FALSE(dim.contains(subDim3));
436
437 HashableDimensionKey subDim4;
438 // Empty dimension is always a sub dimension of other dimensions
439 EXPECT_TRUE(dim.contains(subDim4));
440 }
441
TEST(AtomMatcherTest,TestMetric2ConditionLink)442 TEST(AtomMatcherTest, TestMetric2ConditionLink) {
443 std::vector<int> attributionUids = {1111, 2222, 3333};
444 std::vector<string> attributionTags = {"location1", "location2", "location3"};
445
446 LogEvent event(/*uid=*/0, /*pid=*/0);
447 makeLogEvent(&event, 10 /*atomId*/, 12345, attributionUids, attributionTags, "some value");
448
449 FieldMatcher whatMatcher;
450 whatMatcher.set_field(10);
451 FieldMatcher* child11 = whatMatcher.add_child();
452 child11->set_field(1);
453 child11->set_position(Position::ANY);
454 child11 = child11->add_child();
455 child11->set_field(1);
456
457 FieldMatcher conditionMatcher;
458 conditionMatcher.set_field(27);
459 FieldMatcher* child2 = conditionMatcher.add_child();
460 child2->set_field(2);
461 child2->set_position(Position::LAST);
462
463 child2 = child2->add_child();
464 child2->set_field(2);
465
466 Metric2Condition link;
467
468 translateFieldMatcher(whatMatcher, &link.metricFields);
469 translateFieldMatcher(conditionMatcher, &link.conditionFields);
470
471 ASSERT_EQ((size_t)1, link.metricFields.size());
472 EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField());
473 EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask);
474 EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag());
475
476 ASSERT_EQ((size_t)1, link.conditionFields.size());
477 EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField());
478 EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask);
479 EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag());
480 }
481
TEST(AtomMatcherTest,TestWriteDimensionPath)482 TEST(AtomMatcherTest, TestWriteDimensionPath) {
483 for (auto position : {Position::ALL, Position::FIRST, Position::LAST}) {
484 FieldMatcher matcher1;
485 matcher1.set_field(10);
486
487 // Repeated nested fields (attribution chain).
488 FieldMatcher* child = matcher1.add_child();
489 child->set_field(2);
490 child->set_position(position);
491 child->add_child()->set_field(1);
492 child->add_child()->set_field(3);
493
494 // Primitive field.
495 child = matcher1.add_child();
496 child->set_field(4);
497
498 // Repeated primitive field.
499 child = matcher1.add_child();
500 child->set_field(6);
501 child->set_position(position);
502
503 vector<Matcher> matchers;
504 translateFieldMatcher(matcher1, &matchers);
505
506 android::util::ProtoOutputStream protoOut;
507 writeDimensionPathToProto(matchers, &protoOut);
508
509 vector<uint8_t> outData;
510 outData.resize(protoOut.size());
511 size_t pos = 0;
512 sp<ProtoReader> reader = protoOut.data();
513 while (reader->readBuffer() != NULL) {
514 size_t toRead = reader->currentToRead();
515 std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
516 pos += toRead;
517 reader->move(toRead);
518 }
519
520 DimensionsValue result;
521 ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
522
523 EXPECT_EQ(10, result.field());
524 EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
525 ASSERT_EQ(3, result.value_tuple().dimensions_value_size());
526
527 const auto& dim1 = result.value_tuple().dimensions_value(0);
528 EXPECT_EQ(2, dim1.field());
529 ASSERT_EQ(2, dim1.value_tuple().dimensions_value_size());
530
531 const auto& dim11 = dim1.value_tuple().dimensions_value(0);
532 EXPECT_EQ(1, dim11.field());
533
534 const auto& dim12 = dim1.value_tuple().dimensions_value(1);
535 EXPECT_EQ(3, dim12.field());
536
537 const auto& dim2 = result.value_tuple().dimensions_value(1);
538 EXPECT_EQ(4, dim2.field());
539
540 const auto& dim3 = result.value_tuple().dimensions_value(2);
541 EXPECT_EQ(6, dim3.field());
542 }
543 }
544
TEST(AtomMatcherTest,TestDedupFieldMatchersAllDifferent)545 TEST(AtomMatcherTest, TestDedupFieldMatchersAllDifferent) {
546 // Matchers: Fields 1, 2, 3
547 FieldMatcher matcher1;
548 matcher1.set_field(10);
549 FieldMatcher* child = matcher1.add_child();
550 child->set_field(1);
551 child = matcher1.add_child();
552 child->set_field(2);
553 child = matcher1.add_child();
554 child->set_field(3);
555
556 vector<Matcher> fieldMatchers;
557 translateFieldMatcher(matcher1, &fieldMatchers);
558 ASSERT_EQ(3, fieldMatchers.size());
559
560 // Deduped Matchers: Fields 1, 2, 3
561 std::vector<Matcher> dedupedFieldMatchers = dedupFieldMatchers(fieldMatchers);
562 ASSERT_EQ((size_t)3, dedupedFieldMatchers.size());
563 EXPECT_EQ(fieldMatchers[0], dedupedFieldMatchers[0]);
564 EXPECT_EQ(fieldMatchers[1], dedupedFieldMatchers[1]);
565 EXPECT_EQ(fieldMatchers[2], dedupedFieldMatchers[2]);
566 }
567
TEST(AtomMatcherTest,TestDedupFieldMatchersAllSame)568 TEST(AtomMatcherTest, TestDedupFieldMatchersAllSame) {
569 // Matcher: Fields 1, 1, 1
570 FieldMatcher matcher1;
571 matcher1.set_field(10);
572 FieldMatcher* child = matcher1.add_child();
573 child->set_field(1);
574 child = matcher1.add_child();
575 child->set_field(1);
576 child = matcher1.add_child();
577 child->set_field(1);
578
579 vector<Matcher> fieldMatchers;
580 translateFieldMatcher(matcher1, &fieldMatchers);
581 ASSERT_EQ(3, fieldMatchers.size());
582
583 // Deduped Matchers: Fields 1, 1, 1
584 std::vector<Matcher> dedupedFieldMatchers = dedupFieldMatchers(fieldMatchers);
585 ASSERT_EQ((size_t)1, dedupedFieldMatchers.size());
586 EXPECT_EQ(fieldMatchers[0], dedupedFieldMatchers[0]);
587 }
588
TEST(AtomMatcherTest,TestDedupFieldMatcherMixOfFields)589 TEST(AtomMatcherTest, TestDedupFieldMatcherMixOfFields) {
590 // Matcher: Fields 2, 2, 1, 3, 2, 1, 3
591 FieldMatcher matcher1;
592 matcher1.set_field(10);
593 FieldMatcher* child = matcher1.add_child();
594 child->set_field(2);
595 child = matcher1.add_child();
596 child->set_field(2);
597 child = matcher1.add_child();
598 child->set_field(1);
599 child = matcher1.add_child();
600 child->set_field(3);
601 child = matcher1.add_child();
602 child->set_field(2);
603 child = matcher1.add_child();
604 child->set_field(1);
605 child = matcher1.add_child();
606 child->set_field(3);
607
608 vector<Matcher> fieldMatchers;
609 translateFieldMatcher(matcher1, &fieldMatchers);
610 ASSERT_EQ(7, fieldMatchers.size());
611
612 // Deduped Matchers: Fields 2, 1, 3
613 std::vector<Matcher> dedupedFieldMatchers = dedupFieldMatchers(fieldMatchers);
614 ASSERT_EQ((size_t)3, dedupedFieldMatchers.size());
615 EXPECT_EQ(fieldMatchers[0], dedupedFieldMatchers[0]);
616 EXPECT_EQ(fieldMatchers[2], dedupedFieldMatchers[1]);
617 EXPECT_EQ(fieldMatchers[3], dedupedFieldMatchers[2]);
618 }
619
TEST(AtomMatcherTest,TestDedupFieldMatcherDifferentPositionSameFields)620 TEST(AtomMatcherTest, TestDedupFieldMatcherDifferentPositionSameFields) {
621 // Matcher: Fields 3, 1.1(FIRST), 1.2(FIRST), 1.1(FIRST), 1.1(LAST), 1.2(FIRST), 2
622 FieldMatcher matcher1;
623 matcher1.set_field(10);
624 FieldMatcher* child = matcher1.add_child();
625 child->set_field(3);
626 child = matcher1.add_child();
627 child->set_field(1);
628 child->set_position(Position::FIRST);
629 child->add_child()->set_field(1);
630 child = matcher1.add_child();
631 child->set_field(1);
632 child->set_position(Position::FIRST);
633 child->add_child()->set_field(2);
634 child = matcher1.add_child();
635 child->set_field(1);
636 child->set_position(Position::FIRST);
637 child->add_child()->set_field(1);
638 child = matcher1.add_child();
639 child->set_field(1);
640 child->set_position(Position::LAST);
641 child->add_child()->set_field(1);
642 child = matcher1.add_child();
643 child->set_field(1);
644 child->set_position(Position::FIRST);
645 child->add_child()->set_field(2);
646 child = matcher1.add_child();
647 child->set_field(2);
648
649 vector<Matcher> fieldMatchers;
650 translateFieldMatcher(matcher1, &fieldMatchers);
651 ASSERT_EQ(7, fieldMatchers.size());
652
653 // Deduped Matchers: Fields 3, 1.1(FIRST), 1.2(FIRST), 1.1(LAST) 2
654 std::vector<Matcher> dedupedFieldMatchers = dedupFieldMatchers(fieldMatchers);
655 ASSERT_EQ((size_t)5, dedupedFieldMatchers.size());
656 EXPECT_EQ(fieldMatchers[0], dedupedFieldMatchers[0]);
657 EXPECT_EQ(fieldMatchers[1], dedupedFieldMatchers[1]);
658 EXPECT_EQ(fieldMatchers[2], dedupedFieldMatchers[2]);
659 EXPECT_EQ(fieldMatchers[4], dedupedFieldMatchers[3]);
660 EXPECT_EQ(fieldMatchers[6], dedupedFieldMatchers[4]);
661 }
662
checkAttributionNodeInDimensionsValueParcel(StatsDimensionsValueParcel & attributionNodeParcel,int32_t nodeDepthInAttributionChain,int32_t uid,string tag)663 void checkAttributionNodeInDimensionsValueParcel(StatsDimensionsValueParcel& attributionNodeParcel,
664 int32_t nodeDepthInAttributionChain,
665 int32_t uid, string tag) {
666 EXPECT_EQ(attributionNodeParcel.field, nodeDepthInAttributionChain /*position at depth 1*/);
667 ASSERT_EQ(attributionNodeParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
668 ASSERT_EQ(attributionNodeParcel.tupleValue.size(), 2);
669
670 StatsDimensionsValueParcel uidParcel = attributionNodeParcel.tupleValue[0];
671 EXPECT_EQ(uidParcel.field, 1 /*position at depth 2*/);
672 EXPECT_EQ(uidParcel.valueType, STATS_DIMENSIONS_VALUE_INT_TYPE);
673 EXPECT_EQ(uidParcel.intValue, uid);
674
675 StatsDimensionsValueParcel tagParcel = attributionNodeParcel.tupleValue[1];
676 EXPECT_EQ(tagParcel.field, 2 /*position at depth 2*/);
677 EXPECT_EQ(tagParcel.valueType, STATS_DIMENSIONS_VALUE_STRING_TYPE);
678 EXPECT_EQ(tagParcel.stringValue, tag);
679 }
680
681 // Test conversion of a HashableDimensionKey into a StatsDimensionValueParcel
TEST(AtomMatcherTest,TestSubscriberDimensionWrite)682 TEST(AtomMatcherTest, TestSubscriberDimensionWrite) {
683 int atomId = 10;
684 // First four fields form an attribution chain
685 int pos1[] = {1, 1, 1};
686 int pos2[] = {1, 1, 2};
687 int pos3[] = {1, 2, 1};
688 int pos4[] = {1, 2, 2};
689 int pos5[] = {2, 1, 1};
690
691 Field field1(atomId, pos1, /*depth=*/2);
692 Field field2(atomId, pos2, /*depth=*/2);
693 Field field3(atomId, pos3, /*depth=*/2);
694 Field field4(atomId, pos4, /*depth=*/2);
695 Field field5(atomId, pos5, /*depth=*/0);
696
697 Value value1((int32_t)1);
698 Value value2("string2");
699 Value value3((int32_t)3);
700 Value value4("string4");
701 Value value5((float)5.0);
702
703 HashableDimensionKey dimensionKey;
704 dimensionKey.addValue(FieldValue(field1, value1));
705 dimensionKey.addValue(FieldValue(field2, value2));
706 dimensionKey.addValue(FieldValue(field3, value3));
707 dimensionKey.addValue(FieldValue(field4, value4));
708 dimensionKey.addValue(FieldValue(field5, value5));
709
710 StatsDimensionsValueParcel rootParcel = dimensionKey.toStatsDimensionsValueParcel();
711 EXPECT_EQ(rootParcel.field, atomId);
712 ASSERT_EQ(rootParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
713 ASSERT_EQ(rootParcel.tupleValue.size(), 2);
714
715 // Check that attribution chain is populated correctly
716 StatsDimensionsValueParcel attributionChainParcel = rootParcel.tupleValue[0];
717 EXPECT_EQ(attributionChainParcel.field, 1 /*position at depth 0*/);
718 ASSERT_EQ(attributionChainParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
719 ASSERT_EQ(attributionChainParcel.tupleValue.size(), 2);
720 checkAttributionNodeInDimensionsValueParcel(attributionChainParcel.tupleValue[0],
721 /*nodeDepthInAttributionChain=*/1,
722 value1.int_value, value2.str_value);
723 checkAttributionNodeInDimensionsValueParcel(attributionChainParcel.tupleValue[1],
724 /*nodeDepthInAttributionChain=*/2,
725 value3.int_value, value4.str_value);
726
727 // Check that the float is populated correctly
728 StatsDimensionsValueParcel floatParcel = rootParcel.tupleValue[1];
729 EXPECT_EQ(floatParcel.field, 2 /*position at depth 0*/);
730 EXPECT_EQ(floatParcel.valueType, STATS_DIMENSIONS_VALUE_FLOAT_TYPE);
731 EXPECT_EQ(floatParcel.floatValue, value5.float_value);
732 }
733
TEST(AtomMatcherTest,TestWriteDimensionToProto)734 TEST(AtomMatcherTest, TestWriteDimensionToProto) {
735 HashableDimensionKey dim;
736 int pos1[] = {1, 1, 1};
737 int pos2[] = {1, 1, 2};
738 int pos3[] = {1, 1, 3};
739 int pos4[] = {2, 0, 0};
740 Field field1(10, pos1, 2);
741 Field field2(10, pos2, 2);
742 Field field3(10, pos3, 2);
743 Field field4(10, pos4, 0);
744
745 Value value1((int32_t)10025);
746 Value value2("tag");
747 Value value3((int32_t)987654);
748 Value value4((int32_t)99999);
749
750 dim.addValue(FieldValue(field1, value1));
751 dim.addValue(FieldValue(field2, value2));
752 dim.addValue(FieldValue(field3, value3));
753 dim.addValue(FieldValue(field4, value4));
754
755 android::util::ProtoOutputStream protoOut;
756 set<int32_t> usedUids;
757 writeDimensionToProto(dim, /*uidfields*/ {}, nullptr /* include strings */, usedUids,
758 &protoOut);
759
760 vector<uint8_t> outData;
761 outData.resize(protoOut.size());
762 size_t pos = 0;
763 sp<ProtoReader> reader = protoOut.data();
764 while (reader->readBuffer() != NULL) {
765 size_t toRead = reader->currentToRead();
766 std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
767 pos += toRead;
768 reader->move(toRead);
769 }
770
771 DimensionsValue result;
772 ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
773 EXPECT_EQ(10, result.field());
774 EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
775 ASSERT_EQ(2, result.value_tuple().dimensions_value_size());
776
777 const auto& dim1 = result.value_tuple().dimensions_value(0);
778 EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, dim1.value_case());
779 ASSERT_EQ(3, dim1.value_tuple().dimensions_value_size());
780
781 const auto& dim11 = dim1.value_tuple().dimensions_value(0);
782 EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim11.value_case());
783 EXPECT_EQ(10025, dim11.value_int());
784
785 const auto& dim12 = dim1.value_tuple().dimensions_value(1);
786 EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim12.value_case());
787 EXPECT_EQ("tag", dim12.value_str());
788
789 const auto& dim13 = dim1.value_tuple().dimensions_value(2);
790 EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim13.value_case());
791 EXPECT_EQ(987654, dim13.value_int());
792
793 const auto& dim2 = result.value_tuple().dimensions_value(1);
794 EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim2.value_case());
795 EXPECT_EQ(99999, dim2.value_int());
796 }
797
TEST(AtomMatcherTest,TestWriteDimensionLeafNodesToProto)798 TEST(AtomMatcherTest, TestWriteDimensionLeafNodesToProto) {
799 HashableDimensionKey dim;
800 int pos1[] = {1, 1, 1};
801 int pos2[] = {1, 1, 2};
802 int pos3[] = {1, 1, 3};
803 int pos4[] = {2, 0, 0};
804 Field field1(10, pos1, 2);
805 Field field2(10, pos2, 2);
806 Field field3(10, pos3, 2);
807 Field field4(10, pos4, 0);
808
809 Value value1((int32_t)10025);
810 Value value2("tag");
811 Value value3((int32_t)987654);
812 Value value4((int64_t)99999);
813
814 dim.addValue(FieldValue(field1, value1));
815 dim.addValue(FieldValue(field2, value2));
816 dim.addValue(FieldValue(field3, value3));
817 dim.addValue(FieldValue(field4, value4));
818
819 android::util::ProtoOutputStream protoOut;
820 set<int32_t> usedUids;
821 writeDimensionLeafNodesToProto(dim, 1, /*uidfields*/ {}, nullptr /* include strings */,
822 usedUids, &protoOut);
823
824 vector<uint8_t> outData;
825 outData.resize(protoOut.size());
826 size_t pos = 0;
827 sp<ProtoReader> reader = protoOut.data();
828 while (reader->readBuffer() != NULL) {
829 size_t toRead = reader->currentToRead();
830 std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
831 pos += toRead;
832 reader->move(toRead);
833 }
834
835 DimensionsValueTuple result;
836 ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
837 ASSERT_EQ(4, result.dimensions_value_size());
838
839 const auto& dim1 = result.dimensions_value(0);
840 EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim1.value_case());
841 EXPECT_EQ(10025, dim1.value_int());
842
843 const auto& dim2 = result.dimensions_value(1);
844 EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim2.value_case());
845 EXPECT_EQ("tag", dim2.value_str());
846
847 const auto& dim3 = result.dimensions_value(2);
848 EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim3.value_case());
849 EXPECT_EQ(987654, dim3.value_int());
850
851 const auto& dim4 = result.dimensions_value(3);
852 EXPECT_EQ(DimensionsValue::ValueCase::kValueLong, dim4.value_case());
853 EXPECT_EQ(99999, dim4.value_long());
854 }
855
TEST(AtomMatcherTest,TestWriteAtomToProto)856 TEST(AtomMatcherTest, TestWriteAtomToProto) {
857 std::vector<int> attributionUids = {1111, 2222};
858 std::vector<string> attributionTags = {"location1", "location2"};
859
860 LogEvent event(/*uid=*/0, /*pid=*/0);
861 makeLogEvent(&event, 4 /*atomId*/, 12345, attributionUids, attributionTags, 999);
862
863 android::util::ProtoOutputStream protoOutput;
864 set<int32_t> usedUids;
865 writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), /*uidfields*/ {}, usedUids,
866 &protoOutput);
867
868 vector<uint8_t> outData;
869 outData.resize(protoOutput.size());
870 size_t pos = 0;
871 sp<ProtoReader> reader = protoOutput.data();
872 while (reader->readBuffer() != NULL) {
873 size_t toRead = reader->currentToRead();
874 std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
875 pos += toRead;
876 reader->move(toRead);
877 }
878
879 Atom result;
880 ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
881 EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case());
882 const auto& atom = result.ble_scan_result_received();
883 ASSERT_EQ(2, atom.attribution_node_size());
884 EXPECT_EQ(1111, atom.attribution_node(0).uid());
885 EXPECT_EQ("location1", atom.attribution_node(0).tag());
886 EXPECT_EQ(2222, atom.attribution_node(1).uid());
887 EXPECT_EQ("location2", atom.attribution_node(1).tag());
888 EXPECT_EQ(999, atom.num_results());
889 }
890
TEST_GUARDED(AtomMatcherTest,TestWriteAtomWithRepeatedFieldsToProto,__ANDROID_API_T__)891 TEST_GUARDED(AtomMatcherTest, TestWriteAtomWithRepeatedFieldsToProto, __ANDROID_API_T__) {
892 vector<int> intArray = {3, 6};
893 vector<int64_t> longArray = {1000L, 10002L};
894 vector<float> floatArray = {0.3f, 0.09f};
895 vector<string> stringArray = {"str1", "str2"};
896 int boolArrayLength = 2;
897 bool boolArray[boolArrayLength];
898 boolArray[0] = 1;
899 boolArray[1] = 0;
900 vector<uint8_t> boolArrayVector = {1, 0};
901 vector<int> enumArray = {TestAtomReported::ON, TestAtomReported::OFF};
902
903 unique_ptr<LogEvent> event = CreateTestAtomReportedEventVariableRepeatedFields(
904 12345, intArray, longArray, floatArray, stringArray, boolArray, boolArrayLength,
905 enumArray);
906
907 android::util::ProtoOutputStream protoOutput;
908 set<int32_t> usedUids;
909 writeFieldValueTreeToStream(event->GetTagId(), event->getValues(), /*uidfields*/ {}, usedUids,
910 &protoOutput);
911
912 vector<uint8_t> outData;
913 outData.resize(protoOutput.size());
914 size_t pos = 0;
915 sp<ProtoReader> reader = protoOutput.data();
916 while (reader->readBuffer() != NULL) {
917 size_t toRead = reader->currentToRead();
918 std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
919 pos += toRead;
920 reader->move(toRead);
921 }
922
923 Atom result;
924 ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
925 EXPECT_EQ(Atom::PushedCase::kTestAtomReported, result.pushed_case());
926 TestAtomReported atom = result.test_atom_reported();
927 EXPECT_THAT(atom.repeated_int_field(), ElementsAreArray(intArray));
928 EXPECT_THAT(atom.repeated_long_field(), ElementsAreArray(longArray));
929 EXPECT_THAT(atom.repeated_float_field(), ElementsAreArray(floatArray));
930 EXPECT_THAT(atom.repeated_string_field(), ElementsAreArray(stringArray));
931 EXPECT_THAT(atom.repeated_boolean_field(), ElementsAreArray(boolArrayVector));
932 EXPECT_THAT(atom.repeated_enum_field(), ElementsAreArray(enumArray));
933 }
934
935 /*
936 * Test two Matchers is not a subset of one Matcher.
937 * Test one Matcher is subset of two Matchers.
938 */
TEST(AtomMatcherTest,TestSubsetDimensions1)939 TEST(AtomMatcherTest, TestSubsetDimensions1) {
940 // Initialize first set of matchers
941 FieldMatcher matcher1;
942 matcher1.set_field(10);
943
944 FieldMatcher* child = matcher1.add_child();
945 child->set_field(1);
946 child->set_position(Position::ALL);
947 child->add_child()->set_field(1);
948 child->add_child()->set_field(2);
949
950 vector<Matcher> matchers1;
951 translateFieldMatcher(matcher1, &matchers1);
952 ASSERT_EQ(2, matchers1.size());
953
954 // Initialize second set of matchers
955 FieldMatcher matcher2;
956 matcher2.set_field(10);
957
958 child = matcher2.add_child();
959 child->set_field(1);
960 child->set_position(Position::ALL);
961 child->add_child()->set_field(1);
962
963 vector<Matcher> matchers2;
964 translateFieldMatcher(matcher2, &matchers2);
965 ASSERT_EQ(1, matchers2.size());
966
967 EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
968 EXPECT_TRUE(subsetDimensions(matchers2, matchers1));
969 }
970 /*
971 * Test not a subset with one matching Matcher, one non-matching Matcher.
972 */
TEST(AtomMatcherTest,TestSubsetDimensions2)973 TEST(AtomMatcherTest, TestSubsetDimensions2) {
974 // Initialize first set of matchers
975 FieldMatcher matcher1;
976 matcher1.set_field(10);
977
978 FieldMatcher* child = matcher1.add_child();
979 child->set_field(1);
980
981 child = matcher1.add_child();
982 child->set_field(2);
983
984 vector<Matcher> matchers1;
985 translateFieldMatcher(matcher1, &matchers1);
986
987 // Initialize second set of matchers
988 FieldMatcher matcher2;
989 matcher2.set_field(10);
990
991 child = matcher2.add_child();
992 child->set_field(1);
993
994 child = matcher2.add_child();
995 child->set_field(3);
996
997 vector<Matcher> matchers2;
998 translateFieldMatcher(matcher2, &matchers2);
999
1000 EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
1001 }
1002
1003 /*
1004 * Test not a subset if parent field is not equal.
1005 */
TEST(AtomMatcherTest,TestSubsetDimensions3)1006 TEST(AtomMatcherTest, TestSubsetDimensions3) {
1007 // Initialize first set of matchers
1008 FieldMatcher matcher1;
1009 matcher1.set_field(10);
1010
1011 FieldMatcher* child = matcher1.add_child();
1012 child->set_field(1);
1013
1014 vector<Matcher> matchers1;
1015 translateFieldMatcher(matcher1, &matchers1);
1016
1017 // Initialize second set of matchers
1018 FieldMatcher matcher2;
1019 matcher2.set_field(5);
1020
1021 child = matcher2.add_child();
1022 child->set_field(1);
1023
1024 vector<Matcher> matchers2;
1025 translateFieldMatcher(matcher2, &matchers2);
1026
1027 EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
1028 }
1029
1030 /*
1031 * Test is subset with two matching Matchers.
1032 */
TEST(AtomMatcherTest,TestSubsetDimensions4)1033 TEST(AtomMatcherTest, TestSubsetDimensions4) {
1034 // Initialize first set of matchers
1035 FieldMatcher matcher1;
1036 matcher1.set_field(10);
1037
1038 FieldMatcher* child = matcher1.add_child();
1039 child->set_field(1);
1040
1041 child = matcher1.add_child();
1042 child->set_field(2);
1043
1044 vector<Matcher> matchers1;
1045 translateFieldMatcher(matcher1, &matchers1);
1046
1047 // Initialize second set of matchers
1048 FieldMatcher matcher2;
1049 matcher2.set_field(10);
1050
1051 child = matcher2.add_child();
1052 child->set_field(1);
1053
1054 child = matcher2.add_child();
1055 child->set_field(2);
1056
1057 child = matcher2.add_child();
1058 child->set_field(3);
1059
1060 vector<Matcher> matchers2;
1061 translateFieldMatcher(matcher2, &matchers2);
1062
1063 EXPECT_TRUE(subsetDimensions(matchers1, matchers2));
1064 EXPECT_FALSE(subsetDimensions(matchers2, matchers1));
1065 }
1066
1067 /*
1068 * Test multiple combinations of repeated field matchers with different positions.
1069 */
TEST(AtomMatcherTest,TestSubsetDimensions_RepeatedFields)1070 TEST(AtomMatcherTest, TestSubsetDimensions_RepeatedFields) {
1071 // Initialize matchers with position ALL.
1072 FieldMatcher matcherAll;
1073 matcherAll.set_field(10);
1074 FieldMatcher* child = matcherAll.add_child();
1075 child->set_field(1);
1076 child = matcherAll.add_child();
1077 child->set_field(2);
1078 child->set_position(Position::ALL);
1079 FieldMatcher* attributionNodeChild = child->add_child();
1080 attributionNodeChild->set_field(1);
1081
1082 vector<Matcher> matchersAll;
1083 translateFieldMatcher(matcherAll, &matchersAll);
1084
1085 // Initialize matchers with position FIRST.
1086 FieldMatcher matcherFirst;
1087 matcherFirst.set_field(10);
1088 child = matcherFirst.add_child();
1089 child->set_field(1);
1090 child = matcherFirst.add_child();
1091 child->set_field(2);
1092 child->set_position(Position::FIRST);
1093 attributionNodeChild = child->add_child();
1094 attributionNodeChild->set_field(1);
1095
1096 vector<Matcher> matchersFirst;
1097 translateFieldMatcher(matcherFirst, &matchersFirst);
1098
1099 // Initialize matchers with position LAST.
1100 FieldMatcher matcherLast;
1101 matcherLast.set_field(10);
1102 child = matcherLast.add_child();
1103 child->set_field(1);
1104 child = matcherLast.add_child();
1105 child->set_field(2);
1106 child->set_position(Position::LAST);
1107 attributionNodeChild = child->add_child();
1108 attributionNodeChild->set_field(1);
1109
1110 vector<Matcher> matchersLast;
1111 translateFieldMatcher(matcherLast, &matchersLast);
1112
1113 // Initialize matchers with position ANY.
1114 FieldMatcher matcherAny;
1115 matcherAny.set_field(10);
1116 child = matcherAny.add_child();
1117 child->set_field(1);
1118 child = matcherAny.add_child();
1119 child->set_field(2);
1120 child->set_position(Position::ANY);
1121 attributionNodeChild = child->add_child();
1122 attributionNodeChild->set_field(1);
1123
1124 vector<Matcher> matchersAny;
1125 translateFieldMatcher(matcherAny, &matchersAny);
1126
1127 // Initialize matchers with position ALL, different field number.
1128 FieldMatcher matcherAllDifferent;
1129 matcherAllDifferent.set_field(10);
1130 child = matcherAllDifferent.add_child();
1131 child->set_field(1);
1132 child = matcherAllDifferent.add_child();
1133 child->set_field(2);
1134 child->set_position(Position::ALL);
1135 attributionNodeChild = child->add_child();
1136 attributionNodeChild->set_field(2);
1137
1138 vector<Matcher> matchersAllDifferent;
1139 translateFieldMatcher(matcherAllDifferent, &matchersAllDifferent);
1140
1141 // Positions ALL, FIRST, LAST are subsets of position ALL.
1142 EXPECT_TRUE(subsetDimensions(matchersAll, matchersAll));
1143 EXPECT_TRUE(subsetDimensions(matchersFirst, matchersAll));
1144 EXPECT_TRUE(subsetDimensions(matchersLast, matchersAll));
1145 EXPECT_FALSE(subsetDimensions(matchersAny, matchersAll));
1146 EXPECT_FALSE(subsetDimensions(matchersAllDifferent, matchersAll));
1147
1148 // Position FIRST is a subset of position FIRST.
1149 EXPECT_FALSE(subsetDimensions(matchersAll, matchersFirst));
1150 EXPECT_TRUE(subsetDimensions(matchersFirst, matchersFirst));
1151 EXPECT_FALSE(subsetDimensions(matchersLast, matchersFirst));
1152 EXPECT_FALSE(subsetDimensions(matchersAny, matchersFirst));
1153 EXPECT_FALSE(subsetDimensions(matchersAllDifferent, matchersFirst));
1154
1155 // Position LAST is a subset of position LAST.
1156 EXPECT_FALSE(subsetDimensions(matchersAll, matchersLast));
1157 EXPECT_FALSE(subsetDimensions(matchersFirst, matchersLast));
1158 EXPECT_TRUE(subsetDimensions(matchersLast, matchersLast));
1159 EXPECT_FALSE(subsetDimensions(matchersAny, matchersLast));
1160 EXPECT_FALSE(subsetDimensions(matchersAllDifferent, matchersLast));
1161
1162 // Position ANY is a subset of position ANY.
1163 EXPECT_FALSE(subsetDimensions(matchersAll, matchersAny));
1164 EXPECT_FALSE(subsetDimensions(matchersFirst, matchersAny));
1165 EXPECT_FALSE(subsetDimensions(matchersLast, matchersAny));
1166 EXPECT_TRUE(subsetDimensions(matchersAny, matchersAny));
1167 EXPECT_FALSE(subsetDimensions(matchersAllDifferent, matchersAny));
1168 }
1169
TEST(AtomMatcherTest,TestAllPositionMatcher)1170 TEST(AtomMatcherTest, TestAllPositionMatcher) {
1171 // Initialize matcher with position ALL.
1172 FieldMatcher matcherAll;
1173 matcherAll.set_field(10);
1174 FieldMatcher* child = matcherAll.add_child();
1175 child->set_field(2);
1176 child->set_position(Position::ALL);
1177 FieldMatcher* attributionNodeChild = child->add_child();
1178 attributionNodeChild->set_field(1);
1179
1180 vector<Matcher> matchersAll;
1181 translateFieldMatcher(matcherAll, &matchersAll);
1182
1183 // Initialize matcher with position ANY.
1184 FieldMatcher matcherAny;
1185 matcherAny.set_field(10);
1186 child = matcherAny.add_child();
1187 child->set_field(2);
1188 child->set_position(Position::ANY);
1189 attributionNodeChild = child->add_child();
1190 attributionNodeChild->set_field(1);
1191
1192 vector<Matcher> matchersAny;
1193 translateFieldMatcher(matcherAny, &matchersAny);
1194
1195 EXPECT_TRUE(matchersAll[0].hasAllPositionMatcher());
1196 EXPECT_FALSE(matchersAny[0].hasAllPositionMatcher());
1197 }
1198
TEST(AtomMatcherTest,TestIsPrimitiveRepeatedField)1199 TEST(AtomMatcherTest, TestIsPrimitiveRepeatedField) {
1200 int pos1[] = {1, 1, 1}; // attribution uid
1201 int pos2[] = {1, 1, 2}; // attribution tag
1202 int pos3[] = {1, 2, 1}; // attribution uid - second node
1203 int pos4[] = {1, 2, 2}; // attribution tag - second node
1204 int pos5[] = {2, 1, 1}; // repeated field first element
1205 int pos6[] = {2, 2, 1}; // repeated field second element
1206 int pos7[] = {3, 1, 1}; // top-level field
1207 Field field1(10, pos1, 2);
1208 Field field2(10, pos2, 2);
1209 Field field3(10, pos3, 2);
1210 Field field4(10, pos4, 2);
1211 Field field5(10, pos5, 1);
1212 Field field6(10, pos6, 1);
1213 Field field7(10, pos7, 0);
1214
1215 EXPECT_FALSE(isPrimitiveRepeatedField(field1));
1216 EXPECT_FALSE(isPrimitiveRepeatedField(field2));
1217 EXPECT_FALSE(isPrimitiveRepeatedField(field3));
1218 EXPECT_FALSE(isPrimitiveRepeatedField(field4));
1219 EXPECT_TRUE(isPrimitiveRepeatedField(field5));
1220 EXPECT_TRUE(isPrimitiveRepeatedField(field6));
1221 EXPECT_FALSE(isPrimitiveRepeatedField(field7));
1222 }
1223
TEST(FieldValueTest,TestShouldKeepSampleInt)1224 TEST(FieldValueTest, TestShouldKeepSampleInt) {
1225 int shardOffset = 5;
1226 int shardCount = 2;
1227 int pos1[] = {1, 1, 1};
1228
1229 Field field(1, pos1, 2);
1230
1231 Value value1((int32_t)1001);
1232 Value value2((int32_t)1002);
1233
1234 FieldValue fieldValue1(field, value1);
1235 FieldValue fieldValue2(field, value2);
1236
1237 EXPECT_TRUE(shouldKeepSample(fieldValue1, shardOffset, shardCount));
1238 EXPECT_FALSE(shouldKeepSample(fieldValue2, shardOffset, shardCount));
1239 }
1240
TEST(FieldValueTest,TestShouldKeepSampleLong)1241 TEST(FieldValueTest, TestShouldKeepSampleLong) {
1242 int shardOffset = 5;
1243 int shardCount = 2;
1244 int pos1[] = {1, 1, 1};
1245
1246 Field field(1, pos1, 2);
1247
1248 Value value1((int64_t)1001L);
1249 Value value2((int64_t)1005L);
1250
1251 FieldValue fieldValue1(field, value1);
1252 FieldValue fieldValue2(field, value2);
1253
1254 EXPECT_FALSE(shouldKeepSample(fieldValue1, shardOffset, shardCount));
1255 EXPECT_TRUE(shouldKeepSample(fieldValue2, shardOffset, shardCount));
1256 }
1257
TEST(FieldValueTest,TestShouldKeepSampleFloat)1258 TEST(FieldValueTest, TestShouldKeepSampleFloat) {
1259 int shardOffset = 5;
1260 int shardCount = 2;
1261 int pos1[] = {1, 1, 1};
1262
1263 Field field(1, pos1, 2);
1264
1265 Value value1((float)10.5);
1266 Value value2((float)3.9);
1267
1268 FieldValue fieldValue1(field, value1);
1269 FieldValue fieldValue2(field, value2);
1270
1271 EXPECT_TRUE(shouldKeepSample(fieldValue1, shardOffset, shardCount));
1272 EXPECT_FALSE(shouldKeepSample(fieldValue2, shardOffset, shardCount));
1273 }
1274
TEST(FieldValueTest,TestShouldKeepSampleDouble)1275 TEST(FieldValueTest, TestShouldKeepSampleDouble) {
1276 int shardOffset = 5;
1277 int shardCount = 2;
1278 int pos1[] = {1, 1, 1};
1279
1280 Field field(1, pos1, 2);
1281
1282 Value value1((double)1.5);
1283 Value value2((double)3.9);
1284
1285 FieldValue fieldValue1(field, value1);
1286 FieldValue fieldValue2(field, value2);
1287
1288 EXPECT_TRUE(shouldKeepSample(fieldValue1, shardOffset, shardCount));
1289 EXPECT_FALSE(shouldKeepSample(fieldValue2, shardOffset, shardCount));
1290 }
1291
TEST(FieldValueTest,TestShouldKeepSampleString)1292 TEST(FieldValueTest, TestShouldKeepSampleString) {
1293 int shardOffset = 5;
1294 int shardCount = 2;
1295 int pos1[] = {1, 1, 1};
1296
1297 Field field(1, pos1, 2);
1298
1299 Value value1("str1");
1300 Value value2("str2");
1301
1302 FieldValue fieldValue1(field, value1);
1303 FieldValue fieldValue2(field, value2);
1304
1305 EXPECT_FALSE(shouldKeepSample(fieldValue1, shardOffset, shardCount));
1306 EXPECT_TRUE(shouldKeepSample(fieldValue2, shardOffset, shardCount));
1307 }
1308
TEST(FieldValueTest,TestShouldKeepSampleByteArray)1309 TEST(FieldValueTest, TestShouldKeepSampleByteArray) {
1310 int shardOffset = 5;
1311 int shardCount = 2;
1312 int pos1[] = {1, 1, 1};
1313
1314 Field field(1, pos1, 2);
1315
1316 vector<uint8_t> message1 = {'\t', 'e', '\0', 's', 't'};
1317 vector<uint8_t> message2 = {'\t', 'e', '\0', 's', 't', 't'};
1318
1319 Value value1(message1);
1320 Value value2(message2);
1321
1322 FieldValue fieldValue1(field, value1);
1323 FieldValue fieldValue2(field, value2);
1324
1325 EXPECT_FALSE(shouldKeepSample(fieldValue1, shardOffset, shardCount));
1326 EXPECT_TRUE(shouldKeepSample(fieldValue2, shardOffset, shardCount));
1327 }
1328
1329 } // namespace statsd
1330 } // namespace os
1331 } // namespace android
1332 #else
1333 GTEST_LOG_(INFO) << "This test does nothing.\n";
1334 #endif
1335