Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 1 | // 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 Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 15 | #include "src/metrics/EventMetricProducer.h" |
| 16 | |
| 17 | #include <gmock/gmock.h> |
| 18 | #include <gtest/gtest.h> |
| 19 | #include <stdio.h> |
tsaichristine | d5800b2 | 2020-03-25 10:31:50 -0700 | [diff] [blame] | 20 | |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 21 | #include <vector> |
| 22 | |
tsaichristine | d5800b2 | 2020-03-25 10:31:50 -0700 | [diff] [blame] | 23 | #include "metrics_test_helper.h" |
| 24 | #include "stats_event.h" |
| 25 | #include "tests/statsd_test_util.h" |
| 26 | |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 27 | using namespace testing; |
| 28 | using android::sp; |
| 29 | using std::set; |
| 30 | using std::unordered_map; |
| 31 | using std::vector; |
| 32 | |
| 33 | #ifdef __ANDROID__ |
| 34 | |
| 35 | namespace android { |
| 36 | namespace os { |
| 37 | namespace statsd { |
| 38 | |
Yangster-mac | 94e197c | 2018-01-02 16:03:03 -0800 | [diff] [blame] | 39 | const ConfigKey kConfigKey(0, 12345); |
Yao Chen | b356151 | 2017-11-21 18:07:17 -0800 | [diff] [blame] | 40 | |
tsaichristine | d5800b2 | 2020-03-25 10:31:50 -0700 | [diff] [blame] | 41 | namespace { |
| 42 | void makeLogEvent(LogEvent* logEvent, int32_t atomId, int64_t timestampNs, string str) { |
| 43 | AStatsEvent* statsEvent = AStatsEvent_obtain(); |
| 44 | AStatsEvent_setAtomId(statsEvent, atomId); |
| 45 | AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); |
tsaichristine | d5800b2 | 2020-03-25 10:31:50 -0700 | [diff] [blame] | 46 | AStatsEvent_writeString(statsEvent, str.c_str()); |
tsaichristine | d5800b2 | 2020-03-25 10:31:50 -0700 | [diff] [blame] | 47 | |
tsaichristine | 8dca82e | 2020-04-07 09:40:03 -0700 | [diff] [blame] | 48 | parseStatsEventToLogEvent(statsEvent, logEvent); |
tsaichristine | d5800b2 | 2020-03-25 10:31:50 -0700 | [diff] [blame] | 49 | } |
| 50 | } // anonymous namespace |
| 51 | |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 52 | TEST(EventMetricProducerTest, TestNoCondition) { |
Yangster-mac | b142cc8 | 2018-03-30 15:22:08 -0700 | [diff] [blame] | 53 | int64_t bucketStartTimeNs = 10000000000; |
| 54 | int64_t eventStartTimeNs = bucketStartTimeNs + 1; |
| 55 | int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL; |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 56 | |
| 57 | EventMetric metric; |
Yangster-mac | 94e197c | 2018-01-02 16:03:03 -0800 | [diff] [blame] | 58 | metric.set_id(1); |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 59 | |
tsaichristine | d5800b2 | 2020-03-25 10:31:50 -0700 | [diff] [blame] | 60 | LogEvent event1(/*uid=*/0, /*pid=*/0); |
| 61 | CreateNoValuesLogEvent(&event1, 1 /*tagId*/, bucketStartTimeNs + 1); |
| 62 | |
| 63 | LogEvent event2(/*uid=*/0, /*pid=*/0); |
| 64 | CreateNoValuesLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 2); |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 65 | |
| 66 | sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); |
| 67 | |
Yao Chen | b356151 | 2017-11-21 18:07:17 -0800 | [diff] [blame] | 68 | EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 69 | bucketStartTimeNs); |
| 70 | |
Chenjie Yu | a7259ab | 2017-12-10 08:31:05 -0800 | [diff] [blame] | 71 | eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1); |
| 72 | eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2); |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 73 | |
tsaichristine | d5800b2 | 2020-03-25 10:31:50 -0700 | [diff] [blame] | 74 | // Check dump report content. |
| 75 | ProtoOutputStream output; |
| 76 | std::set<string> strSet; |
| 77 | eventProducer.onDumpReport(bucketStartTimeNs + 20, true /*include current partial bucket*/, |
| 78 | true /*erase data*/, FAST, &strSet, &output); |
| 79 | |
| 80 | StatsLogReport report = outputStreamToProto(&output); |
| 81 | EXPECT_TRUE(report.has_event_metrics()); |
Muhammad Qureshi | dff78d6 | 2020-05-11 13:37:43 -0700 | [diff] [blame] | 82 | ASSERT_EQ(2, report.event_metrics().data_size()); |
tsaichristine | d5800b2 | 2020-03-25 10:31:50 -0700 | [diff] [blame] | 83 | EXPECT_EQ(bucketStartTimeNs + 1, report.event_metrics().data(0).elapsed_timestamp_nanos()); |
| 84 | EXPECT_EQ(bucketStartTimeNs + 2, report.event_metrics().data(1).elapsed_timestamp_nanos()); |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 85 | } |
| 86 | |
| 87 | TEST(EventMetricProducerTest, TestEventsWithNonSlicedCondition) { |
Yangster-mac | b142cc8 | 2018-03-30 15:22:08 -0700 | [diff] [blame] | 88 | int64_t bucketStartTimeNs = 10000000000; |
| 89 | int64_t eventStartTimeNs = bucketStartTimeNs + 1; |
| 90 | int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL; |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 91 | |
| 92 | EventMetric metric; |
Yangster-mac | 94e197c | 2018-01-02 16:03:03 -0800 | [diff] [blame] | 93 | metric.set_id(1); |
| 94 | metric.set_condition(StringToId("SCREEN_ON")); |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 95 | |
tsaichristine | d5800b2 | 2020-03-25 10:31:50 -0700 | [diff] [blame] | 96 | LogEvent event1(/*uid=*/0, /*pid=*/0); |
| 97 | CreateNoValuesLogEvent(&event1, 1 /*tagId*/, bucketStartTimeNs + 1); |
| 98 | |
| 99 | LogEvent event2(/*uid=*/0, /*pid=*/0); |
| 100 | CreateNoValuesLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 10); |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 101 | |
| 102 | sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); |
| 103 | |
Yao Chen | b356151 | 2017-11-21 18:07:17 -0800 | [diff] [blame] | 104 | EventMetricProducer eventProducer(kConfigKey, metric, 1, wizard, bucketStartTimeNs); |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 105 | |
| 106 | eventProducer.onConditionChanged(true /*condition*/, bucketStartTimeNs); |
Chenjie Yu | a7259ab | 2017-12-10 08:31:05 -0800 | [diff] [blame] | 107 | eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1); |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 108 | |
| 109 | eventProducer.onConditionChanged(false /*condition*/, bucketStartTimeNs + 2); |
| 110 | |
Chenjie Yu | a7259ab | 2017-12-10 08:31:05 -0800 | [diff] [blame] | 111 | eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2); |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 112 | |
tsaichristine | d5800b2 | 2020-03-25 10:31:50 -0700 | [diff] [blame] | 113 | // Check dump report content. |
| 114 | ProtoOutputStream output; |
| 115 | std::set<string> strSet; |
| 116 | eventProducer.onDumpReport(bucketStartTimeNs + 20, true /*include current partial bucket*/, |
| 117 | true /*erase data*/, FAST, &strSet, &output); |
| 118 | |
| 119 | StatsLogReport report = outputStreamToProto(&output); |
| 120 | EXPECT_TRUE(report.has_event_metrics()); |
Muhammad Qureshi | dff78d6 | 2020-05-11 13:37:43 -0700 | [diff] [blame] | 121 | ASSERT_EQ(1, report.event_metrics().data_size()); |
tsaichristine | d5800b2 | 2020-03-25 10:31:50 -0700 | [diff] [blame] | 122 | EXPECT_EQ(bucketStartTimeNs + 1, report.event_metrics().data(0).elapsed_timestamp_nanos()); |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 123 | } |
| 124 | |
tsaichristine | d5800b2 | 2020-03-25 10:31:50 -0700 | [diff] [blame] | 125 | TEST(EventMetricProducerTest, TestEventsWithSlicedCondition) { |
| 126 | int64_t bucketStartTimeNs = 10000000000; |
| 127 | int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL; |
| 128 | |
| 129 | int tagId = 1; |
| 130 | int conditionTagId = 2; |
| 131 | |
| 132 | EventMetric metric; |
| 133 | metric.set_id(1); |
| 134 | metric.set_condition(StringToId("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON")); |
| 135 | MetricConditionLink* link = metric.add_links(); |
| 136 | link->set_condition(StringToId("APP_IN_BACKGROUND_PER_UID")); |
| 137 | buildSimpleAtomFieldMatcher(tagId, 1, link->mutable_fields_in_what()); |
| 138 | buildSimpleAtomFieldMatcher(conditionTagId, 2, link->mutable_fields_in_condition()); |
| 139 | |
| 140 | LogEvent event1(/*uid=*/0, /*pid=*/0); |
| 141 | makeLogEvent(&event1, 1 /*tagId*/, bucketStartTimeNs + 1, "111"); |
| 142 | ConditionKey key1; |
| 143 | key1[StringToId("APP_IN_BACKGROUND_PER_UID")] = { |
| 144 | getMockedDimensionKey(conditionTagId, 2, "111")}; |
| 145 | |
| 146 | LogEvent event2(/*uid=*/0, /*pid=*/0); |
| 147 | makeLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 10, "222"); |
| 148 | ConditionKey key2; |
| 149 | key2[StringToId("APP_IN_BACKGROUND_PER_UID")] = { |
| 150 | getMockedDimensionKey(conditionTagId, 2, "222")}; |
| 151 | |
| 152 | sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); |
| 153 | // Condition is false for first event. |
| 154 | EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse)); |
| 155 | // Condition is true for second event. |
| 156 | EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue)); |
| 157 | |
| 158 | EventMetricProducer eventProducer(kConfigKey, metric, 1, wizard, bucketStartTimeNs); |
| 159 | |
| 160 | eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1); |
| 161 | eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2); |
| 162 | |
| 163 | // Check dump report content. |
| 164 | ProtoOutputStream output; |
| 165 | std::set<string> strSet; |
| 166 | eventProducer.onDumpReport(bucketStartTimeNs + 20, true /*include current partial bucket*/, |
| 167 | true /*erase data*/, FAST, &strSet, &output); |
| 168 | |
| 169 | StatsLogReport report = outputStreamToProto(&output); |
| 170 | EXPECT_TRUE(report.has_event_metrics()); |
Muhammad Qureshi | dff78d6 | 2020-05-11 13:37:43 -0700 | [diff] [blame] | 171 | ASSERT_EQ(1, report.event_metrics().data_size()); |
tsaichristine | d5800b2 | 2020-03-25 10:31:50 -0700 | [diff] [blame] | 172 | EXPECT_EQ(bucketStartTimeNs + 10, report.event_metrics().data(0).elapsed_timestamp_nanos()); |
| 173 | } |
Yao Chen | 93fe3a3 | 2017-11-02 13:52:59 -0700 | [diff] [blame] | 174 | |
| 175 | } // namespace statsd |
| 176 | } // namespace os |
| 177 | } // namespace android |
| 178 | #else |
| 179 | GTEST_LOG_(INFO) << "This test does nothing.\n"; |
| 180 | #endif |