blob: 86e24fb0c80b23cd4908fd7096feeec8160ea7bb [file] [log] [blame]
Yao Chen967b2052017-11-07 16:36:43 -08001// Copyright (C) 2017 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
Yangster-mac94e197c2018-01-02 16:03:03 -080014
Yao Chen967b2052017-11-07 16:36:43 -080015#include "src/condition/SimpleConditionTracker.h"
Ruchir Rastogidfd63d42020-02-20 17:54:13 -080016#include "stats_event.h"
Yangster-mac94e197c2018-01-02 16:03:03 -080017#include "tests/statsd_test_util.h"
Yao Chen967b2052017-11-07 16:36:43 -080018
19#include <gmock/gmock.h>
20#include <gtest/gtest.h>
21#include <stdio.h>
22#include <vector>
Yangster-mac20877162017-12-22 17:19:39 -080023#include <numeric>
Yao Chen967b2052017-11-07 16:36:43 -080024
25using std::map;
26using std::unordered_map;
27using std::vector;
28
29#ifdef __ANDROID__
30
31namespace android {
32namespace os {
33namespace statsd {
34
Ruchir Rastogidfd63d42020-02-20 17:54:13 -080035namespace {
36
Yangster-mac94e197c2018-01-02 16:03:03 -080037const ConfigKey kConfigKey(0, 12345);
Yao Chenb3561512017-11-21 18:07:17 -080038
Yangster-mac20877162017-12-22 17:19:39 -080039const int ATTRIBUTION_NODE_FIELD_ID = 1;
40const int ATTRIBUTION_UID_FIELD_ID = 1;
41const int TAG_ID = 1;
42
Stefan Lafon12d01fa2017-12-04 20:56:09 -080043SimplePredicate getWakeLockHeldCondition(bool countNesting, bool defaultFalse,
Yangster-mac20877162017-12-22 17:19:39 -080044 bool outputSlicedUid, Position position) {
Stefan Lafon12d01fa2017-12-04 20:56:09 -080045 SimplePredicate simplePredicate;
Yangster-mac94e197c2018-01-02 16:03:03 -080046 simplePredicate.set_start(StringToId("WAKE_LOCK_ACQUIRE"));
47 simplePredicate.set_stop(StringToId("WAKE_LOCK_RELEASE"));
48 simplePredicate.set_stop_all(StringToId("RELEASE_ALL"));
Yao Chen967b2052017-11-07 16:36:43 -080049 if (outputSlicedUid) {
Yangster-mac20877162017-12-22 17:19:39 -080050 simplePredicate.mutable_dimensions()->set_field(TAG_ID);
51 simplePredicate.mutable_dimensions()->add_child()->set_field(ATTRIBUTION_NODE_FIELD_ID);
52 simplePredicate.mutable_dimensions()->mutable_child(0)->set_position(position);
53 simplePredicate.mutable_dimensions()->mutable_child(0)->add_child()->set_field(
54 ATTRIBUTION_UID_FIELD_ID);
Yao Chen967b2052017-11-07 16:36:43 -080055 }
56
Stefan Lafon12d01fa2017-12-04 20:56:09 -080057 simplePredicate.set_count_nesting(countNesting);
58 simplePredicate.set_initial_value(defaultFalse ? SimplePredicate_InitialValue_FALSE
59 : SimplePredicate_InitialValue_UNKNOWN);
60 return simplePredicate;
Yao Chen967b2052017-11-07 16:36:43 -080061}
62
Ruchir Rastogidfd63d42020-02-20 17:54:13 -080063void makeWakeLockEvent(LogEvent* logEvent, uint32_t atomId, uint64_t timestamp,
64 const vector<int>& uids, const string& wl, int acquire) {
65 AStatsEvent* statsEvent = AStatsEvent_obtain();
66 AStatsEvent_setAtomId(statsEvent, atomId);
67 AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
68
69 vector<std::string> tags(uids.size()); // vector of empty strings
tsaichristine8dca82e2020-04-07 09:40:03 -070070 writeAttribution(statsEvent, uids, tags);
Ruchir Rastogidfd63d42020-02-20 17:54:13 -080071
72 AStatsEvent_writeString(statsEvent, wl.c_str());
73 AStatsEvent_writeInt32(statsEvent, acquire);
Ruchir Rastogidfd63d42020-02-20 17:54:13 -080074
tsaichristine8dca82e2020-04-07 09:40:03 -070075 parseStatsEventToLogEvent(statsEvent, logEvent);
Yangster-mac20877162017-12-22 17:19:39 -080076}
77
Ruchir Rastogidfd63d42020-02-20 17:54:13 -080078} // anonymous namespace
79
Yao Chen967b2052017-11-07 16:36:43 -080080
Yangster13fb7e42018-03-07 17:30:49 -080081std::map<int64_t, HashableDimensionKey> getWakeLockQueryKey(
Yangster-mac20877162017-12-22 17:19:39 -080082 const Position position,
83 const std::vector<int> &uids, const string& conditionName) {
Yangster13fb7e42018-03-07 17:30:49 -080084 std::map<int64_t, HashableDimensionKey> outputKeyMap;
Yangster-mac20877162017-12-22 17:19:39 -080085 std::vector<int> uid_indexes;
Yao Chen8a8d16c2018-02-08 14:50:40 -080086 int pos[] = {1, 1, 1};
87 int depth = 2;
88 Field field(1, pos, depth);
Yangster-mac20877162017-12-22 17:19:39 -080089 switch(position) {
90 case Position::FIRST:
91 uid_indexes.push_back(0);
92 break;
93 case Position::LAST:
94 uid_indexes.push_back(uids.size() - 1);
Yao Chen8a8d16c2018-02-08 14:50:40 -080095 field.setField(0x02018001);
Yangster-mac20877162017-12-22 17:19:39 -080096 break;
97 case Position::ANY:
98 uid_indexes.resize(uids.size());
99 std::iota(uid_indexes.begin(), uid_indexes.end(), 0);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800100 field.setField(0x02010001);
Yangster-mac20877162017-12-22 17:19:39 -0800101 break;
102 default:
103 break;
104 }
105
106 for (const int idx : uid_indexes) {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800107 Value value((int32_t)uids[idx]);
108 HashableDimensionKey dim;
109 dim.addValue(FieldValue(field, value));
Yangster13fb7e42018-03-07 17:30:49 -0800110 outputKeyMap[StringToId(conditionName)] = dim;
Yangster-mac20877162017-12-22 17:19:39 -0800111 }
112 return outputKeyMap;
Yao Chen967b2052017-11-07 16:36:43 -0800113}
114
115TEST(SimpleConditionTrackerTest, TestNonSlicedCondition) {
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800116 SimplePredicate simplePredicate;
Yangster-mac94e197c2018-01-02 16:03:03 -0800117 simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
118 simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800119 simplePredicate.set_count_nesting(false);
120 simplePredicate.set_initial_value(SimplePredicate_InitialValue_UNKNOWN);
Yao Chen967b2052017-11-07 16:36:43 -0800121
Yangster-mac94e197c2018-01-02 16:03:03 -0800122 unordered_map<int64_t, int> trackerNameIndexMap;
123 trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
124 trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
Yao Chen967b2052017-11-07 16:36:43 -0800125
Yangster-mac94e197c2018-01-02 16:03:03 -0800126 SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"), 0 /*tracker index*/,
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800127 simplePredicate, trackerNameIndexMap);
Yangster13fb7e42018-03-07 17:30:49 -0800128 EXPECT_FALSE(conditionTracker.isSliced());
Yao Chen967b2052017-11-07 16:36:43 -0800129
tsaichristine7747d372020-02-28 17:36:59 -0800130 // This event is not accessed in this test besides dimensions which is why this is okay.
131 // This is technically an invalid LogEvent because we do not call parseBuffer.
132 LogEvent event(/*uid=*/0, /*pid=*/0);
Yao Chen967b2052017-11-07 16:36:43 -0800133
134 vector<MatchingState> matcherState;
135 matcherState.push_back(MatchingState::kNotMatched);
136 matcherState.push_back(MatchingState::kNotMatched);
137
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800138 vector<sp<ConditionTracker>> allPredicates;
Yao Chen967b2052017-11-07 16:36:43 -0800139 vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
140 vector<bool> changedCache(1, false);
141
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800142 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
Yao Chen967b2052017-11-07 16:36:43 -0800143 changedCache);
144 // not matched start or stop. condition doesn't change
145 EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
146 EXPECT_FALSE(changedCache[0]);
147
148 // prepare a case for match start.
149 matcherState.clear();
150 matcherState.push_back(MatchingState::kMatched);
151 matcherState.push_back(MatchingState::kNotMatched);
152 conditionCache[0] = ConditionState::kNotEvaluated;
153 changedCache[0] = false;
154
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800155 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
Yao Chen967b2052017-11-07 16:36:43 -0800156 changedCache);
157 // now condition should change to true.
158 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
159 EXPECT_TRUE(changedCache[0]);
160
Yao Chend41c4222017-11-15 19:26:14 -0800161 // match nothing.
162 matcherState.clear();
163 matcherState.push_back(MatchingState::kNotMatched);
164 matcherState.push_back(MatchingState::kNotMatched);
165 conditionCache[0] = ConditionState::kNotEvaluated;
166 changedCache[0] = false;
167
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800168 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
Yao Chend41c4222017-11-15 19:26:14 -0800169 changedCache);
170 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
171 EXPECT_FALSE(changedCache[0]);
172
Yao Chen967b2052017-11-07 16:36:43 -0800173 // the case for match stop.
174 matcherState.clear();
175 matcherState.push_back(MatchingState::kNotMatched);
176 matcherState.push_back(MatchingState::kMatched);
177 conditionCache[0] = ConditionState::kNotEvaluated;
178 changedCache[0] = false;
179
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800180 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
Yao Chen967b2052017-11-07 16:36:43 -0800181 changedCache);
182
183 // condition changes to false.
184 EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
185 EXPECT_TRUE(changedCache[0]);
186
187 // match stop again.
188 matcherState.clear();
189 matcherState.push_back(MatchingState::kNotMatched);
190 matcherState.push_back(MatchingState::kMatched);
191 conditionCache[0] = ConditionState::kNotEvaluated;
192 changedCache[0] = false;
193
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800194 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
Yao Chen967b2052017-11-07 16:36:43 -0800195 changedCache);
196 // condition should still be false. not changed.
197 EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
198 EXPECT_FALSE(changedCache[0]);
199}
200
201TEST(SimpleConditionTrackerTest, TestNonSlicedConditionNestCounting) {
Yangster13fb7e42018-03-07 17:30:49 -0800202 std::vector<sp<ConditionTracker>> allConditions;
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800203 SimplePredicate simplePredicate;
Yangster-mac94e197c2018-01-02 16:03:03 -0800204 simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
205 simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800206 simplePredicate.set_count_nesting(true);
Yao Chen967b2052017-11-07 16:36:43 -0800207
Yangster-mac94e197c2018-01-02 16:03:03 -0800208 unordered_map<int64_t, int> trackerNameIndexMap;
209 trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
210 trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
Yao Chen967b2052017-11-07 16:36:43 -0800211
Yangster-mac94e197c2018-01-02 16:03:03 -0800212 SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"),
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800213 0 /*condition tracker index*/, simplePredicate,
Yao Chenb3561512017-11-21 18:07:17 -0800214 trackerNameIndexMap);
Yangster13fb7e42018-03-07 17:30:49 -0800215 EXPECT_FALSE(conditionTracker.isSliced());
Yao Chen967b2052017-11-07 16:36:43 -0800216
tsaichristine7747d372020-02-28 17:36:59 -0800217 // This event is not accessed in this test besides dimensions which is why this is okay.
218 // This is technically an invalid LogEvent because we do not call parseBuffer.
219 LogEvent event(/*uid=*/0, /*pid=*/0);
Yao Chen967b2052017-11-07 16:36:43 -0800220
221 // one matched start
222 vector<MatchingState> matcherState;
223 matcherState.push_back(MatchingState::kMatched);
224 matcherState.push_back(MatchingState::kNotMatched);
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800225 vector<sp<ConditionTracker>> allPredicates;
Yao Chen967b2052017-11-07 16:36:43 -0800226 vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
227 vector<bool> changedCache(1, false);
228
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800229 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
Yao Chen967b2052017-11-07 16:36:43 -0800230 changedCache);
231
232 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
233 EXPECT_TRUE(changedCache[0]);
234
235 // prepare for another matched start.
236 matcherState.clear();
237 matcherState.push_back(MatchingState::kMatched);
238 matcherState.push_back(MatchingState::kNotMatched);
239 conditionCache[0] = ConditionState::kNotEvaluated;
240 changedCache[0] = false;
241
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800242 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
Yao Chen967b2052017-11-07 16:36:43 -0800243 changedCache);
244
245 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
246 EXPECT_FALSE(changedCache[0]);
247
248 // ONE MATCHED STOP
249 matcherState.clear();
250 matcherState.push_back(MatchingState::kNotMatched);
251 matcherState.push_back(MatchingState::kMatched);
252 conditionCache[0] = ConditionState::kNotEvaluated;
253 changedCache[0] = false;
254
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800255 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
Yao Chen967b2052017-11-07 16:36:43 -0800256 changedCache);
257 // result should still be true
258 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
259 EXPECT_FALSE(changedCache[0]);
260
261 // ANOTHER MATCHED STOP
262 matcherState.clear();
263 matcherState.push_back(MatchingState::kNotMatched);
264 matcherState.push_back(MatchingState::kMatched);
265 conditionCache[0] = ConditionState::kNotEvaluated;
266 changedCache[0] = false;
267
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800268 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
Yao Chen967b2052017-11-07 16:36:43 -0800269 changedCache);
Yao Chen967b2052017-11-07 16:36:43 -0800270 EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
271 EXPECT_TRUE(changedCache[0]);
272}
273
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800274TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
275 std::vector<sp<ConditionTracker>> allConditions;
276 for (Position position : {Position::FIRST, Position::LAST}) {
277 SimplePredicate simplePredicate = getWakeLockHeldCondition(
278 true /*nesting*/, true /*default to false*/, true /*output slice by uid*/,
279 position);
280 string conditionName = "WL_HELD_BY_UID2";
281
282 unordered_map<int64_t, int> trackerNameIndexMap;
283 trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
284 trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
285 trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
286
287 SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
288 0 /*condition tracker index*/, simplePredicate,
289 trackerNameIndexMap);
290
291 std::vector<int> uids = {111, 222, 333};
292
tsaichristine7747d372020-02-28 17:36:59 -0800293 LogEvent event1(/*uid=*/0, /*pid=*/0);
294 makeWakeLockEvent(&event1, /*atomId=*/1, /*timestamp=*/0, uids, "wl1", /*acquire=*/1);
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800295
296 // one matched start
297 vector<MatchingState> matcherState;
298 matcherState.push_back(MatchingState::kMatched);
299 matcherState.push_back(MatchingState::kNotMatched);
300 matcherState.push_back(MatchingState::kNotMatched);
301 vector<sp<ConditionTracker>> allPredicates;
302 vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
303 vector<bool> changedCache(1, false);
304
tsaichristine7747d372020-02-28 17:36:59 -0800305 conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800306 changedCache);
307
308 if (position == Position::FIRST || position == Position::LAST) {
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700309 ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800310 } else {
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700311 ASSERT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800312 }
313 EXPECT_TRUE(changedCache[0]);
314 if (position == Position::FIRST || position == Position::LAST) {
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700315 ASSERT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(), 1u);
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800316 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
317 } else {
318 EXPECT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(),
319 uids.size());
320 }
321
322 // Now test query
323 const auto queryKey = getWakeLockQueryKey(position, uids, conditionName);
324 conditionCache[0] = ConditionState::kNotEvaluated;
325
326 conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
327 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
328
329 // another wake lock acquired by this uid
tsaichristine7747d372020-02-28 17:36:59 -0800330 LogEvent event2(/*uid=*/0, /*pid=*/0);
Ruchir Rastogi2250fa12020-02-27 16:33:39 -0800331 makeWakeLockEvent(&event2, /*atomId=*/1, /*timestamp=*/0, uids, "wl2", /*acquire=*/1);
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800332 matcherState.clear();
333 matcherState.push_back(MatchingState::kMatched);
334 matcherState.push_back(MatchingState::kNotMatched);
335 conditionCache[0] = ConditionState::kNotEvaluated;
336 changedCache[0] = false;
337 conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
338 changedCache);
339 EXPECT_FALSE(changedCache[0]);
340 if (position == Position::FIRST || position == Position::LAST) {
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700341 ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800342 } else {
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700343 ASSERT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800344 }
345 EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
346 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
347
348
349 // wake lock 1 release
tsaichristine7747d372020-02-28 17:36:59 -0800350 LogEvent event3(/*uid=*/0, /*pid=*/0);
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800351 makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids, "wl1", /*acquire=*/0);
352 matcherState.clear();
353 matcherState.push_back(MatchingState::kNotMatched);
354 matcherState.push_back(MatchingState::kMatched);
355 conditionCache[0] = ConditionState::kNotEvaluated;
356 changedCache[0] = false;
357 conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
358 changedCache);
359 // nothing changes, because wake lock 2 is still held for this uid
360 EXPECT_FALSE(changedCache[0]);
361 if (position == Position::FIRST || position == Position::LAST) {
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700362 ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800363 } else {
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700364 ASSERT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800365 }
366 EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
367 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
368
tsaichristine7747d372020-02-28 17:36:59 -0800369 LogEvent event4(/*uid=*/0, /*pid=*/0);
Ruchir Rastogi2250fa12020-02-27 16:33:39 -0800370 makeWakeLockEvent(&event4, /*atomId=*/1, /*timestamp=*/0, uids, "wl2", /*acquire=*/0);
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800371 matcherState.clear();
372 matcherState.push_back(MatchingState::kNotMatched);
373 matcherState.push_back(MatchingState::kMatched);
374 conditionCache[0] = ConditionState::kNotEvaluated;
375 changedCache[0] = false;
376 conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache,
377 changedCache);
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700378 ASSERT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800379 EXPECT_TRUE(changedCache[0]);
380 if (position == Position::FIRST || position == Position::LAST) {
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700381 ASSERT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(), 1u);
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800382 EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
383 } else {
384 EXPECT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(),
385 uids.size());
386 }
387
388 // query again
389 conditionCache[0] = ConditionState::kNotEvaluated;
390 conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
391 EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
392 }
393
394}
395
tsaichristine7747d372020-02-28 17:36:59 -0800396TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) {
397 std::vector<sp<ConditionTracker>> allConditions;
398
399 SimplePredicate simplePredicate =
400 getWakeLockHeldCondition(true /*nesting*/, true /*default to false*/,
401 false /*slice output by uid*/, Position::ANY /* position */);
402 string conditionName = "WL_HELD";
403
404 unordered_map<int64_t, int> trackerNameIndexMap;
405 trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
406 trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
407 trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
408
409 SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
410 0 /*condition tracker index*/, simplePredicate,
411 trackerNameIndexMap);
412
413 EXPECT_FALSE(conditionTracker.isSliced());
414
415 std::vector<int> uids1 = {111, 1111, 11111};
416 string uid1_wl1 = "wl1_1";
417 std::vector<int> uids2 = {222, 2222, 22222};
418 string uid2_wl1 = "wl2_1";
419
420 LogEvent event1(/*uid=*/0, /*pid=*/0);
421 makeWakeLockEvent(&event1, /*atomId=*/1, /*timestamp=*/0, uids1, uid1_wl1, /*acquire=*/1);
422
423 // one matched start for uid1
424 vector<MatchingState> matcherState;
425 matcherState.push_back(MatchingState::kMatched);
426 matcherState.push_back(MatchingState::kNotMatched);
427 matcherState.push_back(MatchingState::kNotMatched);
428 vector<sp<ConditionTracker>> allPredicates;
429 vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
430 vector<bool> changedCache(1, false);
431
432 conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
433 changedCache);
434
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700435 ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
tsaichristine7747d372020-02-28 17:36:59 -0800436 EXPECT_TRUE(changedCache[0]);
437
438 // Now test query
439 ConditionKey queryKey;
440 conditionCache[0] = ConditionState::kNotEvaluated;
441
442 conditionTracker.isConditionMet(queryKey, allPredicates, true, conditionCache);
443 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
444
445 // another wake lock acquired by this uid
446 LogEvent event2(/*uid=*/0, /*pid=*/0);
447 makeWakeLockEvent(&event2, /*atomId=*/1, /*timestamp=*/0, uids2, uid2_wl1, /*acquire=*/1);
448
449 matcherState.clear();
450 matcherState.push_back(MatchingState::kMatched);
451 matcherState.push_back(MatchingState::kNotMatched);
452 conditionCache[0] = ConditionState::kNotEvaluated;
453 changedCache[0] = false;
454 conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
455 changedCache);
456 EXPECT_FALSE(changedCache[0]);
457
458 // uid1 wake lock 1 release
459 LogEvent event3(/*uid=*/0, /*pid=*/0);
460 makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids1, uid1_wl1,
461 /*release=*/0); // now release it.
462
463 matcherState.clear();
464 matcherState.push_back(MatchingState::kNotMatched);
465 matcherState.push_back(MatchingState::kMatched);
466 conditionCache[0] = ConditionState::kNotEvaluated;
467 changedCache[0] = false;
468 conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
469 changedCache);
470 // nothing changes, because uid2 is still holding wl.
471 EXPECT_FALSE(changedCache[0]);
472
473 LogEvent event4(/*uid=*/0, /*pid=*/0);
474 makeWakeLockEvent(&event4, /*atomId=*/1, /*timestamp=*/0, uids2, uid2_wl1,
475 /*acquire=*/0); // now release it.
476 matcherState.clear();
477 matcherState.push_back(MatchingState::kNotMatched);
478 matcherState.push_back(MatchingState::kMatched);
479 conditionCache[0] = ConditionState::kNotEvaluated;
480 changedCache[0] = false;
481 conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache,
482 changedCache);
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700483 ASSERT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
tsaichristine7747d372020-02-28 17:36:59 -0800484 EXPECT_TRUE(changedCache[0]);
485
486 // query again
487 conditionCache[0] = ConditionState::kNotEvaluated;
488 conditionTracker.isConditionMet(queryKey, allPredicates, true, conditionCache);
489 EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
490}
491
492TEST(SimpleConditionTrackerTest, TestStopAll) {
493 std::vector<sp<ConditionTracker>> allConditions;
494 for (Position position : {Position::FIRST, Position::LAST}) {
495 SimplePredicate simplePredicate =
496 getWakeLockHeldCondition(true /*nesting*/, true /*default to false*/,
497 true /*output slice by uid*/, position);
498 string conditionName = "WL_HELD_BY_UID3";
499
500 unordered_map<int64_t, int> trackerNameIndexMap;
501 trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
502 trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
503 trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
504
505 SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
506 0 /*condition tracker index*/, simplePredicate,
507 trackerNameIndexMap);
508
509 std::vector<int> uids1 = {111, 1111, 11111};
510 std::vector<int> uids2 = {222, 2222, 22222};
511
512 LogEvent event1(/*uid=*/0, /*pid=*/0);
513 makeWakeLockEvent(&event1, /*atomId=*/1, /*timestamp=*/0, uids1, "wl1", /*acquire=*/1);
514
515 // one matched start
516 vector<MatchingState> matcherState;
517 matcherState.push_back(MatchingState::kMatched);
518 matcherState.push_back(MatchingState::kNotMatched);
519 matcherState.push_back(MatchingState::kNotMatched);
520 vector<sp<ConditionTracker>> allPredicates;
521 vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
522 vector<bool> changedCache(1, false);
523
524 conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
525 changedCache);
526 if (position == Position::FIRST || position == Position::LAST) {
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700527 ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
tsaichristine7747d372020-02-28 17:36:59 -0800528 } else {
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700529 ASSERT_EQ(uids1.size(), conditionTracker.mSlicedConditionState.size());
tsaichristine7747d372020-02-28 17:36:59 -0800530 }
531 EXPECT_TRUE(changedCache[0]);
532 {
533 if (position == Position::FIRST || position == Position::LAST) {
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700534 ASSERT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
tsaichristine7747d372020-02-28 17:36:59 -0800535 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
536 } else {
537 EXPECT_EQ(uids1.size(),
538 conditionTracker.getChangedToTrueDimensions(allConditions)->size());
539 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
540 }
541 }
542
543 // Now test query
544 const auto queryKey = getWakeLockQueryKey(position, uids1, conditionName);
545 conditionCache[0] = ConditionState::kNotEvaluated;
546
547 conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
548 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
549
550 // another wake lock acquired by uid2
551 LogEvent event2(/*uid=*/0, /*pid=*/0);
552 makeWakeLockEvent(&event2, /*atomId=*/1, /*timestamp=*/0, uids2, "wl2", /*acquire=*/1);
553
554 matcherState.clear();
555 matcherState.push_back(MatchingState::kMatched);
556 matcherState.push_back(MatchingState::kNotMatched);
557 matcherState.push_back(MatchingState::kNotMatched);
558 conditionCache[0] = ConditionState::kNotEvaluated;
559 changedCache[0] = false;
560 conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
561 changedCache);
562 if (position == Position::FIRST || position == Position::LAST) {
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700563 ASSERT_EQ(2UL, conditionTracker.mSlicedConditionState.size());
tsaichristine7747d372020-02-28 17:36:59 -0800564 } else {
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700565 ASSERT_EQ(uids1.size() + uids2.size(), conditionTracker.mSlicedConditionState.size());
tsaichristine7747d372020-02-28 17:36:59 -0800566 }
567 EXPECT_TRUE(changedCache[0]);
568 {
569 if (position == Position::FIRST || position == Position::LAST) {
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700570 ASSERT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
tsaichristine7747d372020-02-28 17:36:59 -0800571 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
572 } else {
573 EXPECT_EQ(uids2.size(),
574 conditionTracker.getChangedToTrueDimensions(allConditions)->size());
575 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
576 }
577 }
578
579 // TEST QUERY
580 const auto queryKey2 = getWakeLockQueryKey(position, uids2, conditionName);
581 conditionCache[0] = ConditionState::kNotEvaluated;
582 conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
583
584 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
585
586 // stop all event
587 LogEvent event3(/*uid=*/0, /*pid=*/0);
588 makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids2, "wl2", /*acquire=*/1);
589
590 matcherState.clear();
591 matcherState.push_back(MatchingState::kNotMatched);
592 matcherState.push_back(MatchingState::kNotMatched);
593 matcherState.push_back(MatchingState::kMatched);
594
595 conditionCache[0] = ConditionState::kNotEvaluated;
596 changedCache[0] = false;
597 conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
598 changedCache);
599 EXPECT_TRUE(changedCache[0]);
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700600 ASSERT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
tsaichristine7747d372020-02-28 17:36:59 -0800601 {
602 if (position == Position::FIRST || position == Position::LAST) {
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700603 ASSERT_EQ(2UL, conditionTracker.getChangedToFalseDimensions(allConditions)->size());
tsaichristine7747d372020-02-28 17:36:59 -0800604 EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
605 } else {
606 EXPECT_EQ(uids1.size() + uids2.size(),
607 conditionTracker.getChangedToFalseDimensions(allConditions)->size());
608 EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
609 }
610 }
611
612 // TEST QUERY
613 const auto queryKey3 = getWakeLockQueryKey(position, uids1, conditionName);
614 conditionCache[0] = ConditionState::kNotEvaluated;
615 conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
616 EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
617
618 // TEST QUERY
619 const auto queryKey4 = getWakeLockQueryKey(position, uids2, conditionName);
620 conditionCache[0] = ConditionState::kNotEvaluated;
621 conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
622 EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
623 }
624}
Yao Chen967b2052017-11-07 16:36:43 -0800625
626} // namespace statsd
627} // namespace os
628} // namespace android
629#else
630GTEST_LOG_(INFO) << "This test does nothing.\n";
631#endif