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