blob: 609324e91daa200678a89985f12caf687b174fc1 [file] [log] [blame]
Yangster-mace2cd6d52017-11-09 20:38:30 -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.
14
Yao Chend5aa01b32017-12-19 16:46:36 -080015#include "src/metrics/GaugeMetricProducer.h"
Yangster-mace2cd6d52017-11-09 20:38:30 -080016
17#include <gmock/gmock.h>
18#include <gtest/gtest.h>
Bookatz6bf98252018-03-14 10:44:24 -070019#include <math.h>
Yangster-mace2cd6d52017-11-09 20:38:30 -080020#include <stdio.h>
tsaichristineb87ca152019-12-09 15:19:41 -080021
Yangster-mace2cd6d52017-11-09 20:38:30 -080022#include <vector>
23
tsaichristineb87ca152019-12-09 15:19:41 -080024#include "logd/LogEvent.h"
25#include "metrics_test_helper.h"
26#include "src/matchers/SimpleLogMatchingTracker.h"
27#include "src/metrics/MetricProducer.h"
28#include "src/stats_log_util.h"
29#include "tests/statsd_test_util.h"
30
Yangster-mace2cd6d52017-11-09 20:38:30 -080031using namespace testing;
32using android::sp;
33using std::set;
34using std::unordered_map;
35using std::vector;
Chenjie Yud9dfda72017-12-11 17:41:20 -080036using std::make_shared;
Yangster-mace2cd6d52017-11-09 20:38:30 -080037
38#ifdef __ANDROID__
39
40namespace android {
41namespace os {
42namespace statsd {
43
Yangster-mac94e197c2018-01-02 16:03:03 -080044const ConfigKey kConfigKey(0, 12345);
Chenjie Yud9dfda72017-12-11 17:41:20 -080045const int tagId = 1;
Yangster-mac94e197c2018-01-02 16:03:03 -080046const int64_t metricId = 123;
Yangster-mac32f07af2018-10-13 17:08:11 -070047const int64_t atomMatcherId = 678;
48const int logEventMatcherIndex = 0;
Yangster-macbe10ddf2018-03-13 15:39:51 -070049const int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
Yangster-macb8144812018-01-04 10:56:23 -080050const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
Chenjie Yud9dfda72017-12-11 17:41:20 -080051const int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
52const int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
53const int64_t bucket4StartTimeNs = bucketStartTimeNs + 3 * bucketSizeNs;
Yangster-macb142cc82018-03-30 15:22:08 -070054const int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
Bookatz8f2f3d82017-12-07 13:53:21 -080055
Chenjie Yue1361ed2018-07-23 17:33:09 -070056/*
57 * Tests that the first bucket works correctly
58 */
59TEST(GaugeMetricProducerTest, TestFirstBucket) {
60 GaugeMetric metric;
61 metric.set_id(metricId);
62 metric.set_bucket(ONE_MINUTE);
63 metric.mutable_gauge_fields_filter()->set_include_all(false);
64 auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
65 gaugeFieldMatcher->set_field(tagId);
66 gaugeFieldMatcher->add_child()->set_field(1);
67 gaugeFieldMatcher->add_child()->set_field(3);
68
69 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Yangster-mac32f07af2018-10-13 17:08:11 -070070
71 UidMap uidMap;
72 SimpleAtomMatcher atomMatcher;
73 atomMatcher.set_atom_id(tagId);
74 sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
75 new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
76
Chenjie Yue1361ed2018-07-23 17:33:09 -070077 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
78
79 // statsd started long ago.
80 // The metric starts in the middle of the bucket
81 GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
Yangster-mac32f07af2018-10-13 17:08:11 -070082 logEventMatcherIndex, eventMatcherWizard,
Chenjie Yu88588972018-08-03 09:49:22 -070083 -1, -1, tagId, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2,
84 pullerManager);
Chenjie Yue1361ed2018-07-23 17:33:09 -070085
86 EXPECT_EQ(600500000000, gaugeProducer.mCurrentBucketStartTimeNs);
87 EXPECT_EQ(10, gaugeProducer.mCurrentBucketNum);
88 EXPECT_EQ(660000000005, gaugeProducer.getCurrentBucketEndTimeNs());
89}
90
Jeffrey Huang1e4368a2020-02-18 12:28:52 -080091// TODO(b/149590301): Update these tests to use new socket schema.
92//TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) {
93// GaugeMetric metric;
94// metric.set_id(metricId);
95// metric.set_bucket(ONE_MINUTE);
96// metric.mutable_gauge_fields_filter()->set_include_all(false);
97// metric.set_max_pull_delay_sec(INT_MAX);
98// auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
99// gaugeFieldMatcher->set_field(tagId);
100// gaugeFieldMatcher->add_child()->set_field(1);
101// gaugeFieldMatcher->add_child()->set_field(3);
102//
103// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
104//
105// UidMap uidMap;
106// SimpleAtomMatcher atomMatcher;
107// atomMatcher.set_atom_id(tagId);
108// sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
109// new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
110//
111// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
112// EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
113// EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
114// EXPECT_CALL(*pullerManager, Pull(tagId, _))
115// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
116// data->clear();
117// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
118// event->write(3);
119// event->write("some value");
120// event->write(11);
121// event->init();
122// data->push_back(event);
123// return true;
124// }));
125//
126// GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
127// logEventMatcherIndex, eventMatcherWizard,
128// tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
129// pullerManager);
130//
131// vector<shared_ptr<LogEvent>> allData;
132// allData.clear();
133// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
134// event->write(10);
135// event->write("some value");
136// event->write(11);
137// event->init();
138// allData.push_back(event);
139//
140// gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
141// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
142// auto it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
143// EXPECT_EQ(INT, it->mValue.getType());
144// EXPECT_EQ(10, it->mValue.int_value);
145// it++;
146// EXPECT_EQ(11, it->mValue.int_value);
147// EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
148// EXPECT_EQ(3, gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms
149// .front().mFields->begin()->mValue.int_value);
150//
151// allData.clear();
152// std::shared_ptr<LogEvent> event2 = std::make_shared<LogEvent>(tagId, bucket3StartTimeNs + 10);
153// event2->write(24);
154// event2->write("some value");
155// event2->write(25);
156// event2->init();
157// allData.push_back(event2);
158// gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
159// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
160// it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
161// EXPECT_EQ(INT, it->mValue.getType());
162// EXPECT_EQ(24, it->mValue.int_value);
163// it++;
164// EXPECT_EQ(INT, it->mValue.getType());
165// EXPECT_EQ(25, it->mValue.int_value);
166// // One dimension.
167// EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
168// EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
169// it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
170// EXPECT_EQ(INT, it->mValue.getType());
171// EXPECT_EQ(10L, it->mValue.int_value);
172// it++;
173// EXPECT_EQ(INT, it->mValue.getType());
174// EXPECT_EQ(11L, it->mValue.int_value);
175//
176// gaugeProducer.flushIfNeededLocked(bucket4StartTimeNs);
177// EXPECT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
178// // One dimension.
179// EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
180// EXPECT_EQ(3UL, gaugeProducer.mPastBuckets.begin()->second.size());
181// it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
182// EXPECT_EQ(INT, it->mValue.getType());
183// EXPECT_EQ(24L, it->mValue.int_value);
184// it++;
185// EXPECT_EQ(INT, it->mValue.getType());
186// EXPECT_EQ(25L, it->mValue.int_value);
187//}
188//
189//TEST(GaugeMetricProducerTest, TestPushedEventsWithUpgrade) {
190// sp<AlarmMonitor> alarmMonitor;
191// GaugeMetric metric;
192// metric.set_id(metricId);
193// metric.set_bucket(ONE_MINUTE);
194// metric.mutable_gauge_fields_filter()->set_include_all(true);
195//
196// Alert alert;
197// alert.set_id(101);
198// alert.set_metric_id(metricId);
199// alert.set_trigger_if_sum_gt(25);
200// alert.set_num_buckets(100);
201// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
202// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
203//
204// UidMap uidMap;
205// SimpleAtomMatcher atomMatcher;
206// atomMatcher.set_atom_id(tagId);
207// sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
208// new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
209//
210// GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
211// logEventMatcherIndex, eventMatcherWizard,
212// -1 /* -1 means no pulling */, -1, tagId, bucketStartTimeNs,
213// bucketStartTimeNs, pullerManager);
214//
215// sp<AnomalyTracker> anomalyTracker = gaugeProducer.addAnomalyTracker(alert, alarmMonitor);
216// EXPECT_TRUE(anomalyTracker != nullptr);
217//
218// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
219// event1->write(1);
220// event1->write(10);
221// event1->init();
222// gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
223// EXPECT_EQ(1UL, (*gaugeProducer.mCurrentSlicedBucket).count(DEFAULT_METRIC_DIMENSION_KEY));
224//
225// gaugeProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
226// EXPECT_EQ(0UL, (*gaugeProducer.mCurrentSlicedBucket).count(DEFAULT_METRIC_DIMENSION_KEY));
227// EXPECT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
228// EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
229// EXPECT_EQ(eventUpgradeTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
230// // Partial buckets are not sent to anomaly tracker.
231// EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
232//
233// // Create an event in the same partial bucket.
234// shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 59 * NS_PER_SEC);
235// event2->write(1);
236// event2->write(10);
237// event2->init();
238// gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
239// EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
240// EXPECT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
241// EXPECT_EQ((int64_t)eventUpgradeTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
242// // Partial buckets are not sent to anomaly tracker.
243// EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
244//
245// // Next event should trigger creation of new bucket and send previous full bucket to anomaly
246// // tracker.
247// shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 65 * NS_PER_SEC);
248// event3->write(1);
249// event3->write(10);
250// event3->init();
251// gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
252// EXPECT_EQ(1L, gaugeProducer.mCurrentBucketNum);
253// EXPECT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
254// EXPECT_EQ((int64_t)bucketStartTimeNs + bucketSizeNs, gaugeProducer.mCurrentBucketStartTimeNs);
255// EXPECT_EQ(1, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
256//
257// // Next event should trigger creation of new bucket.
258// shared_ptr<LogEvent> event4 =
259// make_shared<LogEvent>(tagId, bucketStartTimeNs + 125 * NS_PER_SEC);
260// event4->write(1);
261// event4->write(10);
262// event4->init();
263// gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
264// EXPECT_EQ(2L, gaugeProducer.mCurrentBucketNum);
265// EXPECT_EQ(3UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
266// EXPECT_EQ(2, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
267//}
268//
269//TEST(GaugeMetricProducerTest, TestPulledWithUpgrade) {
270// GaugeMetric metric;
271// metric.set_id(metricId);
272// metric.set_bucket(ONE_MINUTE);
273// metric.set_max_pull_delay_sec(INT_MAX);
274// auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
275// gaugeFieldMatcher->set_field(tagId);
276// gaugeFieldMatcher->add_child()->set_field(2);
277//
278// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
279//
280// UidMap uidMap;
281// SimpleAtomMatcher atomMatcher;
282// atomMatcher.set_atom_id(tagId);
283// sp<EventMatcherWizard> eventMatcherWizard =
284// new EventMatcherWizard({new SimpleLogMatchingTracker(
285// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
286//
287// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
288// EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
289// EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
290// EXPECT_CALL(*pullerManager, Pull(tagId, _))
291// .WillOnce(Return(false))
292// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
293// data->clear();
294// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, eventUpgradeTimeNs);
295// event->write("some value");
296// event->write(2);
297// event->init();
298// data->push_back(event);
299// return true;
300// }));
301//
302// GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
303// logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
304// bucketStartTimeNs, bucketStartTimeNs, pullerManager);
305//
306// vector<shared_ptr<LogEvent>> allData;
307// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
308// event->write("some value");
309// event->write(1);
310// event->init();
311// allData.push_back(event);
312// gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
313// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
314// EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
315// ->second.front()
316// .mFields->begin()
317// ->mValue.int_value);
318//
319// gaugeProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
320// EXPECT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
321// EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
322// EXPECT_EQ((int64_t)eventUpgradeTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
323// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
324// EXPECT_EQ(2, gaugeProducer.mCurrentSlicedBucket->begin()
325// ->second.front()
326// .mFields->begin()
327// ->mValue.int_value);
328//
329// allData.clear();
330// event = make_shared<LogEvent>(tagId, bucketStartTimeNs + bucketSizeNs + 1);
331// event->write("some value");
332// event->write(3);
333// event->init();
334// allData.push_back(event);
335// gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + bucketSizeNs);
336// EXPECT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
337// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
338// EXPECT_EQ(3, gaugeProducer.mCurrentSlicedBucket->begin()
339// ->second.front()
340// .mFields->begin()
341// ->mValue.int_value);
342//}
343//
344//TEST(GaugeMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
345// GaugeMetric metric;
346// metric.set_id(metricId);
347// metric.set_bucket(ONE_MINUTE);
348// metric.set_max_pull_delay_sec(INT_MAX);
349// metric.set_split_bucket_for_app_upgrade(false);
350// auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
351// gaugeFieldMatcher->set_field(tagId);
352// gaugeFieldMatcher->add_child()->set_field(2);
353//
354// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
355//
356// UidMap uidMap;
357// SimpleAtomMatcher atomMatcher;
358// atomMatcher.set_atom_id(tagId);
359// sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
360// new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
361//
362// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
363// EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
364// EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
365// EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(false));
366//
367// GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
368// logEventMatcherIndex, eventMatcherWizard,
369// tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
370// pullerManager);
371//
372// vector<shared_ptr<LogEvent>> allData;
373// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
374// event->write("some value");
375// event->write(1);
376// event->init();
377// allData.push_back(event);
378// gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
379// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
380// EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
381// ->second.front()
382// .mFields->begin()
383// ->mValue.int_value);
384//
385// gaugeProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
386// EXPECT_EQ(0UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
387// EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
388// EXPECT_EQ(bucketStartTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
389// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
390// EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
391// ->second.front()
392// .mFields->begin()
393// ->mValue.int_value);
394//}
395//
396//TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition) {
397// GaugeMetric metric;
398// metric.set_id(metricId);
399// metric.set_bucket(ONE_MINUTE);
400// metric.set_max_pull_delay_sec(INT_MAX);
401// auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
402// gaugeFieldMatcher->set_field(tagId);
403// gaugeFieldMatcher->add_child()->set_field(2);
404// metric.set_condition(StringToId("SCREEN_ON"));
405//
406// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
407//
408// UidMap uidMap;
409// SimpleAtomMatcher atomMatcher;
410// atomMatcher.set_atom_id(tagId);
411// sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
412// new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
413//
414// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
415// EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
416// EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
417// EXPECT_CALL(*pullerManager, Pull(tagId, _))
418// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
419// data->clear();
420// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
421// event->write("some value");
422// event->write(100);
423// event->init();
424// data->push_back(event);
425// return true;
426// }));
427//
428// GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard,
429// logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
430// bucketStartTimeNs, bucketStartTimeNs, pullerManager);
431//
432// gaugeProducer.onConditionChanged(true, bucketStartTimeNs + 8);
433// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
434// EXPECT_EQ(100, gaugeProducer.mCurrentSlicedBucket->begin()
435// ->second.front()
436// .mFields->begin()
437// ->mValue.int_value);
438// EXPECT_EQ(0UL, gaugeProducer.mPastBuckets.size());
439//
440// vector<shared_ptr<LogEvent>> allData;
441// allData.clear();
442// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
443// event->write("some value");
444// event->write(110);
445// event->init();
446// allData.push_back(event);
447// gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
448//
449// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
450// EXPECT_EQ(110, gaugeProducer.mCurrentSlicedBucket->begin()
451// ->second.front()
452// .mFields->begin()
453// ->mValue.int_value);
454// EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
455// EXPECT_EQ(100, gaugeProducer.mPastBuckets.begin()
456// ->second.back()
457// .mGaugeAtoms.front()
458// .mFields->begin()
459// ->mValue.int_value);
460//
461// gaugeProducer.onConditionChanged(false, bucket2StartTimeNs + 10);
462// gaugeProducer.flushIfNeededLocked(bucket3StartTimeNs + 10);
463// EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
464// EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
465// EXPECT_EQ(110L, gaugeProducer.mPastBuckets.begin()
466// ->second.back()
467// .mGaugeAtoms.front()
468// .mFields->begin()
469// ->mValue.int_value);
470//}
471//
472//TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) {
473// const int conditionTag = 65;
474// GaugeMetric metric;
475// metric.set_id(1111111);
476// metric.set_bucket(ONE_MINUTE);
477// metric.mutable_gauge_fields_filter()->set_include_all(true);
478// metric.set_condition(StringToId("APP_DIED"));
479// metric.set_max_pull_delay_sec(INT_MAX);
480// auto dim = metric.mutable_dimensions_in_what();
481// dim->set_field(tagId);
482// dim->add_child()->set_field(1);
483//
484// UidMap uidMap;
485// SimpleAtomMatcher atomMatcher;
486// atomMatcher.set_atom_id(tagId);
487// sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
488// new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
489//
490// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
491// EXPECT_CALL(*wizard, query(_, _, _))
492// .WillRepeatedly(
493// Invoke([](const int conditionIndex, const ConditionKey& conditionParameters,
494// const bool isPartialLink) {
495// int pos[] = {1, 0, 0};
496// Field f(conditionTag, pos, 0);
497// HashableDimensionKey key;
498// key.mutableValues()->emplace_back(f, Value((int32_t)1000000));
499//
500// return ConditionState::kTrue;
501// }));
502//
503// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
504// EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
505// EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
506// EXPECT_CALL(*pullerManager, Pull(tagId, _))
507// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
508// data->clear();
509// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
510// event->write(1000);
511// event->write(100);
512// event->init();
513// data->push_back(event);
514// return true;
515// }));
516//
517// GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard,
518// logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
519// bucketStartTimeNs, bucketStartTimeNs, pullerManager);
520//
521// gaugeProducer.onSlicedConditionMayChange(true, bucketStartTimeNs + 8);
522//
523// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
524// const auto& key = gaugeProducer.mCurrentSlicedBucket->begin()->first;
525// EXPECT_EQ(1UL, key.getDimensionKeyInWhat().getValues().size());
526// EXPECT_EQ(1000, key.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
527//
528// EXPECT_EQ(0UL, gaugeProducer.mPastBuckets.size());
529//
530// vector<shared_ptr<LogEvent>> allData;
531// allData.clear();
532// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
533// event->write(1000);
534// event->write(110);
535// event->init();
536// allData.push_back(event);
537// gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
538//
539// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
540// EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
541//}
542//
543//TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) {
544// sp<AlarmMonitor> alarmMonitor;
545// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
546//
547// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
548// EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
549// EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
550// EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(false));
551//
552// GaugeMetric metric;
553// metric.set_id(metricId);
554// metric.set_bucket(ONE_MINUTE);
555// metric.set_max_pull_delay_sec(INT_MAX);
556// auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
557// gaugeFieldMatcher->set_field(tagId);
558// gaugeFieldMatcher->add_child()->set_field(2);
559//
560// UidMap uidMap;
561// SimpleAtomMatcher atomMatcher;
562// atomMatcher.set_atom_id(tagId);
563// sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
564// new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
565//
566// GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
567// logEventMatcherIndex, eventMatcherWizard,
568// tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
569// pullerManager);
570//
571// Alert alert;
572// alert.set_id(101);
573// alert.set_metric_id(metricId);
574// alert.set_trigger_if_sum_gt(25);
575// alert.set_num_buckets(2);
576// const int32_t refPeriodSec = 60;
577// alert.set_refractory_period_secs(refPeriodSec);
578// sp<AnomalyTracker> anomalyTracker = gaugeProducer.addAnomalyTracker(alert, alarmMonitor);
579//
580// int tagId = 1;
581// std::shared_ptr<LogEvent> event1 = std::make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
582// event1->write("some value");
583// event1->write(13);
584// event1->init();
585//
586// gaugeProducer.onDataPulled({event1}, /** succeed */ true, bucketStartTimeNs);
587// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
588// EXPECT_EQ(13L, gaugeProducer.mCurrentSlicedBucket->begin()
589// ->second.front()
590// .mFields->begin()
591// ->mValue.int_value);
592// EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
593//
594// std::shared_ptr<LogEvent> event2 =
595// std::make_shared<LogEvent>(tagId, bucketStartTimeNs + bucketSizeNs + 20);
596// event2->write("some value");
597// event2->write(15);
598// event2->init();
599//
600// gaugeProducer.onDataPulled({event2}, /** succeed */ true, bucketStartTimeNs + bucketSizeNs);
601// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
602// EXPECT_EQ(15L, gaugeProducer.mCurrentSlicedBucket->begin()
603// ->second.front()
604// .mFields->begin()
605// ->mValue.int_value);
606// EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
607// std::ceil(1.0 * event2->GetElapsedTimestampNs() / NS_PER_SEC) + refPeriodSec);
608//
609// std::shared_ptr<LogEvent> event3 =
610// std::make_shared<LogEvent>(tagId, bucketStartTimeNs + 2 * bucketSizeNs + 10);
611// event3->write("some value");
612// event3->write(26);
613// event3->init();
614//
615// gaugeProducer.onDataPulled({event3}, /** succeed */ true, bucket2StartTimeNs + 2 * bucketSizeNs);
616// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
617// EXPECT_EQ(26L, gaugeProducer.mCurrentSlicedBucket->begin()
618// ->second.front()
619// .mFields->begin()
620// ->mValue.int_value);
621// EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
622// std::ceil(1.0 * event2->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
623//
624// // The event4 does not have the gauge field. Thus the current bucket value is 0.
625// std::shared_ptr<LogEvent> event4 =
626// std::make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10);
627// event4->write("some value");
628// event4->init();
629// gaugeProducer.onDataPulled({event4}, /** succeed */ true, bucketStartTimeNs + 3 * bucketSizeNs);
630// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
631// EXPECT_TRUE(gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->empty());
632//}
633//
634//TEST(GaugeMetricProducerTest, TestPullOnTrigger) {
635// GaugeMetric metric;
636// metric.set_id(metricId);
637// metric.set_bucket(ONE_MINUTE);
638// metric.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES);
639// metric.mutable_gauge_fields_filter()->set_include_all(false);
640// metric.set_max_pull_delay_sec(INT_MAX);
641// auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
642// gaugeFieldMatcher->set_field(tagId);
643// gaugeFieldMatcher->add_child()->set_field(1);
644//
645// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
646//
647// UidMap uidMap;
648// SimpleAtomMatcher atomMatcher;
649// atomMatcher.set_atom_id(tagId);
650// sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
651// new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
652//
653// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
654// EXPECT_CALL(*pullerManager, Pull(tagId, _))
655// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
656// data->clear();
657// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
658// event->write(4);
659// event->init();
660// data->push_back(event);
661// return true;
662// }))
663// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
664// data->clear();
665// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
666// event->write(5);
667// event->init();
668// data->push_back(event);
669// return true;
670// }))
671// .WillOnce(Return(true));
672//
673// int triggerId = 5;
674// GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
675// logEventMatcherIndex, eventMatcherWizard,
676// tagId, triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
677// pullerManager);
678//
679// vector<shared_ptr<LogEvent>> allData;
680//
681// EXPECT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
682// LogEvent trigger(triggerId, bucketStartTimeNs + 10);
683// trigger.init();
684// gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
685// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
686// trigger.setElapsedTimestampNs(bucketStartTimeNs + 20);
687// gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
688// EXPECT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
689// trigger.setElapsedTimestampNs(bucket2StartTimeNs + 1);
690// gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
691//
692// EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
693// EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.size());
694// EXPECT_EQ(4, gaugeProducer.mPastBuckets.begin()
695// ->second.back()
696// .mGaugeAtoms[0]
697// .mFields->begin()
698// ->mValue.int_value);
699// EXPECT_EQ(5, gaugeProducer.mPastBuckets.begin()
700// ->second.back()
701// .mGaugeAtoms[1]
702// .mFields->begin()
703// ->mValue.int_value);
704//}
705//
706//TEST(GaugeMetricProducerTest, TestRemoveDimensionInOutput) {
707// GaugeMetric metric;
708// metric.set_id(metricId);
709// metric.set_bucket(ONE_MINUTE);
710// metric.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES);
711// metric.mutable_gauge_fields_filter()->set_include_all(true);
712// metric.set_max_pull_delay_sec(INT_MAX);
713// auto dimensionMatcher = metric.mutable_dimensions_in_what();
714// // use field 1 as dimension.
715// dimensionMatcher->set_field(tagId);
716// dimensionMatcher->add_child()->set_field(1);
717//
718// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
719//
720// UidMap uidMap;
721// SimpleAtomMatcher atomMatcher;
722// atomMatcher.set_atom_id(tagId);
723// sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
724// new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
725//
726// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
727// EXPECT_CALL(*pullerManager, Pull(tagId, _))
728// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
729// data->clear();
730// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3);
731// event->write(3);
732// event->write(4);
733// event->init();
734// data->push_back(event);
735// return true;
736// }))
737// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
738// data->clear();
739// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
740// event->write(4);
741// event->write(5);
742// event->init();
743// data->push_back(event);
744// return true;
745// }))
746// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
747// data->clear();
748// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
749// event->write(4);
750// event->write(6);
751// event->init();
752// data->push_back(event);
753// return true;
754// }))
755// .WillOnce(Return(true));
756//
757// int triggerId = 5;
758// GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
759// logEventMatcherIndex, eventMatcherWizard,
760// tagId, triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
761// pullerManager);
762//
763// vector<shared_ptr<LogEvent>> allData;
764//
765// LogEvent trigger(triggerId, bucketStartTimeNs + 3);
766// trigger.init();
767// gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
768// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
769// trigger.setElapsedTimestampNs(bucketStartTimeNs + 10);
770// gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
771// EXPECT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->size());
772// EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
773// trigger.setElapsedTimestampNs(bucketStartTimeNs + 20);
774// gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
775// EXPECT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
776// trigger.setElapsedTimestampNs(bucket2StartTimeNs + 1);
777// gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
778//
779// EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.size());
780// auto bucketIt = gaugeProducer.mPastBuckets.begin();
781// EXPECT_EQ(1UL, bucketIt->second.back().mGaugeAtoms.size());
782// EXPECT_EQ(3, bucketIt->first.getDimensionKeyInWhat().getValues().begin()->mValue.int_value);
783// EXPECT_EQ(4, bucketIt->second.back().mGaugeAtoms[0].mFields->begin()->mValue.int_value);
784// bucketIt++;
785// EXPECT_EQ(2UL, bucketIt->second.back().mGaugeAtoms.size());
786// EXPECT_EQ(4, bucketIt->first.getDimensionKeyInWhat().getValues().begin()->mValue.int_value);
787// EXPECT_EQ(5, bucketIt->second.back().mGaugeAtoms[0].mFields->begin()->mValue.int_value);
788// EXPECT_EQ(6, bucketIt->second.back().mGaugeAtoms[1].mFields->begin()->mValue.int_value);
789//}
790//
791///*
792// * Test that BUCKET_TOO_SMALL dump reason is logged when a flushed bucket size
793// * is smaller than the "min_bucket_size_nanos" specified in the metric config.
794// */
795//TEST(GaugeMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) {
796// GaugeMetric metric;
797// metric.set_id(metricId);
798// metric.set_bucket(FIVE_MINUTES);
799// metric.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES);
800// metric.set_min_bucket_size_nanos(10000000000); // 10 seconds
801//
802// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
803//
804// UidMap uidMap;
805// SimpleAtomMatcher atomMatcher;
806// atomMatcher.set_atom_id(tagId);
807// sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
808// new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
809//
810// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
811// EXPECT_CALL(*pullerManager, Pull(tagId, _))
812// // Bucket start.
813// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
814// data->clear();
815// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
816// event->write("field1");
817// event->write(10);
818// event->init();
819// data->push_back(event);
820// return true;
821// }));
822//
823// int triggerId = 5;
824// GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
825// logEventMatcherIndex, eventMatcherWizard,
826// tagId, triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
827// pullerManager);
828//
829// LogEvent trigger(triggerId, bucketStartTimeNs + 3);
830// trigger.init();
831// gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
832//
833// // Check dump report.
834// ProtoOutputStream output;
835// std::set<string> strSet;
836// gaugeProducer.onDumpReport(bucketStartTimeNs + 9000000, true /* include recent buckets */,
837// true, FAST /* dump_latency */, &strSet, &output);
838//
839// StatsLogReport report = outputStreamToProto(&output);
840// EXPECT_TRUE(report.has_gauge_metrics());
841// EXPECT_EQ(0, report.gauge_metrics().data_size());
842// EXPECT_EQ(1, report.gauge_metrics().skipped_size());
843//
844// EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
845// report.gauge_metrics().skipped(0).start_bucket_elapsed_millis());
846// EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 9000000),
847// report.gauge_metrics().skipped(0).end_bucket_elapsed_millis());
848// EXPECT_EQ(1, report.gauge_metrics().skipped(0).drop_event_size());
849//
850// auto dropEvent = report.gauge_metrics().skipped(0).drop_event(0);
851// EXPECT_EQ(BucketDropReason::BUCKET_TOO_SMALL, dropEvent.drop_reason());
852// EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 9000000), dropEvent.drop_time_millis());
853//}
tsaichristineb87ca152019-12-09 15:19:41 -0800854
Yangster-mace2cd6d52017-11-09 20:38:30 -0800855} // namespace statsd
856} // namespace os
857} // namespace android
858#else
859GTEST_LOG_(INFO) << "This test does nothing.\n";
860#endif