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 
15 #include "src/metrics/EventMetricProducer.h"
16 
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 #include <stdio.h>
20 
21 #include <vector>
22 
23 #include "metrics_test_helper.h"
24 #include "stats_event.h"
25 #include "tests/statsd_test_util.h"
26 
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 
39 namespace {
40 const ConfigKey kConfigKey(0, 12345);
41 const uint64_t protoHash = 0x1234567890;
42 
makeLogEvent(LogEvent * logEvent,int32_t atomId,int64_t timestampNs,string str,vector<uint8_t> * bytesField=nullptr)43 void makeLogEvent(LogEvent* logEvent, int32_t atomId, int64_t timestampNs, string str,
44                   vector<uint8_t>* bytesField = nullptr) {
45     AStatsEvent* statsEvent = AStatsEvent_obtain();
46     AStatsEvent_setAtomId(statsEvent, atomId);
47     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
48     AStatsEvent_writeString(statsEvent, str.c_str());
49     if (bytesField != nullptr) {
50         AStatsEvent_writeByteArray(statsEvent, bytesField->data(), bytesField->size());
51     }
52 
53     parseStatsEventToLogEvent(statsEvent, logEvent);
54 }
55 
onDumpReport(EventMetricProducer & producer,int64_t dumpTimeNs)56 StatsLogReport onDumpReport(EventMetricProducer& producer, int64_t dumpTimeNs) {
57     ProtoOutputStream output;
58     set<int32_t> usedUids;
59     producer.onDumpReport(dumpTimeNs, true /*include current partial bucket*/, true /*erase data*/,
60                           FAST, nullptr, usedUids, &output);
61     return outputStreamToProto(&output);
62 }
63 
64 }  // anonymous namespace
65 
66 class EventMetricProducerTest : public ::testing::Test {
SetUp()67     void SetUp() override {
68         FlagProvider::getInstance().overrideFuncs(&isAtLeastSFuncTrue);
69     }
70 
TearDown()71     void TearDown() override {
72         FlagProvider::getInstance().resetOverrides();
73     }
74 };
75 
TEST_F(EventMetricProducerTest,TestNoCondition)76 TEST_F(EventMetricProducerTest, TestNoCondition) {
77     int64_t bucketStartTimeNs = 10000000000;
78     int64_t eventStartTimeNs = bucketStartTimeNs + 1;
79     int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
80 
81     EventMetric metric;
82     metric.set_id(1);
83 
84     LogEvent event1(/*uid=*/0, /*pid=*/0);
85     CreateNoValuesLogEvent(&event1, 1 /*tagId*/, bucketStartTimeNs + 1);
86 
87     LogEvent event2(/*uid=*/0, /*pid=*/0);
88     CreateNoValuesLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 2);
89 
90     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
91     sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
92 
93     EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
94                                       wizard, protoHash, bucketStartTimeNs, provider);
95 
96     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
97     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
98 
99     // Check dump report content.
100     StatsLogReport report = onDumpReport(eventProducer, bucketStartTimeNs + 20);
101     backfillAggregatedAtoms(&report);
102     EXPECT_TRUE(report.has_event_metrics());
103     ASSERT_EQ(2, report.event_metrics().data_size());
104     EXPECT_EQ(bucketStartTimeNs + 1, report.event_metrics().data(0).elapsed_timestamp_nanos());
105     EXPECT_EQ(bucketStartTimeNs + 2, report.event_metrics().data(1).elapsed_timestamp_nanos());
106 }
107 
TEST_F(EventMetricProducerTest,TestEventsWithNonSlicedCondition)108 TEST_F(EventMetricProducerTest, TestEventsWithNonSlicedCondition) {
109     int64_t bucketStartTimeNs = 10000000000;
110     int64_t eventStartTimeNs = bucketStartTimeNs + 1;
111     int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
112 
113     EventMetric metric;
114     metric.set_id(1);
115     metric.set_condition(StringToId("SCREEN_ON"));
116 
117     LogEvent event1(/*uid=*/0, /*pid=*/0);
118     CreateNoValuesLogEvent(&event1, 1 /*tagId*/, bucketStartTimeNs + 1);
119 
120     LogEvent event2(/*uid=*/0, /*pid=*/0);
121     CreateNoValuesLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 10);
122 
123     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
124     sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
125 
126     EventMetricProducer eventProducer(kConfigKey, metric, 0 /*condition index*/,
127                                       {ConditionState::kUnknown}, wizard, protoHash,
128                                       bucketStartTimeNs, provider);
129 
130     eventProducer.onConditionChanged(true /*condition*/, bucketStartTimeNs);
131     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
132 
133     eventProducer.onConditionChanged(false /*condition*/, bucketStartTimeNs + 2);
134 
135     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
136 
137     // Check dump report content.
138     StatsLogReport report = onDumpReport(eventProducer, bucketStartTimeNs + 20);
139     EXPECT_TRUE(report.has_event_metrics());
140     backfillAggregatedAtoms(&report);
141     ASSERT_EQ(1, report.event_metrics().data_size());
142     EXPECT_EQ(bucketStartTimeNs + 1, report.event_metrics().data(0).elapsed_timestamp_nanos());
143 }
144 
TEST_F(EventMetricProducerTest,TestEventsWithSlicedCondition)145 TEST_F(EventMetricProducerTest, TestEventsWithSlicedCondition) {
146     int64_t bucketStartTimeNs = 10000000000;
147     int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
148 
149     int tagId = 1;
150     int conditionTagId = 2;
151 
152     EventMetric metric;
153     metric.set_id(1);
154     metric.set_condition(StringToId("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON"));
155     MetricConditionLink* link = metric.add_links();
156     link->set_condition(StringToId("APP_IN_BACKGROUND_PER_UID"));
157     buildSimpleAtomFieldMatcher(tagId, 1, link->mutable_fields_in_what());
158     buildSimpleAtomFieldMatcher(conditionTagId, 2, link->mutable_fields_in_condition());
159 
160     LogEvent event1(/*uid=*/0, /*pid=*/0);
161     makeLogEvent(&event1, 1 /*tagId*/, bucketStartTimeNs + 1, "111");
162     ConditionKey key1;
163     key1[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
164             getMockedDimensionKey(conditionTagId, 2, "111")};
165 
166     LogEvent event2(/*uid=*/0, /*pid=*/0);
167     makeLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 10, "222");
168     ConditionKey key2;
169     key2[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
170             getMockedDimensionKey(conditionTagId, 2, "222")};
171 
172     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
173     // Condition is false for first event.
174     EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse));
175     // Condition is true for second event.
176     EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue));
177     sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
178 
179     EventMetricProducer eventProducer(kConfigKey, metric, 0 /*condition index*/,
180                                       {ConditionState::kUnknown}, wizard, protoHash,
181                                       bucketStartTimeNs, provider);
182 
183     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
184     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
185 
186     // Check dump report content.
187     StatsLogReport report = onDumpReport(eventProducer, bucketStartTimeNs + 20);
188     backfillAggregatedAtoms(&report);
189     EXPECT_TRUE(report.has_event_metrics());
190     ASSERT_EQ(1, report.event_metrics().data_size());
191     EXPECT_EQ(bucketStartTimeNs + 10, report.event_metrics().data(0).elapsed_timestamp_nanos());
192 }
193 
TEST_F(EventMetricProducerTest,TestOneAtomTagAggregatedEvents)194 TEST_F(EventMetricProducerTest, TestOneAtomTagAggregatedEvents) {
195     int64_t bucketStartTimeNs = 10000000000;
196     int tagId = 1;
197 
198     EventMetric metric;
199     metric.set_id(1);
200 
201     LogEvent event1(/*uid=*/0, /*pid=*/0);
202     makeLogEvent(&event1, tagId, bucketStartTimeNs + 10, "111");
203     LogEvent event2(/*uid=*/0, /*pid=*/0);
204     makeLogEvent(&event2, tagId, bucketStartTimeNs + 20, "111");
205     LogEvent event3(/*uid=*/0, /*pid=*/0);
206     makeLogEvent(&event3, tagId, bucketStartTimeNs + 30, "111");
207 
208     LogEvent event4(/*uid=*/0, /*pid=*/0);
209     makeLogEvent(&event4, tagId, bucketStartTimeNs + 40, "222");
210 
211     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
212     sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
213     EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
214                                       wizard, protoHash, bucketStartTimeNs, provider);
215 
216     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
217     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
218     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event3);
219     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event4);
220 
221     // Check dump report content.
222     StatsLogReport report = onDumpReport(eventProducer, bucketStartTimeNs + 50);
223     EXPECT_TRUE(report.has_event_metrics());
224     ASSERT_EQ(2, report.event_metrics().data_size());
225 
226     for (EventMetricData metricData : report.event_metrics().data()) {
227         AggregatedAtomInfo atomInfo = metricData.aggregated_atom_info();
228         if (atomInfo.elapsed_timestamp_nanos_size() == 1) {
229             EXPECT_EQ(atomInfo.elapsed_timestamp_nanos(0), bucketStartTimeNs + 40);
230         } else if (atomInfo.elapsed_timestamp_nanos_size() == 3) {
231             EXPECT_EQ(atomInfo.elapsed_timestamp_nanos(0), bucketStartTimeNs + 10);
232             EXPECT_EQ(atomInfo.elapsed_timestamp_nanos(1), bucketStartTimeNs + 20);
233             EXPECT_EQ(atomInfo.elapsed_timestamp_nanos(2), bucketStartTimeNs + 30);
234         } else {
235             FAIL();
236         }
237     }
238 }
239 
TEST_F(EventMetricProducerTest,TestBytesFieldAggregatedEvents)240 TEST_F(EventMetricProducerTest, TestBytesFieldAggregatedEvents) {
241     int64_t bucketStartTimeNs = 10000000000;
242     int tagId = 1;
243 
244     EventMetric metric;
245     metric.set_id(1);
246 
247     vector<uint8_t> bytesField1{10, 20, 30};
248     vector<uint8_t> bytesField2{10, 20, 30, 40};
249     LogEvent event1(/*uid=*/0, /*pid=*/0);
250     makeLogEvent(&event1, tagId, bucketStartTimeNs + 10, "111", &bytesField1);
251     LogEvent event2(/*uid=*/0, /*pid=*/0);
252     makeLogEvent(&event2, tagId, bucketStartTimeNs + 20, "111", &bytesField1);
253     LogEvent event3(/*uid=*/0, /*pid=*/0);
254     makeLogEvent(&event3, tagId, bucketStartTimeNs + 30, "111", &bytesField1);
255 
256     LogEvent event4(/*uid=*/0, /*pid=*/0);
257     makeLogEvent(&event4, tagId, bucketStartTimeNs + 40, "111", &bytesField2);
258 
259     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
260     sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
261     EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
262                                       wizard, protoHash, bucketStartTimeNs, provider);
263 
264     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
265     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
266     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event3);
267     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event4);
268 
269     // Check dump report content.
270     StatsLogReport report = onDumpReport(eventProducer, bucketStartTimeNs + 50);
271     EXPECT_TRUE(report.has_event_metrics());
272     ASSERT_EQ(2, report.event_metrics().data_size());
273 
274     for (EventMetricData metricData : report.event_metrics().data()) {
275         AggregatedAtomInfo atomInfo = metricData.aggregated_atom_info();
276         if (atomInfo.elapsed_timestamp_nanos_size() == 1) {
277             EXPECT_EQ(atomInfo.elapsed_timestamp_nanos(0), bucketStartTimeNs + 40);
278         } else if (atomInfo.elapsed_timestamp_nanos_size() == 3) {
279             EXPECT_EQ(atomInfo.elapsed_timestamp_nanos(0), bucketStartTimeNs + 10);
280             EXPECT_EQ(atomInfo.elapsed_timestamp_nanos(1), bucketStartTimeNs + 20);
281             EXPECT_EQ(atomInfo.elapsed_timestamp_nanos(2), bucketStartTimeNs + 30);
282         } else {
283             FAIL();
284         }
285     }
286 }
287 
TEST_F(EventMetricProducerTest,TestTwoAtomTagAggregatedEvents)288 TEST_F(EventMetricProducerTest, TestTwoAtomTagAggregatedEvents) {
289     int64_t bucketStartTimeNs = 10000000000;
290     int tagId = 1;
291     int tagId2 = 0;
292 
293     EventMetric metric;
294     metric.set_id(1);
295 
296     LogEvent event1(/*uid=*/0, /*pid=*/0);
297     makeLogEvent(&event1, tagId, bucketStartTimeNs + 10, "111");
298     LogEvent event2(/*uid=*/0, /*pid=*/0);
299     makeLogEvent(&event2, tagId, bucketStartTimeNs + 20, "111");
300 
301     LogEvent event3(/*uid=*/0, /*pid=*/0);
302     makeLogEvent(&event3, tagId2, bucketStartTimeNs + 40, "222");
303 
304     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
305     sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
306     EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
307                                       wizard, protoHash, bucketStartTimeNs, provider);
308 
309     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
310     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
311     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event3);
312 
313     // Check dump report content.
314     StatsLogReport report = onDumpReport(eventProducer, bucketStartTimeNs + 50);
315 
316     EXPECT_TRUE(report.has_event_metrics());
317     ASSERT_EQ(2, report.event_metrics().data_size());
318 
319     for (EventMetricData metricData : report.event_metrics().data()) {
320         AggregatedAtomInfo atomInfo = metricData.aggregated_atom_info();
321         if (atomInfo.elapsed_timestamp_nanos_size() == 1) {
322             EXPECT_EQ(atomInfo.elapsed_timestamp_nanos(0), bucketStartTimeNs + 40);
323         } else if (atomInfo.elapsed_timestamp_nanos_size() == 2) {
324             EXPECT_EQ(atomInfo.elapsed_timestamp_nanos(0), bucketStartTimeNs + 10);
325             EXPECT_EQ(atomInfo.elapsed_timestamp_nanos(1), bucketStartTimeNs + 20);
326         } else {
327             FAIL();
328         }
329     }
330 }
331 
TEST_F(EventMetricProducerTest,TestCorruptedDataReason_OnDumpReport)332 TEST_F(EventMetricProducerTest, TestCorruptedDataReason_OnDumpReport) {
333     int64_t bucketStartTimeNs = 10000000000;
334     int tagId = 1;
335 
336     EventMetric metric;
337     metric.set_id(1);
338 
339     LogEvent event1(/*uid=*/0, /*pid=*/0);
340     makeLogEvent(&event1, tagId, bucketStartTimeNs + 10, "111");
341 
342     sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
343     EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
344                                       nullptr, protoHash, bucketStartTimeNs, provider);
345 
346     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
347     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
348               MetricProducer::DataCorruptionSeverity::kNone);
349     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
350               MetricProducer::DataCorruptionSeverity::kNone);
351     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_SOCKET_LOSS,
352                                         MetricProducer::LostAtomType::kWhat);
353     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
354               MetricProducer::DataCorruptionSeverity::kResetOnDump);
355     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
356               MetricProducer::DataCorruptionSeverity::kNone);
357 
358     {
359         // Check dump report content.
360         StatsLogReport report = onDumpReport(eventProducer, bucketStartTimeNs + 50);
361 
362         EXPECT_TRUE(report.has_event_metrics());
363         EXPECT_EQ(1, report.event_metrics().data_size());
364         ASSERT_EQ(1, report.data_corrupted_reason_size());
365         ASSERT_EQ(DATA_CORRUPTED_SOCKET_LOSS, report.data_corrupted_reason()[0]);
366         EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
367                   MetricProducer::DataCorruptionSeverity::kNone);
368         EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
369                   MetricProducer::DataCorruptionSeverity::kNone);
370     }
371 
372     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
373     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
374               MetricProducer::DataCorruptionSeverity::kNone);
375     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
376               MetricProducer::DataCorruptionSeverity::kNone);
377     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_EVENT_QUEUE_OVERFLOW,
378                                         MetricProducer::LostAtomType::kWhat);
379     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
380               MetricProducer::DataCorruptionSeverity::kNone);
381     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
382               MetricProducer::DataCorruptionSeverity::kResetOnDump);
383 
384     {
385         // Check dump report content.
386         StatsLogReport report = onDumpReport(eventProducer, bucketStartTimeNs + 150);
387 
388         EXPECT_TRUE(report.has_event_metrics());
389         EXPECT_EQ(1, report.event_metrics().data_size());
390         ASSERT_EQ(1, report.data_corrupted_reason_size());
391         ASSERT_EQ(DATA_CORRUPTED_EVENT_QUEUE_OVERFLOW, report.data_corrupted_reason()[0]);
392         EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
393                   MetricProducer::DataCorruptionSeverity::kNone);
394         EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
395                   MetricProducer::DataCorruptionSeverity::kNone);
396     }
397 
398     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
399     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
400               MetricProducer::DataCorruptionSeverity::kNone);
401     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
402               MetricProducer::DataCorruptionSeverity::kNone);
403     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_SOCKET_LOSS,
404                                         MetricProducer::LostAtomType::kWhat);
405     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_EVENT_QUEUE_OVERFLOW,
406                                         MetricProducer::LostAtomType::kWhat);
407     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
408               MetricProducer::DataCorruptionSeverity::kResetOnDump);
409     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
410               MetricProducer::DataCorruptionSeverity::kResetOnDump);
411 
412     {
413         // Check dump report content.
414         StatsLogReport report = onDumpReport(eventProducer, bucketStartTimeNs + 250);
415 
416         EXPECT_TRUE(report.has_event_metrics());
417         EXPECT_EQ(1, report.event_metrics().data_size());
418         EXPECT_EQ(2, report.data_corrupted_reason_size());
419         EXPECT_THAT(report.data_corrupted_reason(),
420                     ElementsAre(DATA_CORRUPTED_EVENT_QUEUE_OVERFLOW, DATA_CORRUPTED_SOCKET_LOSS));
421         EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
422                   MetricProducer::DataCorruptionSeverity::kNone);
423         EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
424                   MetricProducer::DataCorruptionSeverity::kNone);
425     }
426 }
427 
TEST_F(EventMetricProducerTest,TestCorruptedDataReason_OnDropData)428 TEST_F(EventMetricProducerTest, TestCorruptedDataReason_OnDropData) {
429     int64_t bucketStartTimeNs = 10000000000;
430     int tagId = 1;
431 
432     EventMetric metric;
433     metric.set_id(1);
434 
435     LogEvent event1(/*uid=*/0, /*pid=*/0);
436     makeLogEvent(&event1, tagId, bucketStartTimeNs + 10, "111");
437 
438     sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
439     EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
440                                       nullptr, protoHash, bucketStartTimeNs, provider);
441     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
442 
443     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
444               MetricProducer::DataCorruptionSeverity::kNone);
445     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
446               MetricProducer::DataCorruptionSeverity::kNone);
447 
448     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_SOCKET_LOSS,
449                                         MetricProducer::LostAtomType::kWhat);
450 
451     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
452               MetricProducer::DataCorruptionSeverity::kResetOnDump);
453     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
454               MetricProducer::DataCorruptionSeverity::kNone);
455 
456     eventProducer.dropData(bucketStartTimeNs + 100);
457 
458     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
459               MetricProducer::DataCorruptionSeverity::kNone);
460     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
461               MetricProducer::DataCorruptionSeverity::kNone);
462 
463     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_EVENT_QUEUE_OVERFLOW,
464                                         MetricProducer::LostAtomType::kWhat);
465 
466     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
467               MetricProducer::DataCorruptionSeverity::kNone);
468     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
469               MetricProducer::DataCorruptionSeverity::kResetOnDump);
470 
471     eventProducer.dropData(bucketStartTimeNs + 200);
472 
473     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
474               MetricProducer::DataCorruptionSeverity::kNone);
475     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
476               MetricProducer::DataCorruptionSeverity::kNone);
477 
478     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_SOCKET_LOSS,
479                                         MetricProducer::LostAtomType::kWhat);
480     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_EVENT_QUEUE_OVERFLOW,
481                                         MetricProducer::LostAtomType::kWhat);
482 
483     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
484               MetricProducer::DataCorruptionSeverity::kResetOnDump);
485     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
486               MetricProducer::DataCorruptionSeverity::kResetOnDump);
487 
488     eventProducer.dropData(bucketStartTimeNs + 300);
489 
490     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
491               MetricProducer::DataCorruptionSeverity::kNone);
492     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
493               MetricProducer::DataCorruptionSeverity::kNone);
494 
495     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_SOCKET_LOSS,
496                                         MetricProducer::LostAtomType::kCondition);
497 
498     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
499               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
500     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
501               MetricProducer::DataCorruptionSeverity::kNone);
502 
503     eventProducer.dropData(bucketStartTimeNs + 400);
504 
505     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
506               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
507     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
508               MetricProducer::DataCorruptionSeverity::kNone);
509 
510     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_EVENT_QUEUE_OVERFLOW,
511                                         MetricProducer::LostAtomType::kCondition);
512 
513     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
514               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
515     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
516               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
517 
518     eventProducer.dropData(bucketStartTimeNs + 500);
519 
520     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
521               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
522     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
523               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
524 }
525 
TEST_F(EventMetricProducerTest,TestCorruptedDataReason_OnClearPastBuckets)526 TEST_F(EventMetricProducerTest, TestCorruptedDataReason_OnClearPastBuckets) {
527     int64_t bucketStartTimeNs = 10000000000;
528     int tagId = 1;
529 
530     EventMetric metric;
531     metric.set_id(1);
532 
533     LogEvent event1(/*uid=*/0, /*pid=*/0);
534     makeLogEvent(&event1, tagId, bucketStartTimeNs + 10, "111");
535 
536     sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
537     EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
538                                       nullptr, protoHash, bucketStartTimeNs, provider);
539     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
540 
541     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
542               MetricProducer::DataCorruptionSeverity::kNone);
543     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
544               MetricProducer::DataCorruptionSeverity::kNone);
545 
546     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_SOCKET_LOSS,
547                                         MetricProducer::LostAtomType::kWhat);
548 
549     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
550               MetricProducer::DataCorruptionSeverity::kResetOnDump);
551     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
552               MetricProducer::DataCorruptionSeverity::kNone);
553 
554     eventProducer.clearPastBuckets(bucketStartTimeNs + 100);
555 
556     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
557               MetricProducer::DataCorruptionSeverity::kNone);
558     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
559               MetricProducer::DataCorruptionSeverity::kNone);
560 
561     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_EVENT_QUEUE_OVERFLOW,
562                                         MetricProducer::LostAtomType::kWhat);
563 
564     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
565               MetricProducer::DataCorruptionSeverity::kNone);
566     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
567               MetricProducer::DataCorruptionSeverity::kResetOnDump);
568 
569     eventProducer.clearPastBuckets(bucketStartTimeNs + 200);
570 
571     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
572               MetricProducer::DataCorruptionSeverity::kNone);
573     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
574               MetricProducer::DataCorruptionSeverity::kNone);
575 
576     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_SOCKET_LOSS,
577                                         MetricProducer::LostAtomType::kWhat);
578     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_EVENT_QUEUE_OVERFLOW,
579                                         MetricProducer::LostAtomType::kWhat);
580 
581     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
582               MetricProducer::DataCorruptionSeverity::kResetOnDump);
583     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
584               MetricProducer::DataCorruptionSeverity::kResetOnDump);
585 
586     eventProducer.clearPastBuckets(bucketStartTimeNs + 300);
587 
588     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
589               MetricProducer::DataCorruptionSeverity::kNone);
590     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
591               MetricProducer::DataCorruptionSeverity::kNone);
592 
593     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_SOCKET_LOSS,
594                                         MetricProducer::LostAtomType::kCondition);
595 
596     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
597               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
598     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
599               MetricProducer::DataCorruptionSeverity::kNone);
600 
601     eventProducer.clearPastBuckets(bucketStartTimeNs + 400);
602 
603     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
604               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
605     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
606               MetricProducer::DataCorruptionSeverity::kNone);
607 
608     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_EVENT_QUEUE_OVERFLOW,
609                                         MetricProducer::LostAtomType::kCondition);
610 
611     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
612               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
613     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
614               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
615 
616     eventProducer.clearPastBuckets(bucketStartTimeNs + 500);
617 
618     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
619               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
620     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
621               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
622 }
623 
TEST_F(EventMetricProducerTest,TestCorruptedDataReason_UnrecoverableLossOfCondition)624 TEST_F(EventMetricProducerTest, TestCorruptedDataReason_UnrecoverableLossOfCondition) {
625     const int64_t bucketStartTimeNs = 10000000000;
626     const int tagId = 1;
627 
628     EventMetric metric;
629     metric.set_id(1);
630 
631     sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
632     EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
633                                       nullptr, protoHash, bucketStartTimeNs, provider);
634 
635     LogEvent event1(/*uid=*/0, /*pid=*/0);
636     makeLogEvent(&event1, tagId, bucketStartTimeNs + 10, "111");
637     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
638     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
639               MetricProducer::DataCorruptionSeverity::kNone);
640     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
641               MetricProducer::DataCorruptionSeverity::kNone);
642 
643     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_SOCKET_LOSS,
644                                         MetricProducer::LostAtomType::kCondition);
645     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
646               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
647     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
648               MetricProducer::DataCorruptionSeverity::kNone);
649 
650     {
651         // Check dump report content.
652         StatsLogReport report = onDumpReport(eventProducer, bucketStartTimeNs + 50);
653 
654         EXPECT_TRUE(report.has_event_metrics());
655         ASSERT_EQ(1, report.event_metrics().data_size());
656         EXPECT_EQ(1, report.data_corrupted_reason_size());
657         EXPECT_THAT(report.data_corrupted_reason(), ElementsAre(DATA_CORRUPTED_SOCKET_LOSS));
658         // confirm that unrecoverable loss status persist after dumpReport
659         EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
660                   MetricProducer::DataCorruptionSeverity::kUnrecoverable);
661         EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
662                   MetricProducer::DataCorruptionSeverity::kNone);
663     }
664 
665     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
666     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
667               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
668     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
669               MetricProducer::DataCorruptionSeverity::kNone);
670     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_EVENT_QUEUE_OVERFLOW,
671                                         MetricProducer::LostAtomType::kWhat);
672     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
673               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
674     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
675               MetricProducer::DataCorruptionSeverity::kResetOnDump);
676 
677     {
678         // Check dump report content.
679         StatsLogReport report = onDumpReport(eventProducer, bucketStartTimeNs + 150);
680         EXPECT_TRUE(report.has_event_metrics());
681         EXPECT_EQ(1, report.event_metrics().data_size());
682         EXPECT_EQ(2, report.data_corrupted_reason_size());
683         EXPECT_THAT(report.data_corrupted_reason(),
684                     ElementsAre(DATA_CORRUPTED_EVENT_QUEUE_OVERFLOW, DATA_CORRUPTED_SOCKET_LOSS));
685         // confirm that unrecoverable loss status persist after dumpReport
686         EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
687                   MetricProducer::DataCorruptionSeverity::kUnrecoverable);
688         // confirm that kResetOnDump loss status is reset after dumpReport
689         EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
690                   MetricProducer::DataCorruptionSeverity::kNone);
691     }
692 
693     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
694     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
695               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
696     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
697               MetricProducer::DataCorruptionSeverity::kNone);
698     eventProducer.onMatchedLogEventLost(tagId, DATA_CORRUPTED_EVENT_QUEUE_OVERFLOW,
699                                         MetricProducer::LostAtomType::kCondition);
700     EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
701               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
702     EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
703               MetricProducer::DataCorruptionSeverity::kUnrecoverable);
704 
705     {
706         // Check dump report content.
707         StatsLogReport report = onDumpReport(eventProducer, bucketStartTimeNs + 150);
708 
709         EXPECT_TRUE(report.has_event_metrics());
710         EXPECT_EQ(1, report.event_metrics().data_size());
711         EXPECT_EQ(2, report.data_corrupted_reason_size());
712         EXPECT_THAT(report.data_corrupted_reason(),
713                     ElementsAre(DATA_CORRUPTED_EVENT_QUEUE_OVERFLOW, DATA_CORRUPTED_SOCKET_LOSS));
714         // confirm that unrecoverable loss status persist after dumpReport
715         EXPECT_EQ(eventProducer.mDataCorruptedDueToSocketLoss,
716                   MetricProducer::DataCorruptionSeverity::kUnrecoverable);
717         EXPECT_EQ(eventProducer.mDataCorruptedDueToQueueOverflow,
718                   MetricProducer::DataCorruptionSeverity::kUnrecoverable);
719     }
720 }
721 
722 }  // namespace statsd
723 }  // namespace os
724 }  // namespace android
725 #else
726 GTEST_LOG_(INFO) << "This test does nothing.\n";
727 #endif
728