// Copyright (C) 2017 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include <gtest/gtest.h> #include <stdio.h> #include "annotations.h" #include "src/statsd_config.pb.h" #include "matchers/matcher_util.h" #include "stats_event.h" #include "stats_log_util.h" #include "stats_util.h" #include "statsd_test_util.h" using namespace android::os::statsd; using std::unordered_map; using std::vector; const int32_t TAG_ID = 123; const int32_t TAG_ID_2 = 28; // hardcoded tag of atom with uid field const int FIELD_ID_1 = 1; const int FIELD_ID_2 = 2; const int FIELD_ID_3 = 2; const int ATTRIBUTION_UID_FIELD_ID = 1; const int ATTRIBUTION_TAG_FIELD_ID = 2; #ifdef __ANDROID__ namespace { void makeIntLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, const int32_t value) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, timestamp); AStatsEvent_writeInt32(statsEvent, value); parseStatsEventToLogEvent(statsEvent, logEvent); } void makeFloatLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, const float floatValue) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, timestamp); AStatsEvent_writeFloat(statsEvent, floatValue); parseStatsEventToLogEvent(statsEvent, logEvent); } void makeStringLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, const string& name) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, timestamp); AStatsEvent_writeString(statsEvent, name.c_str()); parseStatsEventToLogEvent(statsEvent, logEvent); } void makeIntWithBoolAnnotationLogEvent(LogEvent* logEvent, const int32_t atomId, const int32_t field, const uint8_t annotationId, const bool annotationValue) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_writeInt32(statsEvent, field); AStatsEvent_addBoolAnnotation(statsEvent, annotationId, annotationValue); parseStatsEventToLogEvent(statsEvent, logEvent); } void makeAttributionLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, const vector<int>& attributionUids, const vector<string>& attributionTags, const string& name) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, timestamp); writeAttribution(statsEvent, attributionUids, attributionTags); AStatsEvent_writeString(statsEvent, name.c_str()); parseStatsEventToLogEvent(statsEvent, logEvent); } void makeBoolLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, const bool bool1, const bool bool2) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, timestamp); AStatsEvent_writeBool(statsEvent, bool1); AStatsEvent_writeBool(statsEvent, bool2); parseStatsEventToLogEvent(statsEvent, logEvent); } void makeRepeatedIntLogEvent(LogEvent* logEvent, const int32_t atomId, const vector<int>& intArray) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_writeInt32Array(statsEvent, intArray.data(), intArray.size()); parseStatsEventToLogEvent(statsEvent, logEvent); } void makeRepeatedUidLogEvent(LogEvent* logEvent, const int32_t atomId, const vector<int>& intArray) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_writeInt32Array(statsEvent, intArray.data(), intArray.size()); AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true); parseStatsEventToLogEvent(statsEvent, logEvent); } void makeRepeatedStringLogEvent(LogEvent* logEvent, const int32_t atomId, const vector<string>& stringArray) { vector<const char*> cStringArray(stringArray.size()); for (int i = 0; i < cStringArray.size(); i++) { cStringArray[i] = stringArray[i].c_str(); } AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_writeStringArray(statsEvent, cStringArray.data(), stringArray.size()); parseStatsEventToLogEvent(statsEvent, logEvent); } } // anonymous namespace TEST(AtomMatcherTest, TestSimpleMatcher) { sp<UidMap> uidMap = new UidMap(); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); LogEvent event(/*uid=*/0, /*pid=*/0); makeIntLogEvent(&event, TAG_ID, 0, 11); // Test EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); // Wrong tag id. simpleMatcher->set_atom_id(TAG_ID + 1); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestAttributionMatcher) { sp<UidMap> uidMap = new UidMap(); std::vector<int> attributionUids = {1111, 2222, 3333}; std::vector<string> attributionTags = {"location1", "location2", "location3"}; // Set up the log event. LogEvent event(/*uid=*/0, /*pid=*/0); makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value"); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); // Match first node. auto attributionMatcher = simpleMatcher->add_field_value_matcher(); attributionMatcher->set_field(FIELD_ID_1); attributionMatcher->set_position(Position::FIRST); attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field( ATTRIBUTION_TAG_FIELD_ID); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "tag"); auto fieldMatcher = simpleMatcher->add_field_value_matcher(); fieldMatcher->set_field(FIELD_ID_2); fieldMatcher->set_eq_string("some value"); // Tag not matched. EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "location3"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "location1"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); // Match last node. attributionMatcher->set_position(Position::LAST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "location3"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); // Match any node. attributionMatcher->set_position(Position::ANY); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "location1"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "location2"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "location3"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "location4"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); // Attribution match but primitive field not match. attributionMatcher->set_position(Position::ANY); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "location2"); fieldMatcher->set_eq_string("wrong value"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldMatcher->set_eq_string("some value"); // Uid match. attributionMatcher->set_position(Position::ANY); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_field( ATTRIBUTION_UID_FIELD_ID); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg0"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); uidMap->updateMap( 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, {android::String16("v1"), android::String16("v1"), android::String16("v2"), android::String16("v1"), android::String16("v2")}, {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, {android::String16(""), android::String16(""), android::String16(""), android::String16(""), android::String16("")}, /* certificateHash */ {{}, {}, {}, {}, {}}); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg3"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg2"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg1"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg0"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->set_position(Position::FIRST); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg0"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg3"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg2"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg1"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->set_position(Position::LAST); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg0"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg3"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg2"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg1"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); // Uid + tag. attributionMatcher->set_position(Position::ANY); attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field( ATTRIBUTION_TAG_FIELD_ID); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg0"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location1"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg1"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location1"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg1"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location2"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg2"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location3"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg3"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location3"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg3"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location1"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->set_position(Position::FIRST); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg0"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location1"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg1"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location1"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg1"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location2"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg2"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location3"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg3"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location3"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg3"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location1"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->set_position(Position::LAST); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg0"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location1"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg1"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location1"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg1"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location2"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg2"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location3"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg3"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location3"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( "pkg3"); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( "location1"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestUidFieldMatcher) { sp<UidMap> uidMap = new UidMap(); uidMap->updateMap( 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, {android::String16("v1"), android::String16("v1"), android::String16("v2"), android::String16("v1"), android::String16("v2")}, {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, {android::String16(""), android::String16(""), android::String16(""), android::String16(""), android::String16("")}, /* certificateHash */ {{}, {}, {}, {}, {}}); // Set up matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); simpleMatcher->add_field_value_matcher()->set_field(1); simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("pkg0"); // Make event without is_uid annotation. LogEvent event1(/*uid=*/0, /*pid=*/0); makeIntLogEvent(&event1, TAG_ID, 0, 1111); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1)); // Make event with is_uid annotation. LogEvent event2(/*uid=*/0, /*pid=*/0); makeIntWithBoolAnnotationLogEvent(&event2, TAG_ID_2, 1111, ANNOTATION_ID_IS_UID, true); // Event has is_uid annotation, so mapping from uid to package name occurs. simpleMatcher->set_atom_id(TAG_ID_2); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2)); // Event has is_uid annotation, but uid maps to different package name. simpleMatcher->mutable_field_value_matcher(0)->set_eq_string( "pkg2"); // package names are normalized EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2)); } TEST(AtomMatcherTest, TestRepeatedUidFieldMatcher) { sp<UidMap> uidMap = new UidMap(); uidMap->updateMap( 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, {android::String16("v1"), android::String16("v1"), android::String16("v2"), android::String16("v1"), android::String16("v2")}, {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, {android::String16(""), android::String16(""), android::String16(""), android::String16(""), android::String16("")}, /* certificateHash */ {{}, {}, {}, {}, {}}); // Set up matcher. AtomMatcher matcher; SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher(); fieldValueMatcher->set_field(FIELD_ID_1); // No is_uid annotation, no mapping from uid to package name. vector<int> intArray = {1111, 3333, 2222}; LogEvent event1(/*uid=*/0, /*pid=*/0); makeRepeatedIntLogEvent(&event1, TAG_ID, intArray); fieldValueMatcher->set_position(Position::FIRST); fieldValueMatcher->set_eq_string("pkg0"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1)); fieldValueMatcher->set_position(Position::LAST); fieldValueMatcher->set_eq_string("pkg1"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1)); fieldValueMatcher->set_position(Position::ANY); fieldValueMatcher->set_eq_string("pkg2"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1)); // is_uid annotation, mapping from uid to package name. LogEvent event2(/*uid=*/0, /*pid=*/0); makeRepeatedUidLogEvent(&event2, TAG_ID, intArray); fieldValueMatcher->set_position(Position::FIRST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2)); fieldValueMatcher->set_eq_string("pkg0"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2)); fieldValueMatcher->set_position(Position::LAST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2)); fieldValueMatcher->set_eq_string("pkg1"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2)); fieldValueMatcher->set_position(Position::ANY); fieldValueMatcher->set_eq_string("pkg"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2)); fieldValueMatcher->set_eq_string("pkg2"); // package names are normalized EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2)); } TEST(AtomMatcherTest, TestNeqAnyStringMatcher_SingleString) { sp<UidMap> uidMap = new UidMap(); // Set up the matcher AtomMatcher matcher; SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher(); fieldValueMatcher->set_field(FIELD_ID_1); StringListMatcher* neqStringList = fieldValueMatcher->mutable_neq_any_string(); neqStringList->add_str_value("some value"); neqStringList->add_str_value("another value"); // First string matched. LogEvent event1(/*uid=*/0, /*pid=*/0); makeStringLogEvent(&event1, TAG_ID, 0, "some value"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1)); // Second string matched. LogEvent event2(/*uid=*/0, /*pid=*/0); makeStringLogEvent(&event2, TAG_ID, 0, "another value"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2)); // No strings matched. LogEvent event3(/*uid=*/0, /*pid=*/0); makeStringLogEvent(&event3, TAG_ID, 0, "foo"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event3)); } TEST(AtomMatcherTest, TestNeqAnyStringMatcher_AttributionUids) { sp<UidMap> uidMap = new UidMap(); uidMap->updateMap( 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, {android::String16("v1"), android::String16("v1"), android::String16("v2"), android::String16("v1"), android::String16("v2")}, {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, {android::String16(""), android::String16(""), android::String16(""), android::String16(""), android::String16("")}, /* certificateHash */ {{}, {}, {}, {}, {}}); std::vector<int> attributionUids = {1111, 2222, 3333, 1066}; std::vector<string> attributionTags = {"location1", "location2", "location3", "location3"}; // Set up the event LogEvent event(/*uid=*/0, /*pid=*/0); makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value"); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); // Match first node. auto attributionMatcher = simpleMatcher->add_field_value_matcher(); attributionMatcher->set_field(FIELD_ID_1); attributionMatcher->set_position(Position::FIRST); attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field( ATTRIBUTION_UID_FIELD_ID); auto neqStringList = attributionMatcher->mutable_matches_tuple() ->mutable_field_value_matcher(0) ->mutable_neq_any_string(); neqStringList->add_str_value("pkg2"); neqStringList->add_str_value("pkg3"); auto fieldMatcher = simpleMatcher->add_field_value_matcher(); fieldMatcher->set_field(FIELD_ID_2); fieldMatcher->set_eq_string("some value"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); neqStringList->Clear(); neqStringList->add_str_value("pkg1"); neqStringList->add_str_value("pkg3"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->set_position(Position::ANY); neqStringList->Clear(); neqStringList->add_str_value("maps.com"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); neqStringList->Clear(); neqStringList->add_str_value("PkG3"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->set_position(Position::LAST); neqStringList->Clear(); neqStringList->add_str_value("AID_STATSD"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestEqAnyStringMatcher) { sp<UidMap> uidMap = new UidMap(); uidMap->updateMap( 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, {android::String16("v1"), android::String16("v1"), android::String16("v2"), android::String16("v1"), android::String16("v2")}, {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, {android::String16(""), android::String16(""), android::String16(""), android::String16(""), android::String16("")}, /* certificateHash */ {{}, {}, {}, {}, {}}); std::vector<int> attributionUids = {1067, 2222, 3333, 1066}; std::vector<string> attributionTags = {"location1", "location2", "location3", "location3"}; // Set up the event LogEvent event(/*uid=*/0, /*pid=*/0); makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value"); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); // Match first node. auto attributionMatcher = simpleMatcher->add_field_value_matcher(); attributionMatcher->set_field(FIELD_ID_1); attributionMatcher->set_position(Position::FIRST); attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field( ATTRIBUTION_UID_FIELD_ID); auto eqStringList = attributionMatcher->mutable_matches_tuple() ->mutable_field_value_matcher(0) ->mutable_eq_any_string(); eqStringList->add_str_value("AID_ROOT"); eqStringList->add_str_value("AID_INCIDENTD"); auto fieldMatcher = simpleMatcher->add_field_value_matcher(); fieldMatcher->set_field(FIELD_ID_2); fieldMatcher->set_eq_string("some value"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->set_position(Position::ANY); eqStringList->Clear(); eqStringList->add_str_value("AID_STATSD"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); eqStringList->Clear(); eqStringList->add_str_value("pkg1"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); auto normalStringField = fieldMatcher->mutable_eq_any_string(); normalStringField->add_str_value("some value123"); normalStringField->add_str_value("some value"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); normalStringField->Clear(); normalStringField->add_str_value("AID_STATSD"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); eqStringList->Clear(); eqStringList->add_str_value("maps.com"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestBoolMatcher) { sp<UidMap> uidMap = new UidMap(); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); auto keyValue1 = simpleMatcher->add_field_value_matcher(); keyValue1->set_field(FIELD_ID_1); auto keyValue2 = simpleMatcher->add_field_value_matcher(); keyValue2->set_field(FIELD_ID_2); // Set up the event LogEvent event(/*uid=*/0, /*pid=*/0); makeBoolLogEvent(&event, TAG_ID, 0, true, false); // Test keyValue1->set_eq_bool(true); keyValue2->set_eq_bool(false); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); keyValue1->set_eq_bool(false); keyValue2->set_eq_bool(false); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); keyValue1->set_eq_bool(false); keyValue2->set_eq_bool(true); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); keyValue1->set_eq_bool(true); keyValue2->set_eq_bool(true); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestStringMatcher) { sp<UidMap> uidMap = new UidMap(); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); auto keyValue = simpleMatcher->add_field_value_matcher(); keyValue->set_field(FIELD_ID_1); keyValue->set_eq_string("some value"); // Set up the event LogEvent event(/*uid=*/0, /*pid=*/0); makeStringLogEvent(&event, TAG_ID, 0, "some value"); // Test EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestIntMatcher_EmptyRepeatedField) { sp<UidMap> uidMap = new UidMap(); // Set up the log event. LogEvent event(/*uid=*/0, /*pid=*/0); makeRepeatedIntLogEvent(&event, TAG_ID, {}); // Set up the matcher. AtomMatcher matcher; SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher(); fieldValueMatcher->set_field(FIELD_ID_1); // Match first int. fieldValueMatcher->set_position(Position::FIRST); fieldValueMatcher->set_eq_int(9); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); // Match last int. fieldValueMatcher->set_position(Position::LAST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); // Match any int. fieldValueMatcher->set_position(Position::ANY); fieldValueMatcher->set_eq_int(13); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestIntMatcher_RepeatedIntField) { sp<UidMap> uidMap = new UidMap(); // Set up the log event. LogEvent event(/*uid=*/0, /*pid=*/0); vector<int> intArray = {21, 9}; makeRepeatedIntLogEvent(&event, TAG_ID, intArray); // Set up the matcher. AtomMatcher matcher; SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); // Match first int. FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher(); fieldValueMatcher->set_field(FIELD_ID_1); fieldValueMatcher->set_position(Position::FIRST); fieldValueMatcher->set_eq_int(9); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_eq_int(21); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); // Match last int. fieldValueMatcher->set_position(Position::LAST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_eq_int(9); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); // Match any int. fieldValueMatcher->set_position(Position::ANY); fieldValueMatcher->set_eq_int(13); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_eq_int(21); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_eq_int(9); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestLtIntMatcher_RepeatedIntField) { sp<UidMap> uidMap = new UidMap(); // Set up the log event. LogEvent event(/*uid=*/0, /*pid=*/0); vector<int> intArray = {21, 9}; makeRepeatedIntLogEvent(&event, TAG_ID, intArray); // Set up the matcher. AtomMatcher matcher; SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); // Match first int. FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher(); fieldValueMatcher->set_field(FIELD_ID_1); fieldValueMatcher->set_position(Position::FIRST); fieldValueMatcher->set_lt_int(9); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_lt_int(21); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_lt_int(23); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); // Match last int. fieldValueMatcher->set_position(Position::LAST); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_lt_int(9); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_lt_int(8); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); // Match any int. fieldValueMatcher->set_position(Position::ANY); fieldValueMatcher->set_lt_int(21); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_lt_int(8); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_lt_int(23); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestStringMatcher_RepeatedStringField) { sp<UidMap> uidMap = new UidMap(); // Set up the log event. LogEvent event(/*uid=*/0, /*pid=*/0); vector<string> strArray = {"str1", "str2", "str3"}; makeRepeatedStringLogEvent(&event, TAG_ID, strArray); // Set up the matcher. AtomMatcher matcher; SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); // Match first int. FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher(); fieldValueMatcher->set_field(FIELD_ID_1); fieldValueMatcher->set_position(Position::FIRST); fieldValueMatcher->set_eq_string("str2"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_eq_string("str1"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); // Match last int. fieldValueMatcher->set_position(Position::LAST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_eq_string("str3"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); // Match any int. fieldValueMatcher->set_position(Position::ANY); fieldValueMatcher->set_eq_string("str4"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_eq_string("str1"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_eq_string("str2"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_eq_string("str3"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestEqAnyStringMatcher_RepeatedStringField) { sp<UidMap> uidMap = new UidMap(); // Set up the log event. LogEvent event(/*uid=*/0, /*pid=*/0); vector<string> strArray = {"str1", "str2", "str3"}; makeRepeatedStringLogEvent(&event, TAG_ID, strArray); // Set up the matcher. AtomMatcher matcher; SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher(); fieldValueMatcher->set_field(FIELD_ID_1); StringListMatcher* eqStringList = fieldValueMatcher->mutable_eq_any_string(); fieldValueMatcher->set_position(Position::FIRST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::LAST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::ANY); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); eqStringList->add_str_value("str4"); fieldValueMatcher->set_position(Position::FIRST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::LAST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::ANY); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); eqStringList->add_str_value("str2"); fieldValueMatcher->set_position(Position::FIRST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::LAST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::ANY); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); eqStringList->add_str_value("str3"); fieldValueMatcher->set_position(Position::FIRST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::LAST); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::ANY); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); eqStringList->add_str_value("str1"); fieldValueMatcher->set_position(Position::FIRST); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::LAST); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::ANY); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestNeqAnyStringMatcher_RepeatedStringField) { sp<UidMap> uidMap = new UidMap(); // Set up the log event. LogEvent event(/*uid=*/0, /*pid=*/0); vector<string> strArray = {"str1", "str2", "str3"}; makeRepeatedStringLogEvent(&event, TAG_ID, strArray); // Set up the matcher. AtomMatcher matcher; SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher(); fieldValueMatcher->set_field(FIELD_ID_1); StringListMatcher* neqStringList = fieldValueMatcher->mutable_neq_any_string(); fieldValueMatcher->set_position(Position::FIRST); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::LAST); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::ANY); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); neqStringList->add_str_value("str4"); fieldValueMatcher->set_position(Position::FIRST); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::LAST); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::ANY); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); neqStringList->add_str_value("str2"); fieldValueMatcher->set_position(Position::FIRST); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::LAST); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::ANY); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); neqStringList->add_str_value("str3"); fieldValueMatcher->set_position(Position::FIRST); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::LAST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::ANY); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); neqStringList->add_str_value("str1"); fieldValueMatcher->set_position(Position::FIRST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::LAST); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); fieldValueMatcher->set_position(Position::ANY); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestMultiFieldsMatcher) { sp<UidMap> uidMap = new UidMap(); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); auto keyValue1 = simpleMatcher->add_field_value_matcher(); keyValue1->set_field(FIELD_ID_1); auto keyValue2 = simpleMatcher->add_field_value_matcher(); keyValue2->set_field(FIELD_ID_2); // Set up the event LogEvent event(/*uid=*/0, /*pid=*/0); CreateTwoValueLogEvent(&event, TAG_ID, 0, 2, 3); // Test keyValue1->set_eq_int(2); keyValue2->set_eq_int(3); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); keyValue1->set_eq_int(2); keyValue2->set_eq_int(4); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); keyValue1->set_eq_int(4); keyValue2->set_eq_int(3); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestIntComparisonMatcher) { sp<UidMap> uidMap = new UidMap(); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); auto keyValue = simpleMatcher->add_field_value_matcher(); keyValue->set_field(FIELD_ID_1); // Set up the event LogEvent event(/*uid=*/0, /*pid=*/0); makeIntLogEvent(&event, TAG_ID, 0, 11); // Test // eq_int keyValue->set_eq_int(10); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); keyValue->set_eq_int(11); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); keyValue->set_eq_int(12); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); // lt_int keyValue->set_lt_int(10); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); keyValue->set_lt_int(11); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); keyValue->set_lt_int(12); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); // lte_int keyValue->set_lte_int(10); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); keyValue->set_lte_int(11); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); keyValue->set_lte_int(12); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); // gt_int keyValue->set_gt_int(10); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); keyValue->set_gt_int(11); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); keyValue->set_gt_int(12); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); // gte_int keyValue->set_gte_int(10); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); keyValue->set_gte_int(11); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); keyValue->set_gte_int(12); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestFloatComparisonMatcher) { sp<UidMap> uidMap = new UidMap(); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); auto keyValue = simpleMatcher->add_field_value_matcher(); keyValue->set_field(FIELD_ID_1); LogEvent event1(/*uid=*/0, /*pid=*/0); makeFloatLogEvent(&event1, TAG_ID, 0, 10.1f); keyValue->set_lt_float(10.0); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1)); LogEvent event2(/*uid=*/0, /*pid=*/0); makeFloatLogEvent(&event2, TAG_ID, 0, 9.9f); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2)); LogEvent event3(/*uid=*/0, /*pid=*/0); makeFloatLogEvent(&event3, TAG_ID, 0, 10.1f); keyValue->set_gt_float(10.0); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event3)); LogEvent event4(/*uid=*/0, /*pid=*/0); makeFloatLogEvent(&event4, TAG_ID, 0, 9.9f); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event4)); } // Helper for the composite matchers. void addSimpleMatcher(SimpleAtomMatcher* simpleMatcher, int tag, int key, int val) { simpleMatcher->set_atom_id(tag); auto keyValue = simpleMatcher->add_field_value_matcher(); keyValue->set_field(key); keyValue->set_eq_int(val); } TEST(AtomMatcherTest, TestAndMatcher) { // Set up the matcher LogicalOperation operation = LogicalOperation::AND; vector<int> children; children.push_back(0); children.push_back(1); children.push_back(2); vector<MatchingState> matcherResults; matcherResults.push_back(MatchingState::kMatched); matcherResults.push_back(MatchingState::kNotMatched); matcherResults.push_back(MatchingState::kMatched); EXPECT_FALSE(combinationMatch(children, operation, matcherResults)); matcherResults.clear(); matcherResults.push_back(MatchingState::kMatched); matcherResults.push_back(MatchingState::kMatched); matcherResults.push_back(MatchingState::kMatched); EXPECT_TRUE(combinationMatch(children, operation, matcherResults)); } TEST(AtomMatcherTest, TestOrMatcher) { // Set up the matcher LogicalOperation operation = LogicalOperation::OR; vector<int> children; children.push_back(0); children.push_back(1); children.push_back(2); vector<MatchingState> matcherResults; matcherResults.push_back(MatchingState::kMatched); matcherResults.push_back(MatchingState::kNotMatched); matcherResults.push_back(MatchingState::kMatched); EXPECT_TRUE(combinationMatch(children, operation, matcherResults)); matcherResults.clear(); matcherResults.push_back(MatchingState::kNotMatched); matcherResults.push_back(MatchingState::kNotMatched); matcherResults.push_back(MatchingState::kNotMatched); EXPECT_FALSE(combinationMatch(children, operation, matcherResults)); } TEST(AtomMatcherTest, TestNotMatcher) { // Set up the matcher LogicalOperation operation = LogicalOperation::NOT; vector<int> children; children.push_back(0); vector<MatchingState> matcherResults; matcherResults.push_back(MatchingState::kMatched); EXPECT_FALSE(combinationMatch(children, operation, matcherResults)); matcherResults.clear(); matcherResults.push_back(MatchingState::kNotMatched); EXPECT_TRUE(combinationMatch(children, operation, matcherResults)); } TEST(AtomMatcherTest, TestNandMatcher) { // Set up the matcher LogicalOperation operation = LogicalOperation::NAND; vector<int> children; children.push_back(0); children.push_back(1); vector<MatchingState> matcherResults; matcherResults.push_back(MatchingState::kMatched); matcherResults.push_back(MatchingState::kNotMatched); EXPECT_TRUE(combinationMatch(children, operation, matcherResults)); matcherResults.clear(); matcherResults.push_back(MatchingState::kNotMatched); matcherResults.push_back(MatchingState::kNotMatched); EXPECT_TRUE(combinationMatch(children, operation, matcherResults)); matcherResults.clear(); matcherResults.push_back(MatchingState::kMatched); matcherResults.push_back(MatchingState::kMatched); EXPECT_FALSE(combinationMatch(children, operation, matcherResults)); } TEST(AtomMatcherTest, TestNorMatcher) { // Set up the matcher LogicalOperation operation = LogicalOperation::NOR; vector<int> children; children.push_back(0); children.push_back(1); vector<MatchingState> matcherResults; matcherResults.push_back(MatchingState::kMatched); matcherResults.push_back(MatchingState::kNotMatched); EXPECT_FALSE(combinationMatch(children, operation, matcherResults)); matcherResults.clear(); matcherResults.push_back(MatchingState::kNotMatched); matcherResults.push_back(MatchingState::kNotMatched); EXPECT_TRUE(combinationMatch(children, operation, matcherResults)); matcherResults.clear(); matcherResults.push_back(MatchingState::kMatched); matcherResults.push_back(MatchingState::kMatched); EXPECT_FALSE(combinationMatch(children, operation, matcherResults)); } #else GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif