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 void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
38                   const vector<int>& attributionUids, const vector<string>& attributionTags,
39                   const string& name) {
40     AStatsEvent* statsEvent = AStatsEvent_obtain();
41     AStatsEvent_setAtomId(statsEvent, atomId);
42     AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
43 
44     writeAttribution(statsEvent, attributionUids, attributionTags);
45     AStatsEvent_writeString(statsEvent, name.c_str());
46 
47     parseStatsEventToLogEvent(statsEvent, logEvent);
48 }
49 
50 void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
51                   const vector<int>& attributionUids, const vector<string>& attributionTags,
52                   const int32_t value) {
53     AStatsEvent* statsEvent = AStatsEvent_obtain();
54     AStatsEvent_setAtomId(statsEvent, atomId);
55     AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
56 
57     writeAttribution(statsEvent, attributionUids, attributionTags);
58     AStatsEvent_writeInt32(statsEvent, value);
59 
60     parseStatsEventToLogEvent(statsEvent, logEvent);
61 }
62 }  // anonymous namespace
63 
64 TEST(AtomMatcherTest, TestFieldTranslation) {
65     FieldMatcher matcher1;
66     matcher1.set_field(10);
67     FieldMatcher* child = matcher1.add_child();
68     child->set_field(1);
69     child->set_position(Position::ANY);
70 
71     child = child->add_child();
72     child->set_field(1);
73 
74     vector<Matcher> output;
75     translateFieldMatcher(matcher1, &output);
76 
77     ASSERT_EQ((size_t)1, output.size());
78 
79     const auto& matcher12 = output[0];
80     EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
81     EXPECT_EQ((int32_t)0x02010001, matcher12.mMatcher.getField());
82     EXPECT_EQ((int32_t)0xff7f007f, matcher12.mMask);
83 }
84 
85 TEST(AtomMatcherTest, TestFieldTranslation_ALL) {
86     FieldMatcher matcher1;
87     matcher1.set_field(10);
88     FieldMatcher* child = matcher1.add_child();
89     child->set_field(1);
90     child->set_position(Position::ALL);
91 
92     child = child->add_child();
93     child->set_field(1);
94 
95     vector<Matcher> output;
96     translateFieldMatcher(matcher1, &output);
97 
98     ASSERT_EQ((size_t)1, output.size());
99 
100     const auto& matcher12 = output[0];
101     EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
102     EXPECT_EQ((int32_t)0x02010001, matcher12.mMatcher.getField());
103     EXPECT_EQ((int32_t)0xff7f7f7f, matcher12.mMask);
104 }
105 
106 TEST(AtomMatcherTest, TestFilter_ALL) {
107     FieldMatcher matcher1;
108     matcher1.set_field(10);
109     FieldMatcher* child = matcher1.add_child();
110     child->set_field(1);
111     child->set_position(Position::ALL);
112 
113     child->add_child()->set_field(1);
114     child->add_child()->set_field(2);
115 
116     child = matcher1.add_child();
117     child->set_field(2);
118 
119     vector<Matcher> matchers;
120     translateFieldMatcher(matcher1, &matchers);
121 
122     std::vector<int> attributionUids = {1111, 2222, 3333};
123     std::vector<string> attributionTags = {"location1", "location2", "location3"};
124 
125     LogEvent event(/*uid=*/0, /*pid=*/0);
126     makeLogEvent(&event, 10 /*atomId*/, 1012345, attributionUids, attributionTags, "some value");
127     HashableDimensionKey output;
128 
129     filterValues(matchers, event.getValues(), &output);
130 
131     ASSERT_EQ((size_t)7, output.getValues().size());
132     EXPECT_EQ((int32_t)0x02010101, output.getValues()[0].mField.getField());
133     EXPECT_EQ((int32_t)1111, output.getValues()[0].mValue.int_value);
134     EXPECT_EQ((int32_t)0x02010102, output.getValues()[1].mField.getField());
135     EXPECT_EQ("location1", output.getValues()[1].mValue.str_value);
136 
137     EXPECT_EQ((int32_t)0x02010201, output.getValues()[2].mField.getField());
138     EXPECT_EQ((int32_t)2222, output.getValues()[2].mValue.int_value);
139     EXPECT_EQ((int32_t)0x02010202, output.getValues()[3].mField.getField());
140     EXPECT_EQ("location2", output.getValues()[3].mValue.str_value);
141 
142     EXPECT_EQ((int32_t)0x02010301, output.getValues()[4].mField.getField());
143     EXPECT_EQ((int32_t)3333, output.getValues()[4].mValue.int_value);
144     EXPECT_EQ((int32_t)0x02010302, output.getValues()[5].mField.getField());
145     EXPECT_EQ("location3", output.getValues()[5].mValue.str_value);
146 
147     EXPECT_EQ((int32_t)0x00020000, output.getValues()[6].mField.getField());
148     EXPECT_EQ("some value", output.getValues()[6].mValue.str_value);
149 }
150 
151 TEST(AtomMatcherTest, TestSubDimension) {
152     HashableDimensionKey dim;
153 
154     int pos1[] = {1, 1, 1};
155     int pos2[] = {1, 1, 2};
156     int pos3[] = {1, 1, 3};
157     int pos4[] = {2, 0, 0};
158     Field field1(10, pos1, 2);
159     Field field2(10, pos2, 2);
160 
161     Field field3(10, pos3, 2);
162     Field field4(10, pos4, 0);
163 
164     Value value1((int32_t)10025);
165     Value value2("tag");
166 
167     Value value11((int32_t)10026);
168     Value value22("tag2");
169 
170     dim.addValue(FieldValue(field1, value1));
171     dim.addValue(FieldValue(field2, value2));
172 
173     HashableDimensionKey subDim1;
174     subDim1.addValue(FieldValue(field1, value1));
175 
176     HashableDimensionKey subDim2;
177     subDim1.addValue(FieldValue(field2, value2));
178 
179     EXPECT_TRUE(dim.contains(dim));
180     EXPECT_TRUE(dim.contains(subDim1));
181     EXPECT_TRUE(dim.contains(subDim2));
182 
183     HashableDimensionKey subDim3;
184     subDim3.addValue(FieldValue(field1, value11));
185     EXPECT_FALSE(dim.contains(subDim3));
186 
187     HashableDimensionKey subDim4;
188     // Empty dimension is always a sub dimension of other dimensions
189     EXPECT_TRUE(dim.contains(subDim4));
190 }
191 
192 TEST(AtomMatcherTest, TestMetric2ConditionLink) {
193     std::vector<int> attributionUids = {1111, 2222, 3333};
194     std::vector<string> attributionTags = {"location1", "location2", "location3"};
195 
196     LogEvent event(/*uid=*/0, /*pid=*/0);
197     makeLogEvent(&event, 10 /*atomId*/, 12345, attributionUids, attributionTags, "some value");
198 
199     FieldMatcher whatMatcher;
200     whatMatcher.set_field(10);
201     FieldMatcher* child11 = whatMatcher.add_child();
202     child11->set_field(1);
203     child11->set_position(Position::ANY);
204     child11 = child11->add_child();
205     child11->set_field(1);
206 
207     FieldMatcher conditionMatcher;
208     conditionMatcher.set_field(27);
209     FieldMatcher* child2 = conditionMatcher.add_child();
210     child2->set_field(2);
211     child2->set_position(Position::LAST);
212 
213     child2 = child2->add_child();
214     child2->set_field(2);
215 
216     Metric2Condition link;
217 
218     translateFieldMatcher(whatMatcher, &link.metricFields);
219     translateFieldMatcher(conditionMatcher, &link.conditionFields);
220 
221     ASSERT_EQ((size_t)1, link.metricFields.size());
222     EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField());
223     EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask);
224     EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag());
225 
226     ASSERT_EQ((size_t)1, link.conditionFields.size());
227     EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField());
228     EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask);
229     EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag());
230 }
231 
232 TEST(AtomMatcherTest, TestWriteDimensionPath) {
233     for (auto position : {Position::ANY, Position::ALL, Position::FIRST, Position::LAST}) {
234         FieldMatcher matcher1;
235         matcher1.set_field(10);
236         FieldMatcher* child = matcher1.add_child();
237         child->set_field(2);
238         child->set_position(position);
239         child->add_child()->set_field(1);
240         child->add_child()->set_field(3);
241 
242         child = matcher1.add_child();
243         child->set_field(4);
244 
245         child = matcher1.add_child();
246         child->set_field(6);
247         child->add_child()->set_field(2);
248 
249         vector<Matcher> matchers;
250         translateFieldMatcher(matcher1, &matchers);
251 
252         android::util::ProtoOutputStream protoOut;
253         writeDimensionPathToProto(matchers, &protoOut);
254 
255         vector<uint8_t> outData;
256         outData.resize(protoOut.size());
257         size_t pos = 0;
258         sp<ProtoReader> reader = protoOut.data();
259         while (reader->readBuffer() != NULL) {
260             size_t toRead = reader->currentToRead();
261             std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
262             pos += toRead;
263             reader->move(toRead);
264         }
265 
266         DimensionsValue result;
267         ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
268 
269         EXPECT_EQ(10, result.field());
270         EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
271         ASSERT_EQ(3, result.value_tuple().dimensions_value_size());
272 
273         const auto& dim1 = result.value_tuple().dimensions_value(0);
274         EXPECT_EQ(2, dim1.field());
275         ASSERT_EQ(2, dim1.value_tuple().dimensions_value_size());
276 
277         const auto& dim11 = dim1.value_tuple().dimensions_value(0);
278         EXPECT_EQ(1, dim11.field());
279 
280         const auto& dim12 = dim1.value_tuple().dimensions_value(1);
281         EXPECT_EQ(3, dim12.field());
282 
283         const auto& dim2 = result.value_tuple().dimensions_value(1);
284         EXPECT_EQ(4, dim2.field());
285 
286         const auto& dim3 = result.value_tuple().dimensions_value(2);
287         EXPECT_EQ(6, dim3.field());
288         ASSERT_EQ(1, dim3.value_tuple().dimensions_value_size());
289         const auto& dim31 = dim3.value_tuple().dimensions_value(0);
290         EXPECT_EQ(2, dim31.field());
291     }
292 }
293 
294 void checkAttributionNodeInDimensionsValueParcel(StatsDimensionsValueParcel& attributionNodeParcel,
295                                                  int32_t nodeDepthInAttributionChain,
296                                                  int32_t uid, string tag) {
297     EXPECT_EQ(attributionNodeParcel.field, nodeDepthInAttributionChain /*position at depth 1*/);
298     ASSERT_EQ(attributionNodeParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
299     ASSERT_EQ(attributionNodeParcel.tupleValue.size(), 2);
300 
301     StatsDimensionsValueParcel uidParcel = attributionNodeParcel.tupleValue[0];
302     EXPECT_EQ(uidParcel.field, 1 /*position at depth 2*/);
303     EXPECT_EQ(uidParcel.valueType, STATS_DIMENSIONS_VALUE_INT_TYPE);
304     EXPECT_EQ(uidParcel.intValue, uid);
305 
306     StatsDimensionsValueParcel tagParcel = attributionNodeParcel.tupleValue[1];
307     EXPECT_EQ(tagParcel.field, 2 /*position at depth 2*/);
308     EXPECT_EQ(tagParcel.valueType, STATS_DIMENSIONS_VALUE_STRING_TYPE);
309     EXPECT_EQ(tagParcel.stringValue, tag);
310 }
311 
312 // Test conversion of a HashableDimensionKey into a StatsDimensionValueParcel
313 TEST(AtomMatcherTest, TestSubscriberDimensionWrite) {
314     int atomId = 10;
315     // First four fields form an attribution chain
316     int pos1[] = {1, 1, 1};
317     int pos2[] = {1, 1, 2};
318     int pos3[] = {1, 2, 1};
319     int pos4[] = {1, 2, 2};
320     int pos5[] = {2, 1, 1};
321 
322     Field field1(atomId, pos1, /*depth=*/2);
323     Field field2(atomId, pos2, /*depth=*/2);
324     Field field3(atomId, pos3, /*depth=*/2);
325     Field field4(atomId, pos4, /*depth=*/2);
326     Field field5(atomId, pos5, /*depth=*/0);
327 
328     Value value1((int32_t)1);
329     Value value2("string2");
330     Value value3((int32_t)3);
331     Value value4("string4");
332     Value value5((float)5.0);
333 
334     HashableDimensionKey dimensionKey;
335     dimensionKey.addValue(FieldValue(field1, value1));
336     dimensionKey.addValue(FieldValue(field2, value2));
337     dimensionKey.addValue(FieldValue(field3, value3));
338     dimensionKey.addValue(FieldValue(field4, value4));
339     dimensionKey.addValue(FieldValue(field5, value5));
340 
341     StatsDimensionsValueParcel rootParcel = dimensionKey.toStatsDimensionsValueParcel();
342     EXPECT_EQ(rootParcel.field, atomId);
343     ASSERT_EQ(rootParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
344     ASSERT_EQ(rootParcel.tupleValue.size(), 2);
345 
346     // Check that attribution chain is populated correctly
347     StatsDimensionsValueParcel attributionChainParcel = rootParcel.tupleValue[0];
348     EXPECT_EQ(attributionChainParcel.field, 1 /*position at depth 0*/);
349     ASSERT_EQ(attributionChainParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
350     ASSERT_EQ(attributionChainParcel.tupleValue.size(), 2);
351     checkAttributionNodeInDimensionsValueParcel(attributionChainParcel.tupleValue[0],
352                                                 /*nodeDepthInAttributionChain=*/1,
353                                                 value1.int_value, value2.str_value);
354     checkAttributionNodeInDimensionsValueParcel(attributionChainParcel.tupleValue[1],
355                                                 /*nodeDepthInAttributionChain=*/2,
356                                                 value3.int_value, value4.str_value);
357 
358     // Check that the float is populated correctly
359     StatsDimensionsValueParcel floatParcel = rootParcel.tupleValue[1];
360     EXPECT_EQ(floatParcel.field, 2 /*position at depth 0*/);
361     EXPECT_EQ(floatParcel.valueType, STATS_DIMENSIONS_VALUE_FLOAT_TYPE);
362     EXPECT_EQ(floatParcel.floatValue, value5.float_value);
363 }
364 
365 TEST(AtomMatcherTest, TestWriteDimensionToProto) {
366     HashableDimensionKey dim;
367     int pos1[] = {1, 1, 1};
368     int pos2[] = {1, 1, 2};
369     int pos3[] = {1, 1, 3};
370     int pos4[] = {2, 0, 0};
371     Field field1(10, pos1, 2);
372     Field field2(10, pos2, 2);
373     Field field3(10, pos3, 2);
374     Field field4(10, pos4, 0);
375 
376     Value value1((int32_t)10025);
377     Value value2("tag");
378     Value value3((int32_t)987654);
379     Value value4((int32_t)99999);
380 
381     dim.addValue(FieldValue(field1, value1));
382     dim.addValue(FieldValue(field2, value2));
383     dim.addValue(FieldValue(field3, value3));
384     dim.addValue(FieldValue(field4, value4));
385 
386     android::util::ProtoOutputStream protoOut;
387     writeDimensionToProto(dim, nullptr /* include strings */, &protoOut);
388 
389     vector<uint8_t> outData;
390     outData.resize(protoOut.size());
391     size_t pos = 0;
392     sp<ProtoReader> reader = protoOut.data();
393     while (reader->readBuffer() != NULL) {
394         size_t toRead = reader->currentToRead();
395         std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
396         pos += toRead;
397         reader->move(toRead);
398     }
399 
400     DimensionsValue result;
401     ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
402     EXPECT_EQ(10, result.field());
403     EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
404     ASSERT_EQ(2, result.value_tuple().dimensions_value_size());
405 
406     const auto& dim1 = result.value_tuple().dimensions_value(0);
407     EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, dim1.value_case());
408     ASSERT_EQ(3, dim1.value_tuple().dimensions_value_size());
409 
410     const auto& dim11 = dim1.value_tuple().dimensions_value(0);
411     EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim11.value_case());
412     EXPECT_EQ(10025, dim11.value_int());
413 
414     const auto& dim12 = dim1.value_tuple().dimensions_value(1);
415     EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim12.value_case());
416     EXPECT_EQ("tag", dim12.value_str());
417 
418     const auto& dim13 = dim1.value_tuple().dimensions_value(2);
419     EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim13.value_case());
420     EXPECT_EQ(987654, dim13.value_int());
421 
422     const auto& dim2 = result.value_tuple().dimensions_value(1);
423     EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim2.value_case());
424     EXPECT_EQ(99999, dim2.value_int());
425 }
426 
427 TEST(AtomMatcherTest, TestWriteDimensionLeafNodesToProto) {
428     HashableDimensionKey dim;
429     int pos1[] = {1, 1, 1};
430     int pos2[] = {1, 1, 2};
431     int pos3[] = {1, 1, 3};
432     int pos4[] = {2, 0, 0};
433     Field field1(10, pos1, 2);
434     Field field2(10, pos2, 2);
435     Field field3(10, pos3, 2);
436     Field field4(10, pos4, 0);
437 
438     Value value1((int32_t)10025);
439     Value value2("tag");
440     Value value3((int32_t)987654);
441     Value value4((int64_t)99999);
442 
443     dim.addValue(FieldValue(field1, value1));
444     dim.addValue(FieldValue(field2, value2));
445     dim.addValue(FieldValue(field3, value3));
446     dim.addValue(FieldValue(field4, value4));
447 
448     android::util::ProtoOutputStream protoOut;
449     writeDimensionLeafNodesToProto(dim, 1, nullptr /* include strings */, &protoOut);
450 
451     vector<uint8_t> outData;
452     outData.resize(protoOut.size());
453     size_t pos = 0;
454     sp<ProtoReader> reader = protoOut.data();
455     while (reader->readBuffer() != NULL) {
456         size_t toRead = reader->currentToRead();
457         std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
458         pos += toRead;
459         reader->move(toRead);
460     }
461 
462     DimensionsValueTuple result;
463     ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
464     ASSERT_EQ(4, result.dimensions_value_size());
465 
466     const auto& dim1 = result.dimensions_value(0);
467     EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim1.value_case());
468     EXPECT_EQ(10025, dim1.value_int());
469 
470     const auto& dim2 = result.dimensions_value(1);
471     EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim2.value_case());
472     EXPECT_EQ("tag", dim2.value_str());
473 
474     const auto& dim3 = result.dimensions_value(2);
475     EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim3.value_case());
476     EXPECT_EQ(987654, dim3.value_int());
477 
478     const auto& dim4 = result.dimensions_value(3);
479     EXPECT_EQ(DimensionsValue::ValueCase::kValueLong, dim4.value_case());
480     EXPECT_EQ(99999, dim4.value_long());
481 }
482 
483 TEST(AtomMatcherTest, TestWriteAtomToProto) {
484     std::vector<int> attributionUids = {1111, 2222};
485     std::vector<string> attributionTags = {"location1", "location2"};
486 
487     LogEvent event(/*uid=*/0, /*pid=*/0);
488     makeLogEvent(&event, 4 /*atomId*/, 12345, attributionUids, attributionTags, 999);
489 
490     android::util::ProtoOutputStream protoOutput;
491     writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput);
492 
493     vector<uint8_t> outData;
494     outData.resize(protoOutput.size());
495     size_t pos = 0;
496     sp<ProtoReader> reader = protoOutput.data();
497     while (reader->readBuffer() != NULL) {
498         size_t toRead = reader->currentToRead();
499         std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
500         pos += toRead;
501         reader->move(toRead);
502     }
503 
504     Atom result;
505     ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
506     EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case());
507     const auto& atom = result.ble_scan_result_received();
508     ASSERT_EQ(2, atom.attribution_node_size());
509     EXPECT_EQ(1111, atom.attribution_node(0).uid());
510     EXPECT_EQ("location1", atom.attribution_node(0).tag());
511     EXPECT_EQ(2222, atom.attribution_node(1).uid());
512     EXPECT_EQ("location2", atom.attribution_node(1).tag());
513     EXPECT_EQ(999, atom.num_results());
514 }
515 
516 /*
517  * Test two Matchers is not a subset of one Matcher.
518  * Test one Matcher is subset of two Matchers.
519  */
520 TEST(AtomMatcherTest, TestSubsetDimensions1) {
521     // Initialize first set of matchers
522     FieldMatcher matcher1;
523     matcher1.set_field(10);
524 
525     FieldMatcher* child = matcher1.add_child();
526     child->set_field(1);
527     child->set_position(Position::ALL);
528     child->add_child()->set_field(1);
529     child->add_child()->set_field(2);
530 
531     vector<Matcher> matchers1;
532     translateFieldMatcher(matcher1, &matchers1);
533     ASSERT_EQ(2, matchers1.size());
534 
535     // Initialize second set of matchers
536     FieldMatcher matcher2;
537     matcher2.set_field(10);
538 
539     child = matcher2.add_child();
540     child->set_field(1);
541     child->set_position(Position::ALL);
542     child->add_child()->set_field(1);
543 
544     vector<Matcher> matchers2;
545     translateFieldMatcher(matcher2, &matchers2);
546     ASSERT_EQ(1, matchers2.size());
547 
548     EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
549     EXPECT_TRUE(subsetDimensions(matchers2, matchers1));
550 }
551 /*
552  * Test not a subset with one matching Matcher, one non-matching Matcher.
553  */
554 TEST(AtomMatcherTest, TestSubsetDimensions2) {
555     // Initialize first set of matchers
556     FieldMatcher matcher1;
557     matcher1.set_field(10);
558 
559     FieldMatcher* child = matcher1.add_child();
560     child->set_field(1);
561 
562     child = matcher1.add_child();
563     child->set_field(2);
564 
565     vector<Matcher> matchers1;
566     translateFieldMatcher(matcher1, &matchers1);
567 
568     // Initialize second set of matchers
569     FieldMatcher matcher2;
570     matcher2.set_field(10);
571 
572     child = matcher2.add_child();
573     child->set_field(1);
574 
575     child = matcher2.add_child();
576     child->set_field(3);
577 
578     vector<Matcher> matchers2;
579     translateFieldMatcher(matcher2, &matchers2);
580 
581     EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
582 }
583 
584 /*
585  * Test not a subset if parent field is not equal.
586  */
587 TEST(AtomMatcherTest, TestSubsetDimensions3) {
588     // Initialize first set of matchers
589     FieldMatcher matcher1;
590     matcher1.set_field(10);
591 
592     FieldMatcher* child = matcher1.add_child();
593     child->set_field(1);
594 
595     vector<Matcher> matchers1;
596     translateFieldMatcher(matcher1, &matchers1);
597 
598     // Initialize second set of matchers
599     FieldMatcher matcher2;
600     matcher2.set_field(5);
601 
602     child = matcher2.add_child();
603     child->set_field(1);
604 
605     vector<Matcher> matchers2;
606     translateFieldMatcher(matcher2, &matchers2);
607 
608     EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
609 }
610 
611 /*
612  * Test is subset with two matching Matchers.
613  */
614 TEST(AtomMatcherTest, TestSubsetDimensions4) {
615     // Initialize first set of matchers
616     FieldMatcher matcher1;
617     matcher1.set_field(10);
618 
619     FieldMatcher* child = matcher1.add_child();
620     child->set_field(1);
621 
622     child = matcher1.add_child();
623     child->set_field(2);
624 
625     vector<Matcher> matchers1;
626     translateFieldMatcher(matcher1, &matchers1);
627 
628     // Initialize second set of matchers
629     FieldMatcher matcher2;
630     matcher2.set_field(10);
631 
632     child = matcher2.add_child();
633     child->set_field(1);
634 
635     child = matcher2.add_child();
636     child->set_field(2);
637 
638     child = matcher2.add_child();
639     child->set_field(3);
640 
641     vector<Matcher> matchers2;
642     translateFieldMatcher(matcher2, &matchers2);
643 
644     EXPECT_TRUE(subsetDimensions(matchers1, matchers2));
645     EXPECT_FALSE(subsetDimensions(matchers2, matchers1));
646 }
647 
648 }  // namespace statsd
649 }  // namespace os
650 }  // namespace android
651 #else
652 GTEST_LOG_(INFO) << "This test does nothing.\n";
653 #endif
654