Files
frameworks_base/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
Yao Chen 9c1debe330 Add annotation to atoms that represent a state change in atoms.proto
+ A state change atom can have one exclusive state field, and any
  number of primary key fields.

  When there is primary key in the atom, it means the state belongs to the primary key.
  For example,
  message UidProcessStateChanged {
    optional int32 uid = 1 [(stateFieldOption).option = PRIMARY];
    optional android.app.ProcessStateEnum state = 2 [(stateFieldOption).option = EXCLUSIVE];
  }

  When there is no primary key fields in the atom, the state is global.
  For example,
  message ScreenStateChanged {
     optional android.view.DisplayStateEnum state = 1 [(stateFieldOption).option = EXCLUSIVE];
  }

+ The annotation is consumed by stats_log_api_gen to generate a static map from the state
  atoms to its primary fields, and exclusive fields

+ stats_log.proto is splitted into 2 proto files, because statsd needs proto lite, and c++
  lite proto library cannot properly ignore the field options which requires full proto.

 This CL doesn't change any logic in the statsd yet. A separate CL will use the field option
 information to correctly track the state.

Test: added unit tests in stats_log_api_gen_test. and statsd_test pases.
Change-Id: I9e8a979fe81ba60efd4d854bb7087ce4b2b147ec
2018-02-21 16:46:56 -08:00

587 lines
24 KiB
C++

