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