// 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 "src/condition/SimpleConditionTracker.h"
#include "tests/statsd_test_util.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <stdio.h>
#include <vector>
#include <numeric>
using std::map;
using std::unordered_map;
using std::vector;
#ifdef __ANDROID__
namespace android {
namespace os {
namespace statsd {
const ConfigKey kConfigKey(0, 12345);
const int ATTRIBUTION_NODE_FIELD_ID = 1;
const int ATTRIBUTION_UID_FIELD_ID = 1;
const int TAG_ID = 1;
SimplePredicate getWakeLockHeldCondition(bool countNesting, bool defaultFalse,
bool outputSlicedUid, Position position) {
SimplePredicate simplePredicate;
simplePredicate.set_start(StringToId("WAKE_LOCK_ACQUIRE"));
simplePredicate.set_stop(StringToId("WAKE_LOCK_RELEASE"));
simplePredicate.set_stop_all(StringToId("RELEASE_ALL"));
if (outputSlicedUid) {
simplePredicate.mutable_dimensions()->set_field(TAG_ID);
simplePredicate.mutable_dimensions()->add_child()->set_field(ATTRIBUTION_NODE_FIELD_ID);
simplePredicate.mutable_dimensions()->mutable_child(0)->set_position(position);
simplePredicate.mutable_dimensions()->mutable_child(0)->add_child()->set_field(
ATTRIBUTION_UID_FIELD_ID);
}
simplePredicate.set_count_nesting(countNesting);
simplePredicate.set_initial_value(defaultFalse ? SimplePredicate_InitialValue_FALSE
: SimplePredicate_InitialValue_UNKNOWN);
return simplePredicate;
}
void writeAttributionNodesToEvent(LogEvent* event, const std::vector<int> &uids) {
std::vector<AttributionNodeInternal> nodes;
for (size_t i = 0; i < uids.size(); ++i) {
AttributionNodeInternal node;
node.set_uid(uids[i]);
nodes.push_back(node);
}
event->write(nodes); // attribution chain.
}
void makeWakeLockEvent(
LogEvent* event, const std::vector<int> &uids, const string& wl, int acquire) {
writeAttributionNodesToEvent(event, uids);
event->write(wl);
event->write(acquire);
event->init();
}
std::map<int64_t, std::vector<HashableDimensionKey>> getWakeLockQueryKey(
const Position position,
const std::vector<int> &uids, const string& conditionName) {
std::map<int64_t, std::vector<HashableDimensionKey>> outputKeyMap;
std::vector<int> uid_indexes;
int pos[] = {1, 1, 1};
int depth = 2;
Field field(1, pos, depth);
switch(position) {
case Position::FIRST:
uid_indexes.push_back(0);
break;
case Position::LAST:
uid_indexes.push_back(uids.size() - 1);
field.setField(0x02018001);
break;
case Position::ANY:
uid_indexes.resize(uids.size());
std::iota(uid_indexes.begin(), uid_indexes.end(), 0);
field.setField(0x02010001);
break;
default:
break;
}
for (const int idx : uid_indexes) {
Value value((int32_t)uids[idx]);
HashableDimensionKey dim;
dim.addValue(FieldValue(field, value));
outputKeyMap[StringToId(conditionName)].push_back(dim);
}
return outputKeyMap;
}
TEST(SimpleConditionTrackerTest, TestNonSlicedCondition) {
SimplePredicate simplePredicate;
simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
simplePredicate.set_count_nesting(false);
simplePredicate.set_initial_value(SimplePredicate_InitialValue_UNKNOWN);
unordered_map<int64_t, int> trackerNameIndexMap;
trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"), 0 /*tracker index*/,
simplePredicate, trackerNameIndexMap);
LogEvent event(1 /*tagId*/, 0 /*timestamp*/);
vector<MatchingState> matcherState;
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kNotMatched);
vector<sp<ConditionTracker>> allPredicates;
vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
vector<bool> changedCache(1, false);
conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
changedCache);
// not matched start or stop. condition doesn't change
EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
EXPECT_FALSE(changedCache[0]);
// prepare a case for match start.
matcherState.clear();
matcherState.push_back(MatchingState::kMatched);
matcherState.push_back(MatchingState::kNotMatched);
conditionCache[0] = ConditionState::kNotEvaluated;
changedCache[0] = false;
conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
changedCache);
// now condition should change to true.
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
EXPECT_TRUE(changedCache[0]);
// match nothing.
matcherState.clear();
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kNotMatched);
conditionCache[0] = ConditionState::kNotEvaluated;
changedCache[0] = false;
conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
changedCache);
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
EXPECT_FALSE(changedCache[0]);
// the case for match stop.
matcherState.clear();
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kMatched);
conditionCache[0] = ConditionState::kNotEvaluated;
changedCache[0] = false;
conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
changedCache);
// condition changes to false.
EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
EXPECT_TRUE(changedCache[0]);
// match stop again.
matcherState.clear();
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kMatched);
conditionCache[0] = ConditionState::kNotEvaluated;
changedCache[0] = false;
conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
changedCache);
// condition should still be false. not changed.
EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
EXPECT_FALSE(changedCache[0]);
}
TEST(SimpleConditionTrackerTest, TestNonSlicedConditionNestCounting) {
SimplePredicate simplePredicate;
simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
simplePredicate.set_count_nesting(true);
unordered_map<int64_t, int> trackerNameIndexMap;
trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"),
0 /*condition tracker index*/, simplePredicate,
trackerNameIndexMap);
LogEvent event(1 /*tagId*/, 0 /*timestamp*/);
// one matched start
vector<MatchingState> matcherState;
matcherState.push_back(MatchingState::kMatched);
matcherState.push_back(MatchingState::kNotMatched);
vector<sp<ConditionTracker>> allPredicates;
vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
vector<bool> changedCache(1, false);
conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
changedCache);
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
EXPECT_TRUE(changedCache[0]);
// prepare for another matched start.
matcherState.clear();
matcherState.push_back(MatchingState::kMatched);
matcherState.push_back(MatchingState::kNotMatched);
conditionCache[0] = ConditionState::kNotEvaluated;
changedCache[0] = false;
conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
changedCache);
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
EXPECT_FALSE(changedCache[0]);
// ONE MATCHED STOP
matcherState.clear();
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kMatched);
conditionCache[0] = ConditionState::kNotEvaluated;
changedCache[0] = false;
conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
changedCache);
// result should still be true
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
EXPECT_FALSE(changedCache[0]);
// ANOTHER MATCHED STOP
matcherState.clear();
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kMatched);
conditionCache[0] = ConditionState::kNotEvaluated;
changedCache[0] = false;
conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
changedCache);
// result should still be true
EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
EXPECT_TRUE(changedCache[0]);
}
TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
for (Position position :
{ Position::ANY, Position::FIRST, Position::LAST}) {
vector<Matcher> dimensionInCondition;
std::unordered_set<HashableDimensionKey> dimensionKeys;
SimplePredicate simplePredicate = getWakeLockHeldCondition(
true /*nesting*/, true /*default to false*/, true /*output slice by uid*/,
position);
string conditionName = "WL_HELD_BY_UID2";
unordered_map<int64_t, int> trackerNameIndexMap;
trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
0 /*condition tracker index*/, simplePredicate,
trackerNameIndexMap);
std::vector<int> uids = {111, 222, 333};
LogEvent event(1 /*tagId*/, 0 /*timestamp*/);
makeWakeLockEvent(&event, uids, "wl1", 1);
// one matched start
vector<MatchingState> matcherState;
matcherState.push_back(MatchingState::kMatched);
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kNotMatched);
vector<sp<ConditionTracker>> allPredicates;
vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
vector<bool> changedCache(1, false);
conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
changedCache);
if (position == Position::FIRST ||
position == Position::LAST) {
EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
} else {
EXPECT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
}
EXPECT_TRUE(changedCache[0]);
// Now test query
const auto queryKey = getWakeLockQueryKey(position, uids, conditionName);
conditionCache[0] = ConditionState::kNotEvaluated;
conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
conditionCache, dimensionKeys);
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
// another wake lock acquired by this uid
LogEvent event2(1 /*tagId*/, 0 /*timestamp*/);
makeWakeLockEvent(&event2, uids, "wl2", 1);
matcherState.clear();
matcherState.push_back(MatchingState::kMatched);
matcherState.push_back(MatchingState::kNotMatched);
conditionCache[0] = ConditionState::kNotEvaluated;
changedCache[0] = false;
conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
changedCache);
EXPECT_FALSE(changedCache[0]);
if (position == Position::FIRST ||
position == Position::LAST) {
EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
} else {
EXPECT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
}
// wake lock 1 release
LogEvent event3(1 /*tagId*/, 0 /*timestamp*/);
makeWakeLockEvent(&event3, uids, "wl1", 0); // now release it.
matcherState.clear();
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kMatched);
conditionCache[0] = ConditionState::kNotEvaluated;
changedCache[0] = false;
conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
changedCache);
// nothing changes, because wake lock 2 is still held for this uid
EXPECT_FALSE(changedCache[0]);
if (position == Position::FIRST ||
position == Position::LAST) {
EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
} else {
EXPECT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
}
LogEvent event4(1 /*tagId*/, 0 /*timestamp*/);
makeWakeLockEvent(&event4, uids, "wl2", 0); // now release it.
matcherState.clear();
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kMatched);
conditionCache[0] = ConditionState::kNotEvaluated;
changedCache[0] = false;
conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache,
changedCache);
EXPECT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
EXPECT_TRUE(changedCache[0]);
// query again
conditionCache[0] = ConditionState::kNotEvaluated;
conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
conditionCache, dimensionKeys);
EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
}
}
TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) {
vector<Matcher> dimensionInCondition;
std::unordered_set<HashableDimensionKey> dimensionKeys;
SimplePredicate simplePredicate = getWakeLockHeldCondition(
true /*nesting*/, true /*default to false*/, false /*slice output by uid*/,
Position::ANY /* position */);
string conditionName = "WL_HELD";
unordered_map<int64_t, int> trackerNameIndexMap;
trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
0 /*condition tracker index*/, simplePredicate,
trackerNameIndexMap);
std::vector<int> uid_list1 = {111, 1111, 11111};
string uid1_wl1 = "wl1_1";
std::vector<int> uid_list2 = {222, 2222, 22222};
string uid2_wl1 = "wl2_1";
LogEvent event(1 /*tagId*/, 0 /*timestamp*/);
makeWakeLockEvent(&event, uid_list1, uid1_wl1, 1);
// one matched start for uid1
vector<MatchingState> matcherState;
matcherState.push_back(MatchingState::kMatched);
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kNotMatched);
vector<sp<ConditionTracker>> allPredicates;
vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
vector<bool> changedCache(1, false);
conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
changedCache);
EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
EXPECT_TRUE(changedCache[0]);
// Now test query
ConditionKey queryKey;
conditionCache[0] = ConditionState::kNotEvaluated;
conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
conditionCache, dimensionKeys);
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
// another wake lock acquired by this uid
LogEvent event2(1 /*tagId*/, 0 /*timestamp*/);
makeWakeLockEvent(&event2, uid_list2, uid2_wl1, 1);
matcherState.clear();
matcherState.push_back(MatchingState::kMatched);
matcherState.push_back(MatchingState::kNotMatched);
conditionCache[0] = ConditionState::kNotEvaluated;
changedCache[0] = false;
conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
changedCache);
EXPECT_FALSE(changedCache[0]);
// uid1 wake lock 1 release
LogEvent event3(1 /*tagId*/, 0 /*timestamp*/);
makeWakeLockEvent(&event3, uid_list1, uid1_wl1, 0); // now release it.
matcherState.clear();
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kMatched);
conditionCache[0] = ConditionState::kNotEvaluated;
changedCache[0] = false;
conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
changedCache);
// nothing changes, because uid2 is still holding wl.
EXPECT_FALSE(changedCache[0]);
LogEvent event4(1 /*tagId*/, 0 /*timestamp*/);
makeWakeLockEvent(&event4, uid_list2, uid2_wl1, 0); // now release it.
matcherState.clear();
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kMatched);
conditionCache[0] = ConditionState::kNotEvaluated;
changedCache[0] = false;
conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache,
changedCache);
EXPECT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
EXPECT_TRUE(changedCache[0]);
// query again
conditionCache[0] = ConditionState::kNotEvaluated;
dimensionKeys.clear();
conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
conditionCache, dimensionKeys);
EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
}
TEST(SimpleConditionTrackerTest, TestStopAll) {
for (Position position :
{Position::ANY, Position::FIRST, Position::LAST}) {
vector<Matcher> dimensionInCondition;
std::unordered_set<HashableDimensionKey> dimensionKeys;
SimplePredicate simplePredicate = getWakeLockHeldCondition(
true /*nesting*/, true /*default to false*/, true /*output slice by uid*/,
position);
string conditionName = "WL_HELD_BY_UID3";
unordered_map<int64_t, int> trackerNameIndexMap;
trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
0 /*condition tracker index*/, simplePredicate,
trackerNameIndexMap);
std::vector<int> uid_list1 = {111, 1111, 11111};
std::vector<int> uid_list2 = {222, 2222, 22222};
LogEvent event(1 /*tagId*/, 0 /*timestamp*/);
makeWakeLockEvent(&event, uid_list1, "wl1", 1);
// one matched start
vector<MatchingState> matcherState;
matcherState.push_back(MatchingState::kMatched);
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kNotMatched);
vector<sp<ConditionTracker>> allPredicates;
vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
vector<bool> changedCache(1, false);
conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
changedCache);
if (position == Position::FIRST ||
position == Position::LAST) {
EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
} else {
EXPECT_EQ(uid_list1.size(), conditionTracker.mSlicedConditionState.size());
}
EXPECT_TRUE(changedCache[0]);
// Now test query
const auto queryKey = getWakeLockQueryKey(position, uid_list1, conditionName);
conditionCache[0] = ConditionState::kNotEvaluated;
conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
conditionCache, dimensionKeys);
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
// another wake lock acquired by uid2
LogEvent event2(1 /*tagId*/, 0 /*timestamp*/);
makeWakeLockEvent(&event2, uid_list2, "wl2", 1);
matcherState.clear();
matcherState.push_back(MatchingState::kMatched);
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kNotMatched);
conditionCache[0] = ConditionState::kNotEvaluated;
changedCache[0] = false;
conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
changedCache);
if (position == Position::FIRST ||
position == Position::LAST) {
EXPECT_EQ(2UL, conditionTracker.mSlicedConditionState.size());
} else {
EXPECT_EQ(uid_list1.size() + uid_list2.size(),
conditionTracker.mSlicedConditionState.size());
}
EXPECT_TRUE(changedCache[0]);
// TEST QUERY
const auto queryKey2 = getWakeLockQueryKey(position, uid_list2, conditionName);
conditionCache[0] = ConditionState::kNotEvaluated;
conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
conditionCache, dimensionKeys);
EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
// stop all event
LogEvent event3(2 /*tagId*/, 0 /*timestamp*/);
matcherState.clear();
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kNotMatched);
matcherState.push_back(MatchingState::kMatched);
conditionCache[0] = ConditionState::kNotEvaluated;
changedCache[0] = false;
conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
changedCache);
EXPECT_TRUE(changedCache[0]);
EXPECT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
// TEST QUERY
const auto queryKey3 = getWakeLockQueryKey(position, uid_list1, conditionName);
conditionCache[0] = ConditionState::kNotEvaluated;
conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
conditionCache, dimensionKeys);
EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
// TEST QUERY
const auto queryKey4 = getWakeLockQueryKey(position, uid_list2, conditionName);
conditionCache[0] = ConditionState::kNotEvaluated;
conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition,
conditionCache, dimensionKeys);
EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
}
}
} // namespace statsd
} // namespace os
} // namespace android
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif